__init__.py
520 lines
| 18.7 KiB
| text/x-python
|
PythonLexer
r1555 | # -*- coding: utf-8 -*- | |||
r4306 | # Copyright (C) 2016-2020 RhodeCode GmbH | |||
r1555 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
r1785 | from rhodecode.apps._base import add_route_with_slash | |||
r1555 | ||||
def includeme(config): | ||||
r1985 | # repo creating checks, special cases that aren't repo routes | |||
config.add_route( | ||||
name='repo_creating', | ||||
pattern='/{repo_name:.*?[^/]}/repo_creating') | ||||
config.add_route( | ||||
name='repo_creating_check', | ||||
pattern='/{repo_name:.*?[^/]}/repo_creating_check') | ||||
r1751 | # Summary | |||
r1785 | # NOTE(marcink): one additional route is defined in very bottom, catch | |||
# all pattern | ||||
r1774 | config.add_route( | |||
r1751 | name='repo_summary_explicit', | |||
pattern='/{repo_name:.*?[^/]}/summary', repo_route=True) | ||||
r1785 | config.add_route( | |||
name='repo_summary_commits', | ||||
pattern='/{repo_name:.*?[^/]}/summary-commits', repo_route=True) | ||||
r1957 | # Commits | |||
r1788 | config.add_route( | |||
name='repo_commit', | ||||
pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}', repo_route=True) | ||||
r1951 | config.add_route( | |||
name='repo_commit_children', | ||||
pattern='/{repo_name:.*?[^/]}/changeset_children/{commit_id}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commit_parents', | ||||
pattern='/{repo_name:.*?[^/]}/changeset_parents/{commit_id}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commit_raw', | ||||
pattern='/{repo_name:.*?[^/]}/changeset-diff/{commit_id}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commit_patch', | ||||
pattern='/{repo_name:.*?[^/]}/changeset-patch/{commit_id}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commit_download', | ||||
pattern='/{repo_name:.*?[^/]}/changeset-download/{commit_id}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commit_data', | ||||
pattern='/{repo_name:.*?[^/]}/changeset-data/{commit_id}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commit_comment_create', | ||||
pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/create', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commit_comment_preview', | ||||
pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/preview', repo_route=True) | ||||
config.add_route( | ||||
r3973 | name='repo_commit_comment_attachment_upload', | |||
pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/attachment_upload', repo_route=True) | ||||
config.add_route( | ||||
r1951 | name='repo_commit_comment_delete', | |||
pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/{comment_id}/delete', repo_route=True) | ||||
r1957 | # still working url for backward compat. | |||
config.add_route( | ||||
name='repo_commit_raw_deprecated', | ||||
pattern='/{repo_name:.*?[^/]}/raw-changeset/{commit_id}', repo_route=True) | ||||
# Files | ||||
r1927 | config.add_route( | |||
name='repo_archivefile', | ||||
r3698 | pattern='/{repo_name:.*?[^/]}/archive/{fname:.*}', repo_route=True) | |||
r1927 | ||||
config.add_route( | ||||
name='repo_files_diff', | ||||
pattern='/{repo_name:.*?[^/]}/diff/{f_path:.*}', repo_route=True) | ||||
config.add_route( # legacy route to make old links work | ||||
name='repo_files_diff_2way_redirect', | ||||
pattern='/{repo_name:.*?[^/]}/diff-2way/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_files', | ||||
pattern='/{repo_name:.*?[^/]}/files/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_files:default_path', | ||||
pattern='/{repo_name:.*?[^/]}/files/{commit_id}/', repo_route=True) | ||||
config.add_route( | ||||
name='repo_files:default_commit', | ||||
pattern='/{repo_name:.*?[^/]}/files', repo_route=True) | ||||
config.add_route( | ||||
name='repo_files:rendered', | ||||
pattern='/{repo_name:.*?[^/]}/render/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_files:annotated', | ||||
pattern='/{repo_name:.*?[^/]}/annotate/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_files:annotated_previous', | ||||
pattern='/{repo_name:.*?[^/]}/annotate-previous/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_nodetree_full', | ||||
pattern='/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_nodetree_full:default_path', | ||||
pattern='/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/', repo_route=True) | ||||
config.add_route( | ||||
name='repo_files_nodelist', | ||||
pattern='/{repo_name:.*?[^/]}/nodelist/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_file_raw', | ||||
pattern='/{repo_name:.*?[^/]}/raw/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_file_download', | ||||
pattern='/{repo_name:.*?[^/]}/download/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( # backward compat to keep old links working | ||||
name='repo_file_download:legacy', | ||||
pattern='/{repo_name:.*?[^/]}/rawfile/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
name='repo_file_history', | ||||
pattern='/{repo_name:.*?[^/]}/history/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_file_authors', | ||||
pattern='/{repo_name:.*?[^/]}/authors/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
r4302 | name='repo_files_check_head', | |||
pattern='/{repo_name:.*?[^/]}/check_head/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
r1927 | name='repo_files_remove_file', | |||
pattern='/{repo_name:.*?[^/]}/remove_file/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
name='repo_files_delete_file', | ||||
pattern='/{repo_name:.*?[^/]}/delete_file/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
name='repo_files_edit_file', | ||||
pattern='/{repo_name:.*?[^/]}/edit_file/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
name='repo_files_update_file', | ||||
pattern='/{repo_name:.*?[^/]}/update_file/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
name='repo_files_add_file', | ||||
pattern='/{repo_name:.*?[^/]}/add_file/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
r3710 | name='repo_files_upload_file', | |||
pattern='/{repo_name:.*?[^/]}/upload_file/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
r1927 | name='repo_files_create_file', | |||
pattern='/{repo_name:.*?[^/]}/create_file/{commit_id}/{f_path:.*}', | ||||
repo_route=True) | ||||
r1957 | # Refs data | |||
r1785 | config.add_route( | |||
name='repo_refs_data', | ||||
pattern='/{repo_name:.*?[^/]}/refs-data', repo_route=True) | ||||
config.add_route( | ||||
name='repo_refs_changelog_data', | ||||
pattern='/{repo_name:.*?[^/]}/refs-data-changelog', repo_route=True) | ||||
config.add_route( | ||||
name='repo_stats', | ||||
pattern='/{repo_name:.*?[^/]}/repo_stats/{commit_id}', repo_route=True) | ||||
r1751 | ||||
r3742 | # Commits | |||
config.add_route( | ||||
name='repo_commits', | ||||
pattern='/{repo_name:.*?[^/]}/commits', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commits_file', | ||||
pattern='/{repo_name:.*?[^/]}/commits/{commit_id}/{f_path:.*}', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commits_elements', | ||||
pattern='/{repo_name:.*?[^/]}/commits_elements', repo_route=True) | ||||
config.add_route( | ||||
name='repo_commits_elements_file', | ||||
pattern='/{repo_name:.*?[^/]}/commits_elements/{commit_id}/{f_path:.*}', repo_route=True) | ||||
# Changelog (old deprecated name for commits page) | ||||
r1931 | config.add_route( | |||
name='repo_changelog', | ||||
pattern='/{repo_name:.*?[^/]}/changelog', repo_route=True) | ||||
config.add_route( | ||||
name='repo_changelog_file', | ||||
pattern='/{repo_name:.*?[^/]}/changelog/{commit_id}/{f_path:.*}', repo_route=True) | ||||
r1957 | # Compare | |||
config.add_route( | ||||
name='repo_compare_select', | ||||
pattern='/{repo_name:.*?[^/]}/compare', repo_route=True) | ||||
config.add_route( | ||||
name='repo_compare', | ||||
pattern='/{repo_name:.*?[^/]}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}', repo_route=True) | ||||
r1746 | # Tags | |||
config.add_route( | ||||
name='tags_home', | ||||
pattern='/{repo_name:.*?[^/]}/tags', repo_route=True) | ||||
# Branches | ||||
config.add_route( | ||||
name='branches_home', | ||||
pattern='/{repo_name:.*?[^/]}/branches', repo_route=True) | ||||
r1988 | # Bookmarks | |||
r1746 | config.add_route( | |||
name='bookmarks_home', | ||||
pattern='/{repo_name:.*?[^/]}/bookmarks', repo_route=True) | ||||
r1988 | # Forks | |||
config.add_route( | ||||
name='repo_fork_new', | ||||
pattern='/{repo_name:.*?[^/]}/fork', repo_route=True, | ||||
r3090 | repo_forbid_when_archived=True, | |||
r1988 | repo_accepted_types=['hg', 'git']) | |||
config.add_route( | ||||
name='repo_fork_create', | ||||
pattern='/{repo_name:.*?[^/]}/fork/create', repo_route=True, | ||||
r3090 | repo_forbid_when_archived=True, | |||
r1988 | repo_accepted_types=['hg', 'git']) | |||
config.add_route( | ||||
name='repo_forks_show_all', | ||||
pattern='/{repo_name:.*?[^/]}/forks', repo_route=True, | ||||
repo_accepted_types=['hg', 'git']) | ||||
config.add_route( | ||||
name='repo_forks_data', | ||||
pattern='/{repo_name:.*?[^/]}/forks/data', repo_route=True, | ||||
repo_accepted_types=['hg', 'git']) | ||||
r1758 | # Pull Requests | |||
config.add_route( | ||||
name='pullrequest_show', | ||||
r1974 | pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}', | |||
r1758 | repo_route=True) | |||
r1766 | config.add_route( | |||
name='pullrequest_show_all', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request', | ||||
repo_route=True, repo_accepted_types=['hg', 'git']) | ||||
config.add_route( | ||||
name='pullrequest_show_all_data', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request-data', | ||||
repo_route=True, repo_accepted_types=['hg', 'git']) | ||||
r1974 | config.add_route( | |||
name='pullrequest_repo_refs', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/refs/{target_repo_name:.*?[^/]}', | ||||
repo_route=True) | ||||
config.add_route( | ||||
r3330 | name='pullrequest_repo_targets', | |||
pattern='/{repo_name:.*?[^/]}/pull-request/repo-targets', | ||||
r1974 | repo_route=True) | |||
config.add_route( | ||||
name='pullrequest_new', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/new', | ||||
r3090 | repo_route=True, repo_accepted_types=['hg', 'git'], | |||
repo_forbid_when_archived=True) | ||||
r1974 | ||||
config.add_route( | ||||
name='pullrequest_create', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/create', | ||||
r3090 | repo_route=True, repo_accepted_types=['hg', 'git'], | |||
repo_forbid_when_archived=True) | ||||
r1974 | ||||
config.add_route( | ||||
name='pullrequest_update', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/update', | ||||
r3090 | repo_route=True, repo_forbid_when_archived=True) | |||
r1974 | ||||
config.add_route( | ||||
name='pullrequest_merge', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/merge', | ||||
r3090 | repo_route=True, repo_forbid_when_archived=True) | |||
r1974 | ||||
config.add_route( | ||||
name='pullrequest_delete', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/delete', | ||||
r3090 | repo_route=True, repo_forbid_when_archived=True) | |||
r1974 | ||||
config.add_route( | ||||
name='pullrequest_comment_create', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment', | ||||
repo_route=True) | ||||
config.add_route( | ||||
name='pullrequest_comment_delete', | ||||
pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/delete', | ||||
repo_route=True, repo_accepted_types=['hg', 'git']) | ||||
r3671 | # Artifacts, (EE feature) | |||
config.add_route( | ||||
name='repo_artifacts_list', | ||||
pattern='/{repo_name:.*?[^/]}/artifacts', repo_route=True) | ||||
r1716 | # Settings | |||
config.add_route( | ||||
name='edit_repo', | ||||
pattern='/{repo_name:.*?[^/]}/settings', repo_route=True) | ||||
r2175 | # update is POST on edit_repo | |||
r1716 | ||||
r1751 | # Settings advanced | |||
config.add_route( | ||||
name='edit_repo_advanced', | ||||
pattern='/{repo_name:.*?[^/]}/settings/advanced', repo_route=True) | ||||
config.add_route( | ||||
r3090 | name='edit_repo_advanced_archive', | |||
pattern='/{repo_name:.*?[^/]}/settings/advanced/archive', repo_route=True) | ||||
config.add_route( | ||||
r1751 | name='edit_repo_advanced_delete', | |||
pattern='/{repo_name:.*?[^/]}/settings/advanced/delete', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_advanced_locking', | ||||
pattern='/{repo_name:.*?[^/]}/settings/advanced/locking', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_advanced_journal', | ||||
pattern='/{repo_name:.*?[^/]}/settings/advanced/journal', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_advanced_fork', | ||||
pattern='/{repo_name:.*?[^/]}/settings/advanced/fork', repo_route=True) | ||||
r2678 | config.add_route( | |||
name='edit_repo_advanced_hooks', | ||||
pattern='/{repo_name:.*?[^/]}/settings/advanced/hooks', repo_route=True) | ||||
r1722 | # Caches | |||
config.add_route( | ||||
name='edit_repo_caches', | ||||
pattern='/{repo_name:.*?[^/]}/settings/caches', repo_route=True) | ||||
r1734 | # Permissions | |||
config.add_route( | ||||
name='edit_repo_perms', | ||||
pattern='/{repo_name:.*?[^/]}/settings/permissions', repo_route=True) | ||||
r3809 | config.add_route( | |||
name='edit_repo_perms_set_private', | ||||
pattern='/{repo_name:.*?[^/]}/settings/permissions/set_private', repo_route=True) | ||||
r2975 | # Permissions Branch (EE feature) | |||
config.add_route( | ||||
name='edit_repo_perms_branch', | ||||
pattern='/{repo_name:.*?[^/]}/settings/branch_permissions', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_perms_branch_delete', | ||||
pattern='/{repo_name:.*?[^/]}/settings/branch_permissions/{rule_id}/delete', | ||||
repo_route=True) | ||||
r2014 | # Maintenance | |||
config.add_route( | ||||
name='edit_repo_maintenance', | ||||
pattern='/{repo_name:.*?[^/]}/settings/maintenance', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_maintenance_execute', | ||||
pattern='/{repo_name:.*?[^/]}/settings/maintenance/execute', repo_route=True) | ||||
# Fields | ||||
config.add_route( | ||||
name='edit_repo_fields', | ||||
pattern='/{repo_name:.*?[^/]}/settings/fields', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_fields_create', | ||||
pattern='/{repo_name:.*?[^/]}/settings/fields/create', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_fields_delete', | ||||
pattern='/{repo_name:.*?[^/]}/settings/fields/{field_id}/delete', repo_route=True) | ||||
# Locking | ||||
config.add_route( | ||||
name='repo_edit_toggle_locking', | ||||
pattern='/{repo_name:.*?[^/]}/settings/toggle_locking', repo_route=True) | ||||
# Remote | ||||
config.add_route( | ||||
name='edit_repo_remote', | ||||
pattern='/{repo_name:.*?[^/]}/settings/remote', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_remote_pull', | ||||
pattern='/{repo_name:.*?[^/]}/settings/remote/pull', repo_route=True) | ||||
r2562 | config.add_route( | |||
name='edit_repo_remote_push', | ||||
pattern='/{repo_name:.*?[^/]}/settings/remote/push', repo_route=True) | ||||
r2014 | ||||
# Statistics | ||||
config.add_route( | ||||
name='edit_repo_statistics', | ||||
pattern='/{repo_name:.*?[^/]}/settings/statistics', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_statistics_reset', | ||||
pattern='/{repo_name:.*?[^/]}/settings/statistics/update', repo_route=True) | ||||
# Issue trackers | ||||
config.add_route( | ||||
name='edit_repo_issuetracker', | ||||
pattern='/{repo_name:.*?[^/]}/settings/issue_trackers', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_issuetracker_test', | ||||
pattern='/{repo_name:.*?[^/]}/settings/issue_trackers/test', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_issuetracker_delete', | ||||
pattern='/{repo_name:.*?[^/]}/settings/issue_trackers/delete', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_issuetracker_update', | ||||
pattern='/{repo_name:.*?[^/]}/settings/issue_trackers/update', repo_route=True) | ||||
# VCS Settings | ||||
config.add_route( | ||||
name='edit_repo_vcs', | ||||
pattern='/{repo_name:.*?[^/]}/settings/vcs', repo_route=True) | ||||
config.add_route( | ||||
name='edit_repo_vcs_update', | ||||
pattern='/{repo_name:.*?[^/]}/settings/vcs/update', repo_route=True) | ||||
# svn pattern | ||||
config.add_route( | ||||
name='edit_repo_vcs_svn_pattern_delete', | ||||
pattern='/{repo_name:.*?[^/]}/settings/vcs/svn_pattern/delete', repo_route=True) | ||||
# Repo Review Rules (EE feature) | ||||
r1725 | config.add_route( | |||
name='repo_reviewers', | ||||
pattern='/{repo_name:.*?[^/]}/settings/review/rules', repo_route=True) | ||||
r1767 | config.add_route( | |||
name='repo_default_reviewers_data', | ||||
pattern='/{repo_name:.*?[^/]}/settings/review/default-reviewers', repo_route=True) | ||||
r2565 | # Repo Automation (EE feature) | |||
config.add_route( | ||||
name='repo_automation', | ||||
pattern='/{repo_name:.*?[^/]}/settings/automation', repo_route=True) | ||||
Bartłomiej Wołyńczyk
|
r1587 | # Strip | ||
config.add_route( | ||||
r2014 | name='edit_repo_strip', | |||
r1745 | pattern='/{repo_name:.*?[^/]}/settings/strip', repo_route=True) | |||
Bartłomiej Wołyńczyk
|
r1587 | |||
config.add_route( | ||||
name='strip_check', | ||||
r1745 | pattern='/{repo_name:.*?[^/]}/settings/strip_check', repo_route=True) | |||
Bartłomiej Wołyńczyk
|
r1587 | |||
config.add_route( | ||||
name='strip_execute', | ||||
r1745 | pattern='/{repo_name:.*?[^/]}/settings/strip_execute', repo_route=True) | |||
r1751 | ||||
r2156 | # Audit logs | |||
config.add_route( | ||||
name='edit_repo_audit_logs', | ||||
pattern='/{repo_name:.*?[^/]}/settings/audit_logs', repo_route=True) | ||||
r3810 | # ATOM/RSS Feed, shouldn't contain slashes for outlook compatibility | |||
r1899 | config.add_route( | |||
name='rss_feed_home', | ||||
r3810 | pattern='/{repo_name:.*?[^/]}/feed-rss', repo_route=True) | |||
config.add_route( | ||||
name='atom_feed_home', | ||||
pattern='/{repo_name:.*?[^/]}/feed-atom', repo_route=True) | ||||
config.add_route( | ||||
name='rss_feed_home_old', | ||||
r1899 | pattern='/{repo_name:.*?[^/]}/feed/rss', repo_route=True) | |||
config.add_route( | ||||
r3810 | name='atom_feed_home_old', | |||
r1899 | pattern='/{repo_name:.*?[^/]}/feed/atom', repo_route=True) | |||
r1751 | # NOTE(marcink): needs to be at the end for catch-all | |||
r1785 | add_route_with_slash( | |||
config, | ||||
name='repo_summary', | ||||
pattern='/{repo_name:.*?[^/]}', repo_route=True) | ||||
r1751 | ||||
r1555 | # Scan module for configuration decorators. | |||
r1991 | config.scan('.views', ignore='.tests') | |||