From 4f5c8572e988e8c0c6871fb59ccfbfd39b9c2a06 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 16 Jun 2020 18:09:01 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../javascripts/issue_show/components/app.vue | 67 ++++- .../javascripts/issue_show/constants.js | 17 ++ .../components/charts/stacked_column.vue | 33 ++- .../components/charts/time_series.vue | 24 +- .../javascripts/monitoring/constants.js | 13 + app/assets/stylesheets/pages/issues.scss | 66 +++++ app/controllers/jwks_controller.rb | 26 -- app/helpers/issuables_helper.rb | 1 + .../application_setting_implementation.rb | 17 +- .../blob_viewer/metrics_dashboard_yml.rb | 6 +- app/models/ci/build.rb | 19 +- .../merge_request_noteable_entity.rb | 2 + app/views/groups/sidebar/_packages.html.haml | 6 +- ...-chart-legend-format-to-tabular-format.yml | 5 + .../214607-ci-jwt-signing-key-jwks.yml | 5 - ...16880-frontend-add-sticky-issue-titles.yml | 5 + .../jc-pick-weighted-repository.yml | 5 + .../rp-use-gitlab-yaml-loader-blob-viewer.yml | 5 + config/initializers/01_secret_token.rb | 3 +- config/locales/doorkeeper.en.yml | 2 + config/routes.rb | 5 +- ...05093113_add_ip_address_to_audit_events.rb | 9 + db/structure.sql | 4 +- .../index.md | 2 +- doc/ci/pipelines/job_artifacts.md | 11 + doc/development/telemetry/usage_ping.md | 2 + doc/integration/elasticsearch.md | 8 +- .../packages/composer_repository/index.md | 6 + doc/user/packages/container_registry/index.md | 2 +- .../prometheus_monitoring_dashboard_v12_8.png | Bin 29683 -> 0 bytes .../prometheus_monitoring_dashboard_v13_1.png | Bin 0 -> 40765 bytes doc/user/project/integrations/prometheus.md | 9 +- .../merge_requests/merge_request_approvals.md | 5 + doc/user/project/protected_branches.md | 2 +- doc/user/project/protected_tags.md | 6 +- .../reducing_the_repo_size_using_git.md | 262 +++++++++--------- doc/user/project/requirements/index.md | 58 ++++ lib/gitlab/ci/build/step.rb | 13 + lib/gitlab/ci/config/entry/job.rb | 2 +- lib/gitlab/ci/features.rb | 4 + lib/gitlab/ci/jwt.rb | 2 +- lib/gitlab/ci/status/core.rb | 2 +- lib/gitlab/ci/yaml_processor.rb | 2 +- locale/gitlab.pot | 60 ++++ spec/controllers/jwks_controller_spec.rb | 31 --- spec/factories/ci/builds.rb | 15 + spec/features/admin/admin_runners_spec.rb | 2 +- .../admin_sees_project_statistics_spec.rb | 2 +- .../admin_sees_projects_statistics_spec.rb | 2 +- .../admin/admin_serverless_domains_spec.rb | 2 +- spec/features/admin/admin_settings_spec.rb | 2 +- spec/features/admin/admin_system_info_spec.rb | 2 +- .../admin_users_impersonation_tokens_spec.rb | 2 +- spec/features/admin/admin_users_spec.rb | 2 +- .../admin_uses_repository_checks_spec.rb | 2 +- .../admin/clusters/applications_spec.rb | 2 +- spec/features/admin/clusters/eks_spec.rb | 2 +- spec/features/admin/dashboard_spec.rb | 2 +- .../admin_activates_prometheus_spec.rb | 2 +- spec/features/atom/dashboard_issues_spec.rb | 2 +- spec/features/atom/dashboard_spec.rb | 2 +- spec/features/atom/issues_spec.rb | 2 +- spec/features/atom/users_spec.rb | 2 +- spec/features/boards/add_issues_modal_spec.rb | 2 +- spec/features/boards/boards_spec.rb | 2 +- spec/features/boards/focus_mode_spec.rb | 2 +- spec/features/boards/issue_ordering_spec.rb | 2 +- .../features/boards/keyboard_shortcut_spec.rb | 2 +- spec/features/boards/modal_filter_spec.rb | 2 +- spec/features/boards/multi_select_spec.rb | 2 +- spec/features/boards/multiple_boards_spec.rb | 2 +- spec/features/boards/new_issue_spec.rb | 2 +- .../reload_boards_on_browser_back_spec.rb | 2 +- spec/features/boards/sidebar_spec.rb | 2 +- .../features/boards/sub_group_project_spec.rb | 2 +- spec/features/broadcast_messages_spec.rb | 2 +- spec/features/calendar_spec.rb | 2 +- .../clusters/cluster_detail_page_spec.rb | 2 +- ...installing_applications_shared_examples.rb | 4 +- .../commits/user_uses_quick_actions_spec.rb | 2 +- .../commits/user_view_commits_spec.rb | 2 +- spec/features/commits_spec.rb | 2 +- spec/features/contextual_sidebar_spec.rb | 2 +- spec/features/cycle_analytics_spec.rb | 2 +- spec/features/dashboard/activity_spec.rb | 2 +- .../dashboard/datetime_on_tooltips_spec.rb | 2 +- ...ith_external_authorization_service_spec.rb | 2 +- spec/features/dashboard/groups_list_spec.rb | 2 +- .../dashboard/instance_statistics_spec.rb | 2 +- .../dashboard/issuables_counter_spec.rb | 2 +- spec/features/dashboard/issues_filter_spec.rb | 2 +- spec/features/dashboard/label_filter_spec.rb | 2 +- .../features/dashboard/merge_requests_spec.rb | 2 +- spec/features/dashboard/milestones_spec.rb | 2 +- .../project_member_activity_index_spec.rb | 2 +- spec/features/dashboard/projects_spec.rb | 2 +- spec/features/dashboard/root_explore_spec.rb | 2 +- spec/features/dashboard/shortcuts_spec.rb | 2 +- spec/features/dashboard/snippets_spec.rb | 2 +- .../dashboard/todos/target_state_spec.rb | 2 +- .../dashboard/todos/todos_filtering_spec.rb | 2 +- .../dashboard/todos/todos_sorting_spec.rb | 2 +- spec/features/dashboard/todos/todos_spec.rb | 2 +- .../dashboard/user_filters_projects_spec.rb | 2 +- .../discussion_comments/commit_spec.rb | 2 +- .../discussion_comments/issue_spec.rb | 2 +- .../discussion_comments/merge_request_spec.rb | 2 +- .../discussion_comments/snippets_spec.rb | 2 +- ...splay_system_header_and_footer_bar_spec.rb | 2 +- spec/features/error_pages_spec.rb | 2 +- .../user_filters_errors_by_status_spec.rb | 2 +- .../user_searches_sentry_errors_spec.rb | 2 +- .../user_sees_error_details_spec.rb | 2 +- .../user_sees_error_index_spec.rb | 2 +- spec/features/expand_collapse_diffs_spec.rb | 2 +- spec/features/explore/groups_list_spec.rb | 2 +- spec/features/explore/groups_spec.rb | 2 +- .../explore/user_explores_projects_spec.rb | 2 +- spec/features/global_search_spec.rb | 2 +- spec/features/graphiql_spec.rb | 2 +- spec/features/group_variables_spec.rb | 2 +- spec/features/groups/activity_spec.rb | 2 +- spec/features/groups/board_sidebar_spec.rb | 2 +- spec/features/groups/board_spec.rb | 2 +- .../groups/clusters/applications_spec.rb | 2 +- spec/features/groups/clusters/eks_spec.rb | 2 +- spec/features/groups/clusters/user_spec.rb | 2 +- .../groups/container_registry_spec.rb | 9 +- spec/features/groups/empty_states_spec.rb | 2 +- ...ith_external_authorization_service_spec.rb | 2 +- spec/features/groups/group_settings_spec.rb | 2 +- .../groups/import_export/export_file_spec.rb | 2 +- spec/features/groups/issues_spec.rb | 2 +- spec/features/groups/labels/create_spec.rb | 2 +- spec/features/groups/labels/edit_spec.rb | 2 +- spec/features/groups/labels/index_spec.rb | 2 +- .../groups/labels/search_labels_spec.rb | 2 +- .../groups/labels/sort_labels_spec.rb | 2 +- .../groups/labels/subscription_spec.rb | 2 +- .../user_sees_links_to_issuables_spec.rb | 2 +- .../groups/members/filter_members_spec.rb | 2 +- .../groups/members/leave_group_spec.rb | 2 +- .../groups/members/list_members_spec.rb | 2 +- .../groups/members/manage_groups_spec.rb | 2 +- .../groups/members/manage_members_spec.rb | 2 +- ...r_adds_member_with_expiration_date_spec.rb | 2 +- .../master_manages_access_requests_spec.rb | 2 +- .../groups/members/request_access_spec.rb | 2 +- .../groups/members/search_members_spec.rb | 2 +- .../groups/members/sort_members_spec.rb | 2 +- spec/features/groups/merge_requests_spec.rb | 2 +- spec/features/groups/milestone_spec.rb | 2 +- .../groups/milestones_sorting_spec.rb | 2 +- spec/features/groups/navbar_spec.rb | 2 +- spec/features/groups/settings/ci_cd_spec.rb | 2 +- .../groups/settings/group_badges_spec.rb | 2 +- .../groups/settings/repository_spec.rb | 2 +- spec/features/groups/share_lock_spec.rb | 2 +- spec/features/groups/show_spec.rb | 2 +- .../user_browse_projects_group_page_spec.rb | 2 +- .../groups/user_sees_package_sidebar_spec.rb | 2 +- ..._users_dropdowns_in_issuables_list_spec.rb | 2 +- spec/features/groups_spec.rb | 2 +- spec/features/help_pages_spec.rb | 2 +- spec/features/ics/dashboard_issues_spec.rb | 2 +- spec/features/ics/group_issues_spec.rb | 2 +- spec/features/ics/project_issues_spec.rb | 2 +- .../ide/clientside_preview_csp_spec.rb | 2 +- ...static_object_external_storage_csp_spec.rb | 2 +- .../features/ide/user_commits_changes_spec.rb | 2 +- .../ide/user_opens_merge_request_spec.rb | 2 +- spec/features/ide_spec.rb | 2 +- spec/features/import/manifest_import_spec.rb | 2 +- .../instance_statistics/cohorts_spec.rb | 2 +- .../instance_statistics/dev_ops_score_spec.rb | 2 +- .../instance_statistics_spec.rb | 2 +- spec/features/invites_spec.rb | 2 +- .../close_reopen_report_toggle_spec.rb | 2 +- .../issuables/discussion_lock_spec.rb | 2 +- spec/features/issuables/issuable_list_spec.rb | 2 +- .../internal_references_spec.rb | 2 +- .../markdown_references/jira_spec.rb | 2 +- .../issuables/shortcuts_issuable_spec.rb | 2 +- spec/features/issuables/sorting_list_spec.rb | 2 +- .../issuables/user_sees_sidebar_spec.rb | 2 +- .../issues/bulk_assignment_labels_spec.rb | 2 +- ...e_for_discussions_in_merge_request_spec.rb | 2 +- ...single_discussion_in_merge_request_spec.rb | 2 +- spec/features/issues/csv_spec.rb | 2 +- .../filtered_search/dropdown_assignee_spec.rb | 2 +- .../filtered_search/dropdown_author_spec.rb | 2 +- .../filtered_search/dropdown_base_spec.rb | 2 +- .../filtered_search/dropdown_emoji_spec.rb | 2 +- .../filtered_search/dropdown_hint_spec.rb | 2 +- .../filtered_search/dropdown_label_spec.rb | 2 +- .../dropdown_milestone_spec.rb | 2 +- .../filtered_search/dropdown_release_spec.rb | 2 +- .../filtered_search/filter_issues_spec.rb | 2 +- .../filtered_search/recent_searches_spec.rb | 2 +- .../issues/filtered_search/search_bar_spec.rb | 2 +- .../filtered_search/visual_tokens_spec.rb | 2 +- spec/features/issues/form_spec.rb | 2 +- spec/features/issues/gfm_autocomplete_spec.rb | 2 +- .../issues/group_label_sidebar_spec.rb | 2 +- spec/features/issues/issue_detail_spec.rb | 2 +- spec/features/issues/issue_sidebar_spec.rb | 2 +- .../features/issues/keyboard_shortcut_spec.rb | 2 +- spec/features/issues/markdown_toolbar_spec.rb | 2 +- spec/features/issues/move_spec.rb | 2 +- spec/features/issues/note_polling_spec.rb | 2 +- spec/features/issues/notes_on_issues_spec.rb | 2 +- .../issues/resource_label_events_spec.rb | 2 +- spec/features/issues/rss_spec.rb | 2 +- spec/features/issues/spam_issues_spec.rb | 2 +- spec/features/issues/todo_spec.rb | 2 +- spec/features/issues/update_issues_spec.rb | 2 +- .../issues/user_comments_on_issue_spec.rb | 2 +- ...r_creates_branch_and_merge_request_spec.rb | 2 +- ...creates_confidential_merge_request_spec.rb | 2 +- .../user_creates_issue_by_email_spec.rb | 2 +- .../issues/user_creates_issue_spec.rb | 2 +- spec/features/issues/user_edits_issue_spec.rb | 2 +- .../issues/user_filters_issues_spec.rb | 2 +- .../issues/user_interacts_with_awards_spec.rb | 2 +- ..._resets_their_incoming_email_token_spec.rb | 2 +- .../issues/user_sees_breadcrumb_links_spec.rb | 2 +- .../issues/user_sees_empty_state_spec.rb | 2 +- .../issues/user_sees_live_update_spec.rb | 2 +- ...r_sees_sidebar_updates_in_realtime_spec.rb | 2 +- .../issues/user_sorts_issue_comments_spec.rb | 2 +- .../features/issues/user_sorts_issues_spec.rb | 2 +- .../issues/user_toggles_subscription_spec.rb | 2 +- .../issues/user_uses_quick_actions_spec.rb | 2 +- spec/features/issues/user_views_issue_spec.rb | 2 +- .../features/issues/user_views_issues_spec.rb | 2 +- spec/features/labels_hierarchy_spec.rb | 2 +- spec/features/markdown/copy_as_gfm_spec.rb | 2 +- .../markdown/gitlab_flavored_markdown_spec.rb | 2 +- spec/features/markdown/markdown_spec.rb | 2 +- spec/features/markdown/math_spec.rb | 2 +- spec/features/markdown/mermaid_spec.rb | 2 +- spec/features/markdown/metrics_spec.rb | 2 +- .../merge_request/batch_comments_spec.rb | 2 +- .../maintainer_edits_fork_spec.rb | 2 +- .../user_accepts_merge_request_spec.rb | 2 +- ...ommits_from_memebers_who_can_merge_spec.rb | 2 +- .../user_assigns_themselves_spec.rb | 2 +- .../merge_request/user_awards_emoji_spec.rb | 2 +- .../user_clicks_merge_request_tabs_spec.rb | 2 +- .../user_closes_merge_request_spec.rb | 2 +- .../user_comments_on_commit_spec.rb | 2 +- .../user_comments_on_diff_spec.rb | 2 +- .../user_comments_on_merge_request_spec.rb | 2 +- .../user_creates_image_diff_notes_spec.rb | 2 +- .../user_creates_merge_request_spec.rb | 2 +- .../merge_request/user_creates_mr_spec.rb | 2 +- ...er_customizes_merge_commit_message_spec.rb | 2 +- .../user_edits_assignees_sidebar_spec.rb | 2 +- .../user_edits_merge_request_spec.rb | 2 +- .../merge_request/user_edits_mr_spec.rb | 2 +- .../merge_request/user_expands_diff_spec.rb | 2 +- ...er_interacts_with_batched_mr_diffs_spec.rb | 2 +- .../user_locks_discussion_spec.rb | 2 +- .../user_manages_subscription_spec.rb | 2 +- .../user_merges_immediately_spec.rb | 2 +- .../user_merges_merge_request_spec.rb | 2 +- ...r_merges_only_if_pipeline_succeeds_spec.rb | 2 +- ...user_merges_when_pipeline_succeeds_spec.rb | 2 +- .../user_posts_diff_notes_spec.rb | 2 +- .../merge_request/user_posts_notes_spec.rb | 2 +- .../user_rebases_merge_request_spec.rb | 2 +- .../user_reopens_merge_request_spec.rb | 2 +- .../user_resolves_conflicts_spec.rb | 2 +- ...diff_notes_and_discussions_resolve_spec.rb | 2 +- ...resolves_outdated_diff_discussions_spec.rb | 2 +- .../user_resolves_wip_mr_spec.rb | 2 +- .../user_reverts_merge_request_spec.rb | 2 +- .../merge_request/user_reviews_image_spec.rb | 2 +- .../user_scrolls_to_note_on_load_spec.rb | 2 +- .../user_sees_avatar_on_diff_notes_spec.rb | 2 +- .../user_sees_breadcrumb_links_spec.rb | 2 +- .../user_sees_check_out_branch_modal_spec.rb | 2 +- .../user_sees_cherry_pick_modal_spec.rb | 2 +- .../user_sees_closing_issues_message_spec.rb | 2 +- .../user_sees_deleted_target_branch_spec.rb | 2 +- .../user_sees_deployment_widget_spec.rb | 2 +- .../merge_request/user_sees_diff_spec.rb | 2 +- .../user_sees_discussions_spec.rb | 2 +- .../user_sees_empty_state_spec.rb | 2 +- ...epending_on_unresolved_discussions_spec.rb | 2 +- .../user_sees_merge_request_pipelines_spec.rb | 2 +- .../user_sees_merge_widget_spec.rb | 2 +- .../user_sees_mini_pipeline_graph_spec.rb | 2 +- ...ees_mr_from_deleted_forked_project_spec.rb | 2 +- ...sees_mr_with_deleted_source_branch_spec.rb | 2 +- ...ser_sees_notes_from_forked_project_spec.rb | 2 +- ...sees_pipelines_from_forked_project_spec.rb | 2 +- .../merge_request/user_sees_pipelines_spec.rb | 2 +- .../user_sees_system_notes_spec.rb | 2 +- .../merge_request/user_sees_versions_spec.rb | 2 +- .../user_sees_wip_help_message_spec.rb | 2 +- .../user_selects_branches_for_new_mr_spec.rb | 2 +- .../user_suggests_changes_on_diff_spec.rb | 2 +- .../user_toggles_whitespace_changes_spec.rb | 2 +- ...rivate_project_info_through_new_mr_spec.rb | 2 +- .../user_uses_quick_actions_spec.rb | 2 +- .../merge_request/user_views_diffs_spec.rb | 2 +- ...ws_merge_request_from_deleted_fork_spec.rb | 2 +- .../user_views_open_merge_request_spec.rb | 2 +- ...views_user_status_on_merge_request_spec.rb | 2 +- .../filters_generic_behavior_spec.rb | 2 +- .../user_filters_by_assignees_spec.rb | 2 +- .../user_filters_by_labels_spec.rb | 2 +- .../user_filters_by_milestones_spec.rb | 2 +- .../user_filters_by_multiple_criteria_spec.rb | 2 +- .../user_filters_by_target_branch_spec.rb | 2 +- .../user_lists_merge_requests_spec.rb | 2 +- .../merge_requests/user_mass_updates_spec.rb | 2 +- .../user_sorts_merge_requests_spec.rb | 2 +- .../user_squashes_merge_request_spec.rb | 2 +- .../user_views_all_merge_requests_spec.rb | 2 +- .../user_views_closed_merge_requests_spec.rb | 2 +- .../user_views_merged_merge_requests_spec.rb | 2 +- .../user_views_open_merge_requests_spec.rb | 2 +- spec/features/milestone_spec.rb | 2 +- .../milestones/user_creates_milestone_spec.rb | 2 +- .../milestones/user_deletes_milestone_spec.rb | 2 +- .../milestones/user_edits_milestone_spec.rb | 2 +- .../user_promotes_milestone_spec.rb | 2 +- .../user_sees_breadcrumb_links_spec.rb | 2 +- .../milestones/user_views_milestone_spec.rb | 2 +- .../milestones/user_views_milestones_spec.rb | 4 +- spec/features/oauth_login_spec.rb | 2 +- .../features/oauth_provider_authorize_spec.rb | 2 +- .../participants_autocomplete_spec.rb | 2 +- spec/features/password_reset_spec.rb | 2 +- ...late_new_pipeline_vars_with_params_spec.rb | 2 +- spec/features/profile_spec.rb | 2 +- spec/features/profiles/account_spec.rb | 2 +- .../features/profiles/active_sessions_spec.rb | 2 +- spec/features/profiles/chat_names_spec.rb | 2 +- spec/features/profiles/emails_spec.rb | 2 +- spec/features/profiles/gpg_keys_spec.rb | 2 +- spec/features/profiles/keys_spec.rb | 2 +- .../profiles/oauth_applications_spec.rb | 2 +- spec/features/profiles/password_spec.rb | 2 +- .../profiles/personal_access_tokens_spec.rb | 2 +- ...r_changes_notified_of_own_activity_spec.rb | 2 +- .../profiles/user_edit_preferences_spec.rb | 2 +- .../profiles/user_edit_profile_spec.rb | 2 +- .../user_manages_applications_spec.rb | 2 +- .../profiles/user_manages_emails_spec.rb | 2 +- .../user_visits_notifications_tab_spec.rb | 2 +- .../user_visits_profile_account_page_spec.rb | 2 +- ..._visits_profile_authentication_log_spec.rb | 2 +- ...er_visits_profile_preferences_page_spec.rb | 2 +- .../profiles/user_visits_profile_spec.rb | 2 +- .../user_visits_profile_ssh_keys_page_spec.rb | 2 +- spec/features/project_group_variables_spec.rb | 2 +- spec/features/project_variables_spec.rb | 2 +- spec/features/projects/active_tabs_spec.rb | 2 +- spec/features/projects/activity/rss_spec.rb | 2 +- .../activity/user_sees_activity_spec.rb | 2 +- .../activity/user_sees_design_comment_spec.rb | 2 +- .../user_sees_private_activity_spec.rb | 2 +- spec/features/projects/artifacts/file_spec.rb | 2 +- spec/features/projects/artifacts/raw_spec.rb | 2 +- .../artifacts/user_browses_artifacts_spec.rb | 2 +- .../user_downloads_artifacts_spec.rb | 2 +- .../features/projects/badges/coverage_spec.rb | 2 +- spec/features/projects/badges/list_spec.rb | 2 +- .../projects/badges/pipeline_badge_spec.rb | 2 +- .../blobs/blob_line_permalink_updater_spec.rb | 2 +- .../features/projects/blobs/blob_show_spec.rb | 2 +- spec/features/projects/blobs/edit_spec.rb | 2 +- .../projects/blobs/shortcuts_blob_spec.rb | 2 +- ...er_creates_new_blob_in_new_project_spec.rb | 2 +- ...ser_follows_pipeline_suggest_nudge_spec.rb | 2 +- .../branches/download_buttons_spec.rb | 2 +- .../branches/new_branch_ref_dropdown_spec.rb | 2 +- .../branches/user_creates_branch_spec.rb | 2 +- .../branches/user_deletes_branch_spec.rb | 2 +- .../branches/user_views_branches_spec.rb | 2 +- spec/features/projects/branches_spec.rb | 2 +- spec/features/projects/ci/lint_spec.rb | 2 +- ...ssification_label_on_project_pages_spec.rb | 2 +- .../projects/clusters/applications_spec.rb | 2 +- spec/features/projects/clusters/eks_spec.rb | 2 +- spec/features/projects/clusters/gcp_spec.rb | 2 +- spec/features/projects/clusters/user_spec.rb | 2 +- spec/features/projects/clusters_spec.rb | 2 +- spec/features/projects/commit/builds_spec.rb | 2 +- .../projects/commit/cherry_pick_spec.rb | 2 +- .../commit/comments/user_adds_comment_spec.rb | 2 +- .../comments/user_deletes_comments_spec.rb | 2 +- .../comments/user_edits_comments_spec.rb | 2 +- .../projects/commit/diff_notes_spec.rb | 2 +- .../commit/mini_pipeline_graph_spec.rb | 2 +- .../commit/user_comments_on_commit_spec.rb | 2 +- .../commit/user_reverts_commit_spec.rb | 2 +- .../user_views_user_status_on_commit_spec.rb | 2 +- spec/features/projects/commits/rss_spec.rb | 2 +- .../commits/user_browses_commits_spec.rb | 2 +- spec/features/projects/compare_spec.rb | 2 +- .../projects/container_registry_spec.rb | 2 +- spec/features/projects/deploy_keys_spec.rb | 2 +- .../features/projects/diffs/diff_show_spec.rb | 2 +- .../environments/environment_metrics_spec.rb | 2 +- .../projects/environments/environment_spec.rb | 2 +- .../environments/environments_spec.rb | 2 +- .../projects/environments_pod_logs_spec.rb | 2 +- .../projects/features_visibility_spec.rb | 2 +- .../files/dockerfile_dropdown_spec.rb | 2 +- .../projects/files/download_buttons_spec.rb | 2 +- .../files/edit_file_soft_wrap_spec.rb | 2 +- .../projects/files/editing_a_file_spec.rb | 2 +- ...files_sort_submodules_with_folders_spec.rb | 2 +- .../projects/files/find_file_keyboard_spec.rb | 2 +- .../projects/files/gitignore_dropdown_spec.rb | 2 +- .../files/gitlab_ci_yml_dropdown_spec.rb | 2 +- ...project_owner_creates_license_file_spec.rb | 2 +- ...eate_license_file_in_empty_project_spec.rb | 2 +- .../files/template_selector_menu_spec.rb | 2 +- .../files/template_type_dropdown_spec.rb | 2 +- .../projects/files/undo_template_spec.rb | 2 +- ..._a_folder_containing_only_a_folder_spec.rb | 2 +- .../projects/files/user_browses_files_spec.rb | 2 +- .../files/user_browses_lfs_files_spec.rb | 2 +- .../files/user_creates_directory_spec.rb | 2 +- .../projects/files/user_creates_files_spec.rb | 2 +- .../projects/files/user_deletes_files_spec.rb | 2 +- .../projects/files/user_edits_files_spec.rb | 2 +- .../projects/files/user_find_file_spec.rb | 2 +- .../files/user_reads_pipeline_status_spec.rb | 2 +- .../files/user_replaces_files_spec.rb | 2 +- .../files/user_searches_for_files_spec.rb | 2 +- .../projects/files/user_uploads_files_spec.rb | 2 +- spec/features/projects/fork_spec.rb | 2 +- .../features/projects/forks/fork_list_spec.rb | 2 +- .../projects/gfm_autocomplete_load_spec.rb | 2 +- spec/features/projects/graph_spec.rb | 2 +- .../projects/hook_logs/user_reads_log_spec.rb | 2 +- .../import_export/export_file_spec.rb | 2 +- .../import_export/import_file_spec.rb | 2 +- .../projects/issuable_templates_spec.rb | 2 +- .../user_links_to_designs_in_issue_spec.rb | 2 +- .../user_paginates_designs_spec.rb | 2 +- .../user_permissions_upload_spec.rb | 2 +- .../user_uploads_designs_spec.rb | 2 +- .../user_views_design_images_spec.rb | 2 +- .../user_views_design_spec.rb | 2 +- .../user_views_designs_spec.rb | 2 +- .../user_views_designs_with_svg_xss_spec.rb | 2 +- ...ith_external_authorization_enabled_spec.rb | 2 +- .../projects/jobs/permissions_spec.rb | 2 +- .../projects/jobs/user_browses_job_spec.rb | 2 +- .../projects/jobs/user_browses_jobs_spec.rb | 2 +- spec/features/projects/jobs_spec.rb | 2 +- .../labels/issues_sorted_by_priority_spec.rb | 2 +- .../projects/labels/search_labels_spec.rb | 2 +- .../projects/labels/sort_labels_spec.rb | 2 +- .../projects/labels/subscription_spec.rb | 2 +- .../labels/update_prioritization_spec.rb | 2 +- .../labels/user_creates_labels_spec.rb | 2 +- .../projects/labels/user_edits_labels_spec.rb | 2 +- .../labels/user_promotes_label_spec.rb | 2 +- .../labels/user_removes_labels_spec.rb | 2 +- .../labels/user_sees_breadcrumb_links_spec.rb | 2 +- .../user_sees_links_to_issuables_spec.rb | 2 +- .../projects/labels/user_views_labels_spec.rb | 2 +- .../anonymous_user_sees_members_spec.rb | 2 +- ..._member_cannot_leave_group_project_spec.rb | 2 +- ...equest_access_to_his_group_project_spec.rb | 2 +- .../projects/members/group_members_spec.rb | 2 +- ...r_cannot_request_access_to_project_spec.rb | 2 +- .../members/groups_with_access_list_spec.rb | 2 +- .../projects/members/invite_group_spec.rb | 2 +- spec/features/projects/members/list_spec.rb | 2 +- ...r_adds_member_with_expiration_date_spec.rb | 2 +- .../master_manages_access_requests_spec.rb | 2 +- ...nnot_request_access_to_his_project_spec.rb | 2 +- .../members/member_leaves_project_spec.rb | 2 +- .../owner_cannot_leave_project_spec.rb | 2 +- ...nnot_request_access_to_his_project_spec.rb | 2 +- .../features/projects/members/sorting_spec.rb | 2 +- .../members/user_requests_access_spec.rb | 2 +- .../projects/merge_request_button_spec.rb | 2 +- .../projects/milestones/milestone_spec.rb | 2 +- .../milestones/milestones_sorting_spec.rb | 2 +- spec/features/projects/milestones/new_spec.rb | 2 +- .../user_interacts_with_labels_spec.rb | 2 +- spec/features/projects/navbar_spec.rb | 2 +- spec/features/projects/network_graph_spec.rb | 2 +- spec/features/projects/new_project_spec.rb | 2 +- .../projects/pages_lets_encrypt_spec.rb | 2 +- spec/features/projects/pages_spec.rb | 4 +- .../tags/developer_creates_tag_spec.rb | 2 +- .../tags/developer_deletes_tag_spec.rb | 2 +- .../tags/developer_updates_tag_spec.rb | 2 +- .../tags/developer_views_tags_spec.rb | 2 +- spec/features/task_lists_spec.rb | 2 +- spec/features/triggers_spec.rb | 2 +- spec/features/u2f_spec.rb | 2 +- spec/features/unsubscribe_links_spec.rb | 2 +- .../user_uploads_avatar_to_group_spec.rb | 2 +- .../user_uploads_avatar_to_profile_spec.rb | 2 +- .../uploads/user_uploads_file_to_note_spec.rb | 2 +- spec/features/usage_stats_consent_spec.rb | 2 +- .../user_can_display_performance_bar_spec.rb | 2 +- .../user_opens_link_to_comment_spec.rb | 2 +- spec/features/user_sees_revert_modal_spec.rb | 2 +- spec/features/user_sorts_things_spec.rb | 2 +- spec/features/users/active_sessions_spec.rb | 2 +- .../add_email_to_existing_account_spec.rb | 2 +- .../features/users/anonymous_sessions_spec.rb | 2 +- spec/features/users/login_spec.rb | 2 +- spec/features/users/logout_spec.rb | 2 +- spec/features/users/overview_spec.rb | 2 +- spec/features/users/rss_spec.rb | 2 +- spec/features/users/show_spec.rb | 2 +- spec/features/users/signup_spec.rb | 8 +- spec/features/users/snippets_spec.rb | 2 +- spec/features/users/terms_spec.rb | 2 +- ...user_browses_projects_on_user_page_spec.rb | 2 +- spec/finders/abuse_reports_finder_spec.rb | 2 +- spec/finders/access_requests_finder_spec.rb | 2 +- spec/finders/admin/projects_finder_spec.rb | 2 +- .../alert_management/alerts_finder_spec.rb | 2 +- spec/finders/applications_finder_spec.rb | 2 +- .../acts_as_taggable_on/tags_finder_spec.rb | 2 +- .../finders/autocomplete/group_finder_spec.rb | 2 +- .../move_to_project_finder_spec.rb | 2 +- .../autocomplete/project_finder_spec.rb | 2 +- .../finders/autocomplete/users_finder_spec.rb | 2 +- spec/finders/award_emojis_finder_spec.rb | 2 +- spec/finders/boards/visits_finder_spec.rb | 2 +- spec/finders/branches_finder_spec.rb | 2 +- ..._build_group_report_results_finder_spec.rb | 2 +- spec/finders/ci/job_artifacts_finder_spec.rb | 2 +- spec/finders/ci/jobs_finder_spec.rb | 2 +- .../ci/pipeline_schedules_finder_spec.rb | 2 +- spec/finders/ci/pipelines_finder_spec.rb | 2 +- ...pipelines_for_merge_request_finder_spec.rb | 2 +- spec/finders/ci/runner_jobs_finder_spec.rb | 2 +- spec/finders/ci/runners_finder_spec.rb | 2 +- spec/finders/cluster_ancestors_finder_spec.rb | 2 +- .../clusters/knative_services_finder_spec.rb | 2 +- spec/finders/clusters_finder_spec.rb | 2 +- spec/finders/concerns/finder_methods_spec.rb | 2 +- .../finder_with_cross_project_access_spec.rb | 2 +- .../container_repositories_finder_spec.rb | 2 +- spec/finders/context_commits_finder_spec.rb | 2 +- .../contributed_projects_finder_spec.rb | 2 +- spec/finders/deployments_finder_spec.rb | 2 +- .../design_management/designs_finder_spec.rb | 2 +- .../design_management/versions_finder_spec.rb | 2 +- spec/finders/environments_finder_spec.rb | 2 +- spec/finders/events_finder_spec.rb | 2 +- spec/finders/fork_projects_finder_spec.rb | 2 +- spec/finders/fork_targets_finder_spec.rb | 2 +- spec/finders/freeze_periods_finder_spec.rb | 2 +- spec/finders/group_descendants_finder_spec.rb | 2 +- spec/finders/group_labels_finder_spec.rb | 2 +- spec/finders/group_members_finder_spec.rb | 2 +- spec/finders/group_projects_finder_spec.rb | 2 +- spec/finders/groups_finder_spec.rb | 2 +- spec/finders/issues_finder_spec.rb | 2 +- spec/finders/joined_groups_finder_spec.rb | 2 +- spec/finders/keys_finder_spec.rb | 2 +- spec/finders/labels_finder_spec.rb | 2 +- spec/finders/license_template_finder_spec.rb | 2 +- spec/finders/members_finder_spec.rb | 2 +- ...erge_request_target_project_finder_spec.rb | 2 +- spec/finders/merge_requests_finder_spec.rb | 2 +- .../dashboards/annotations_finder_spec.rb | 2 +- .../users_starred_dashboards_finder_spec.rb | 2 +- spec/finders/milestones_finder_spec.rb | 2 +- spec/finders/notes_finder_spec.rb | 2 +- spec/finders/pending_todos_finder_spec.rb | 2 +- .../personal_access_tokens_finder_spec.rb | 2 +- spec/finders/personal_projects_finder_spec.rb | 2 +- .../projects/export_job_finder_spec.rb | 2 +- .../projects/prometheus/alerts_finder_spec.rb | 2 +- .../serverless/functions_finder_spec.rb | 2 +- spec/finders/projects_finder_spec.rb | 2 +- .../finders/prometheus_metrics_finder_spec.rb | 2 +- .../finders/protected_branches_finder_spec.rb | 2 +- spec/finders/releases_finder_spec.rb | 2 +- .../resource_milestone_event_finder_spec.rb | 2 +- spec/finders/sentry_issue_finder_spec.rb | 2 +- spec/finders/serverless_domain_finder_spec.rb | 2 +- spec/finders/snippets_finder_spec.rb | 2 +- spec/finders/starred_projects_finder_spec.rb | 2 +- spec/finders/tags_finder_spec.rb | 2 +- spec/finders/template_finder_spec.rb | 2 +- spec/finders/todos_finder_spec.rb | 2 +- spec/finders/uploader_finder_spec.rb | 2 +- spec/finders/user_finder_spec.rb | 2 +- .../finders/user_recent_events_finder_spec.rb | 2 +- spec/finders/users_finder_spec.rb | 2 +- .../users_star_projects_finder_spec.rb | 2 +- .../users_with_pending_todos_finder_spec.rb | 2 +- .../entities/merge_request_noteable.json | 3 +- spec/frontend/fixtures/abuse_reports.rb | 2 +- spec/frontend/fixtures/admin_users.rb | 2 +- .../frontend/fixtures/application_settings.rb | 2 +- .../frontend/fixtures/autocomplete_sources.rb | 2 +- spec/frontend/fixtures/blob.rb | 2 +- spec/frontend/fixtures/boards.rb | 2 +- spec/frontend/fixtures/branches.rb | 2 +- spec/frontend/fixtures/clusters.rb | 2 +- spec/frontend/fixtures/commit.rb | 2 +- spec/frontend/fixtures/deploy_keys.rb | 2 +- spec/frontend/fixtures/groups.rb | 2 +- spec/frontend/fixtures/issues.rb | 4 +- spec/frontend/fixtures/jobs.rb | 2 +- spec/frontend/fixtures/labels.rb | 2 +- spec/frontend/fixtures/merge_requests.rb | 2 +- .../frontend/fixtures/merge_requests_diffs.rb | 2 +- spec/frontend/fixtures/metrics_dashboard.rb | 2 +- spec/frontend/fixtures/pipeline_schedules.rb | 2 +- spec/frontend/fixtures/pipelines.rb | 2 +- spec/frontend/fixtures/projects.rb | 2 +- spec/frontend/fixtures/prometheus_service.rb | 2 +- spec/frontend/fixtures/raw.rb | 2 +- spec/frontend/fixtures/search.rb | 2 +- spec/frontend/fixtures/services.rb | 2 +- spec/frontend/fixtures/sessions.rb | 2 +- spec/frontend/fixtures/snippet.rb | 2 +- spec/frontend/fixtures/test_report.rb | 2 +- spec/frontend/fixtures/todos.rb | 2 +- spec/frontend/fixtures/u2f.rb | 2 +- .../issue_show/components/app_spec.js | 45 +++ .../components/charts/stacked_column_spec.js | 71 ++++- .../components/charts/time_series_spec.js | 64 ++++- spec/graphql/features/authorization_spec.rb | 2 +- spec/graphql/features/feature_flag_spec.rb | 2 +- spec/graphql/gitlab_schema_spec.rb | 2 +- .../create_alert_issue_spec.rb | 2 +- .../update_alert_status_spec.rb | 2 +- .../graphql/mutations/branches/create_spec.rb | 2 +- spec/graphql/mutations/commits/create_spec.rb | 2 +- .../concerns/mutations/resolves_group_spec.rb | 2 +- .../mutations/resolves_issuable_spec.rb | 2 +- .../design_management/delete_spec.rb | 2 +- .../design_management/upload_spec.rb | 2 +- .../discussions/toggle_resolve_spec.rb | 2 +- .../mutations/issues/set_confidential_spec.rb | 2 +- .../mutations/issues/set_due_date_spec.rb | 2 +- spec/initializers/secret_token_spec.rb | 11 +- spec/lib/gitlab/ci/build/step_spec.rb | 26 +- spec/lib/gitlab/ci/jwt_spec.rb | 2 +- .../blob_viewer/metrics_dashboard_yml_spec.rb | 36 ++- spec/models/ci/build_spec.rb | 24 +- spec/requests/api/runner_spec.rb | 38 +++ spec/routing/openid_connect_spec.rb | 5 + spec/routing/routing_spec.rb | 7 - spec/services/audit_event_service_spec.rb | 6 +- .../application_setting_shared_examples.rb | 34 ++- .../has_repository_shared_examples.rb | 8 +- 660 files changed, 1565 insertions(+), 883 deletions(-) create mode 100644 app/assets/javascripts/issue_show/constants.js delete mode 100644 app/controllers/jwks_controller.rb create mode 100644 changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml delete mode 100644 changelogs/unreleased/214607-ci-jwt-signing-key-jwks.yml create mode 100644 changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml create mode 100644 changelogs/unreleased/jc-pick-weighted-repository.yml create mode 100644 changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml create mode 100644 db/migrate/20200605093113_add_ip_address_to_audit_events.rb delete mode 100644 doc/user/project/integrations/img/prometheus_monitoring_dashboard_v12_8.png create mode 100644 doc/user/project/integrations/img/prometheus_monitoring_dashboard_v13_1.png delete mode 100644 spec/controllers/jwks_controller_spec.rb diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue index 90e840c5400..09acfd1cfae 100644 --- a/app/assets/javascripts/issue_show/components/app.vue +++ b/app/assets/javascripts/issue_show/components/app.vue @@ -1,9 +1,10 @@ @@ -385,10 +415,40 @@ export default { :title-text="state.titleText" :show-inline-edit-button="showInlineEditButton" /> + + + +
+
+

+ + {{ statusText }} +

+

+ {{ state.titleText }} +

+
+
+
+
+ + + diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue index 09ce2667d16..28af2d8ba77 100644 --- a/app/assets/javascripts/monitoring/components/charts/time_series.vue +++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue @@ -5,7 +5,7 @@ import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/ch import { s__ } from '~/locale'; import { getSvgIconPathContent } from '~/lib/utils/icon_utils'; import Icon from '~/vue_shared/components/icon.vue'; -import { panelTypes, chartHeight, lineTypes, lineWidths } from '../../constants'; +import { panelTypes, chartHeight, lineTypes, lineWidths, legendLayoutTypes } from '../../constants'; import { getYAxisOptions, getTimeAxisOptions, getChartGrid, getTooltipFormatter } from './options'; import { annotationsYAxis, generateAnnotationsSeries } from './annotations'; import { makeDataSeries } from '~/helpers/monitor_helper'; @@ -75,16 +75,31 @@ export default { required: false, default: () => [], }, + legendLayout: { + type: String, + required: false, + default: legendLayoutTypes.table, + }, legendAverageText: { type: String, required: false, default: s__('Metrics|Avg'), }, + legendCurrentText: { + type: String, + required: false, + default: s__('Metrics|Current'), + }, legendMaxText: { type: String, required: false, default: s__('Metrics|Max'), }, + legendMinText: { + type: String, + required: false, + default: s__('Metrics|Min'), + }, groupId: { type: String, required: false, @@ -368,8 +383,11 @@ export default { :thresholds="thresholds" :width="width" :height="height" - :average-text="legendAverageText" - :max-text="legendMaxText" + :legend-layout="legendLayout" + :legend-average-text="legendAverageText" + :legend-current-text="legendCurrentText" + :legend-max-text="legendMaxText" + :legend-min-text="legendMinText" @created="onChartCreated" @updated="onChartUpdated" > diff --git a/app/assets/javascripts/monitoring/constants.js b/app/assets/javascripts/monitoring/constants.js index a49e35b2d5f..50330046c99 100644 --- a/app/assets/javascripts/monitoring/constants.js +++ b/app/assets/javascripts/monitoring/constants.js @@ -135,6 +135,19 @@ export const linkTypes = { GRAFANA: 'grafana', }; +/** + * These are the supported values for the GitLab-UI + * chart legend layout. + * + * Currently defined in + * https://gitlab.com/gitlab-org/gitlab-ui/-/blob/master/src/utils/charts/constants.js + * + */ +export const legendLayoutTypes = { + inline: 'inline', + table: 'table', +}; + /** * These Vuex store properties are allowed to be * replaced dynamically after component has been created diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 0dd25ec5360..0c349ab73a3 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -304,6 +304,72 @@ ul.related-merge-requests > li { } } +.issue-sticky-header { + @include gl-left-0; + @include gl-w-full; + top: $header-height; + + // collapsed right sidebar + @include media-breakpoint-up(sm) { + width: calc(100% - #{$gutter-collapsed-width}); + } + + .issue-sticky-header-text { + max-width: $limited-layout-width; + } +} + +.with-performance-bar .issue-sticky-header { + top: $header-height + $performance-bar-height; +} + +@include media-breakpoint-up(md) { + // collapsed left sidebar + collapsed right sidebar + .issue-sticky-header { + left: $contextual-sidebar-collapsed-width; + width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-collapsed-width}); + } + + // collapsed left sidebar + expanded right sidebar + .right-sidebar-expanded .issue-sticky-header { + width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-width}); + } +} + +@include media-breakpoint-up(xl) { + // expanded left sidebar + collapsed right sidebar + .issue-sticky-header { + left: $contextual-sidebar-width; + width: calc(100% - #{$contextual-sidebar-width} - #{$gutter-collapsed-width}); + } + + // collapsed left sidebar + collapsed right sidebar + .page-with-icon-sidebar .issue-sticky-header { + left: $contextual-sidebar-collapsed-width; + width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-collapsed-width}); + } + + // expanded left sidebar + expanded right sidebar + .right-sidebar-expanded .issue-sticky-header { + width: calc(100% - #{$contextual-sidebar-width} - #{$gutter-width}); + } + + // collapsed left sidebar + expanded right sidebar + .right-sidebar-expanded.page-with-icon-sidebar .issue-sticky-header { + width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-width}); + } +} + +.issuable-header-slide-enter-active, +.issuable-header-slide-leave-active { + @include gl-transition-slow; +} + +.issuable-header-slide-enter, +.issuable-header-slide-leave-to { + transform: translateY(-100%); +} + .issuable-list-root { .gl-label-link { text-decoration: none; diff --git a/app/controllers/jwks_controller.rb b/app/controllers/jwks_controller.rb deleted file mode 100644 index ea5da62fb7a..00000000000 --- a/app/controllers/jwks_controller.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -class JwksController < ActionController::Base # rubocop:disable Rails/ApplicationController - def index - render json: { keys: keys } - end - - private - - def keys - [ - # We keep openid_connect_signing_key so that we can seamlessly - # replace it with ci_jwt_signing_key and remove it on the next release. - # TODO: Remove openid_connect_signing_key in 13.2 - # https://gitlab.com/gitlab-org/gitlab/-/issues/221031 - Rails.application.secrets.openid_connect_signing_key, - Rails.application.secrets.ci_jwt_signing_key - ].compact.map do |key_data| - OpenSSL::PKey::RSA.new(key_data) - .public_key - .to_jwk - .slice(:kty, :kid, :e, :n) - .merge(use: 'sig', alg: 'RS256') - end - end -end diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 9534ab19c39..a848c814742 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -276,6 +276,7 @@ module IssuablesHelper canUpdate: can?(current_user, :"update_#{issuable.to_ability_name}", issuable), canDestroy: can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable), issuableRef: issuable.to_reference, + issuableStatus: issuable.state, markdownPreviewPath: preview_markdown_path(parent), markdownDocsPath: help_page_path('user/markdown'), lockVersion: issuable.lock_version, diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index dddd9555f5f..d24136cc04a 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -297,10 +297,21 @@ module ApplicationSettingImplementation performance_bar_allowed_group_id.present? end - # Choose one of the available repository storage options. Currently all have - # equal weighting. + def normalized_repository_storage_weights + strong_memoize(:normalized_repository_storage_weights) do + weights_total = repository_storages_weighted.values.reduce(:+) + + repository_storages_weighted.transform_values do |w| + next w if weights_total == 0 + + w.to_f / weights_total + end + end + end + + # Choose one of the available repository storage options based on a normalized weighted probability. def pick_repository_storage - repository_storages.sample + normalized_repository_storage_weights.max_by { |_, weight| rand**(1.0 / weight) }.first end def runners_registration_token diff --git a/app/models/blob_viewer/metrics_dashboard_yml.rb b/app/models/blob_viewer/metrics_dashboard_yml.rb index 374c1b6953d..c05fb5d88d6 100644 --- a/app/models/blob_viewer/metrics_dashboard_yml.rb +++ b/app/models/blob_viewer/metrics_dashboard_yml.rb @@ -25,9 +25,11 @@ module BlobViewer private def parse_blob_data - ::PerformanceMonitoring::PrometheusDashboard.from_json(YAML.safe_load(blob.data)) + yaml = ::Gitlab::Config::Loader::Yaml.new(blob.data).load_raw! + + ::PerformanceMonitoring::PrometheusDashboard.from_json(yaml) nil - rescue Psych::SyntaxError => error + rescue Gitlab::Config::Loader::FormatError => error wrap_yml_syntax_error(error) rescue ActiveModel::ValidationError => invalid invalid.model.errors diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 8d4fe633aa4..b5e68b55f72 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -26,7 +26,8 @@ module Ci RUNNER_FEATURES = { upload_multiple_artifacts: -> (build) { build.publishes_artifacts_reports? }, refspecs: -> (build) { build.merge_request_ref? }, - artifacts_exclude: -> (build) { build.supports_artifacts_exclude? } + artifacts_exclude: -> (build) { build.supports_artifacts_exclude? }, + release_steps: -> (build) { build.release_steps? } }.freeze DEFAULT_RETRIES = { @@ -815,6 +816,7 @@ module Ci def steps [Gitlab::Ci::Build::Step.from_commands(self), + Gitlab::Ci::Build::Step.from_release(self), Gitlab::Ci::Build::Step.from_after_script(self)].compact end @@ -878,6 +880,16 @@ module Ci options&.dig(:artifacts, :reports)&.any? end + def supports_artifacts_exclude? + options&.dig(:artifacts, :exclude)&.any? && + Gitlab::Ci::Features.artifacts_exclude_enabled? + end + + def release_steps? + options.dig(:release)&.any? && + Gitlab::Ci::Features.release_generation_enabled? + end + def hide_secrets(trace) return unless trace @@ -951,11 +963,6 @@ module Ci failure_reason: :data_integrity_failure) end - def supports_artifacts_exclude? - options&.dig(:artifacts, :exclude)&.any? && - Gitlab::Ci::Features.artifacts_exclude_enabled? - end - def degradation_threshold var = yaml_variables.find { |v| v[:key] == DEGRADATION_THRESHOLD_VARIABLE_NAME } var[:value]&.to_i if var diff --git a/app/serializers/merge_request_noteable_entity.rb b/app/serializers/merge_request_noteable_entity.rb index 8e7456ce059..a356b5b5cd4 100644 --- a/app/serializers/merge_request_noteable_entity.rb +++ b/app/serializers/merge_request_noteable_entity.rb @@ -50,6 +50,8 @@ class MergeRequestNoteableEntity < IssuableEntity merge_request.project.archived? end + expose :project_id + expose :archived_project_docs_path, if: -> (merge_request) { merge_request.project.archived? } do |merge_request| help_page_path('user/project/settings/index.md', anchor: 'archiving-a-project') end diff --git a/app/views/groups/sidebar/_packages.html.haml b/app/views/groups/sidebar/_packages.html.haml index 67e759a4d63..59061a048b3 100644 --- a/app/views/groups/sidebar/_packages.html.haml +++ b/app/views/groups/sidebar/_packages.html.haml @@ -1,16 +1,16 @@ - if group_container_registry_nav? - = nav_link(path: group_packages_nav_link_paths) do + = nav_link(controller: 'groups/registry/repositories') do = link_to group_container_registries_path(@group), title: _('Container Registry') do .nav-icon-container = sprite_icon('package') %span.nav-item-name = _('Packages & Registries') %ul.sidebar-sub-level-items - = nav_link(controller: [:packages, :repositories], html_options: { class: "fly-out-top-item" } ) do + = nav_link(controller: 'groups/registry/repositories', html_options: { class: "fly-out-top-item" } ) do = link_to group_container_registries_path(@group), title: _('Container Registry') do %strong.fly-out-top-item-name = _('Packages & Registries') %li.divider.fly-out-top-item - = nav_link(controller: 'groups/container_registries') do + = nav_link(controller: 'groups/registry/repositories') do = link_to group_container_registries_path(@group), title: _('Container Registry') do %span= _('Container Registry') diff --git a/changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml b/changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml new file mode 100644 index 00000000000..9db7b230ded --- /dev/null +++ b/changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml @@ -0,0 +1,5 @@ +--- +title: Change legends in monitor dashboards to tabular layout +merge_request: 30131 +author: +type: changed diff --git a/changelogs/unreleased/214607-ci-jwt-signing-key-jwks.yml b/changelogs/unreleased/214607-ci-jwt-signing-key-jwks.yml deleted file mode 100644 index 66052c4a39c..00000000000 --- a/changelogs/unreleased/214607-ci-jwt-signing-key-jwks.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Use dedicated RSA key to sign CI_JOB_JWT -merge_request: 34249 -author: -type: added diff --git a/changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml b/changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml new file mode 100644 index 00000000000..1194adab7a3 --- /dev/null +++ b/changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml @@ -0,0 +1,5 @@ +--- +title: Add sticky title on Issue pages +merge_request: 33983 +author: +type: added diff --git a/changelogs/unreleased/jc-pick-weighted-repository.yml b/changelogs/unreleased/jc-pick-weighted-repository.yml new file mode 100644 index 00000000000..803741e00cc --- /dev/null +++ b/changelogs/unreleased/jc-pick-weighted-repository.yml @@ -0,0 +1,5 @@ +--- +title: Pick repository storage based on weight +merge_request: 34095 +author: +type: changed diff --git a/changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml b/changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml new file mode 100644 index 00000000000..e9ecbc0cd66 --- /dev/null +++ b/changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml @@ -0,0 +1,5 @@ +--- +title: Display error for YAML files that are too large +merge_request: 34199 +author: +type: changed diff --git a/config/initializers/01_secret_token.rb b/config/initializers/01_secret_token.rb index 3240621164c..8b96727a2a1 100644 --- a/config/initializers/01_secret_token.rb +++ b/config/initializers/01_secret_token.rb @@ -39,8 +39,7 @@ def create_tokens secret_key_base: file_secret_key || generate_new_secure_token, otp_key_base: env_secret_key || file_secret_key || generate_new_secure_token, db_key_base: generate_new_secure_token, - openid_connect_signing_key: generate_new_rsa_private_key, - ci_jwt_signing_key: generate_new_rsa_private_key + openid_connect_signing_key: generate_new_rsa_private_key } missing_secrets = set_missing_keys(defaults) diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml index 7c8dc2d0a32..8469b72c312 100644 --- a/config/locales/doorkeeper.en.yml +++ b/config/locales/doorkeeper.en.yml @@ -81,6 +81,8 @@ en: Grants read-write access to repositories on private projects using Git-over-HTTP (not using the API). read_registry: Grants read-only access to container registry images on private projects. + write_registry: + Grants write access to container registry images on private projects. openid: Grants permission to authenticate with GitLab using OpenID Connect. Also gives read-only access to the user's profile and group memberships. sudo: diff --git a/config/routes.rb b/config/routes.rb index 3fcc9941250..598a52cddb3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -171,8 +171,9 @@ Rails.application.routes.draw do resources :abuse_reports, only: [:new, :create] # JWKS (JSON Web Key Set) endpoint - # Used by third parties to verify CI_JOB_JWT - get 'jwks' => 'jwks#index' + # Used by third parties to verify CI_JOB_JWT, placeholder route + # in case we decide to move away from doorkeeper-openid_connect + get 'jwks' => 'doorkeeper/openid_connect/discovery#keys' end # End of the /-/ scope. diff --git a/db/migrate/20200605093113_add_ip_address_to_audit_events.rb b/db/migrate/20200605093113_add_ip_address_to_audit_events.rb new file mode 100644 index 00000000000..9f5694ddce2 --- /dev/null +++ b/db/migrate/20200605093113_add_ip_address_to_audit_events.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddIpAddressToAuditEvents < ActiveRecord::Migration[6.0] + DOWNTIME = false + + def change + add_column :audit_events, :ip_address, :inet + end +end diff --git a/db/structure.sql b/db/structure.sql index e78b1c41a09..053f6c6dd8d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -697,7 +697,8 @@ CREATE TABLE public.audit_events ( entity_type character varying NOT NULL, details text, created_at timestamp without time zone, - updated_at timestamp without time zone + updated_at timestamp without time zone, + ip_address inet ); CREATE SEQUENCE public.audit_events_id_seq @@ -13982,6 +13983,7 @@ COPY "schema_migrations" (version) FROM STDIN; 20200604174544 20200604174558 20200605003204 +20200605093113 20200608072931 20200608075553 20200608214008 diff --git a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md index 489c7425797..3b8be54ae59 100644 --- a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md +++ b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md @@ -50,7 +50,7 @@ The JWT's payload looks like this: } ``` -The JWT is encoded by using RS256 and signed with a dedicated RSA private key. The expire time for the token will be set to job's timeout, if specifed, or 5 minutes if it is not. The key used to sign this token may change without any notice. In such case retrying the job will generate new JWT using the current signing key. +The JWT is encoded by using RS256 and signed with your GitLab instance's OpenID Connect private key. The expire time for the token will be set to job's timeout, if specifed, or 5 minutes if it is not. The key used to sign this token may change without any notice. In such case retrying the job will generate new JWT using the current signing key. You can use this JWT and your instance's JWKS endpoint (`https://gitlab.example.com/-/jwks`) to authenticate with a Vault server that is configured to allow the JWT Authentication method for authentication. diff --git a/doc/ci/pipelines/job_artifacts.md b/doc/ci/pipelines/job_artifacts.md index d20bfae8bf3..1d60f412e5e 100644 --- a/doc/ci/pipelines/job_artifacts.md +++ b/doc/ci/pipelines/job_artifacts.md @@ -266,6 +266,17 @@ as artifacts. The collected Metrics report will be uploaded to GitLab as an artifact and will be automatically shown in merge requests. +#### `artifacts:reports:requirements` **(ULTIMATE)** + +> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in GitLab 13.1. +> - Requires GitLab Runner 11.5 and above. + +The `requirements` report collects `requirements.json` files as artifacts. + +The collected Requirements report will be uploaded to GitLab as an artifact and +existing [requirements](../../user/project/requirements/index.md) will be +marked as Satisfied. + ## Browsing artifacts > - From GitLab 9.2, PDFs, images, videos, and other formats can be previewed directly in the job artifacts browser without the need to download them. diff --git a/doc/development/telemetry/usage_ping.md b/doc/development/telemetry/usage_ping.md index bfd1b98d581..9ead605548b 100644 --- a/doc/development/telemetry/usage_ping.md +++ b/doc/development/telemetry/usage_ping.md @@ -562,6 +562,8 @@ appear to be associated to any of the services running, since they all appear to | `sast_jobs` | `counts` | | | | | `status_page_projects` | `counts` | `monitor` | | Projects with status page enabled | | `status_page_issues` | `counts` | `monitor` | | Issues published to a Status Page | +| `status_page_incident_publishes` | `counts` | `monitor` | | Cumulative count of usages of publish operation | +| `status_page_incident_unpublishes` | `counts` | `monitor` | | Cumulative count of usages of unpublish operation | | `epics_deepest_relationship_level` | `counts` | | | | | `operations_dashboard_default_dashboard` | `counts` | `monitor` | | Active users with enabled operations dashboard | | `operations_dashboard_users_with_projects_added` | `counts` | `monitor` | | Active users with projects on operations dashboard| diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md index 5cd24b4a6ec..07ef5dbb99d 100644 --- a/doc/integration/elasticsearch.md +++ b/doc/integration/elasticsearch.md @@ -512,7 +512,9 @@ Here are some common pitfalls and how to overcome them: pp s.search_objects.class.name ``` - If you see `Elasticsearch::Model::Response::Records`, you are using Elasticsearch. + If you see `"ActiveRecord::Relation"`, you are **not** using Elasticsearch. + + If you see `"Kaminari::PaginatableArray"` you are using Elasticsearch. NOTE: **Note**: The above instructions are used to verify that GitLab is using Elasticsearch only when indexing all namespaces. This is not to be used for scenarios that only index a [subset of namespaces](#limiting-namespaces-and-projects). @@ -628,9 +630,9 @@ Here are some common pitfalls and how to overcome them: You probably have not used either `http://` or `https://` as part of your value in the **"URL"** field of the Elasticsearch Integration Menu. Please make sure you are using either `http://` or `https://` in this field as the [Elasticsearch client for Go](https://github.com/olivere/elastic) that we are using [needs the prefix for the URL to be accepted as valid](https://github.com/olivere/elastic/commit/a80af35aa41856dc2c986204e2b64eab81ccac3a). Once you have corrected the formatting of the URL, delete the index (via the [dedicated Rake task](#gitlab-elasticsearch-rake-tasks)) and [reindex the content of your instance](#adding-gitlabs-data-to-the-elasticsearch-index). -### Low level troubleshooting +### Low-level troubleshooting -There is more [low level troubleshooting documentation](../administration/troubleshooting/elasticsearch.md) for when you experience other issues, including poor performance. +There is a [more structured, lower-level troubleshooting document](../administration/troubleshooting/elasticsearch.md) for when you experience other issues, including poor performance. ### Known Issues diff --git a/doc/user/packages/composer_repository/index.md b/doc/user/packages/composer_repository/index.md index 26517cfa22b..cccb91c45fa 100644 --- a/doc/user/packages/composer_repository/index.md +++ b/doc/user/packages/composer_repository/index.md @@ -141,3 +141,9 @@ composer update ``` If successful, you should be able to see the output indicating that the package has been successfully installed. + +CAUTION: **Important:** +Make sure to never commit the `auth.json` file to your repository. To install packages from a CI job, +consider using the [`composer config`](https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md#authentication) tool with your personal access token +stored in a [GitLab CI/CD environment variable](../../../ci/variables/README.md) or in +[Hashicorp Vault](../../../ci/examples/authenticating-with-hashicorp-vault/index.md). diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md index d42a58ba049..eb1933de62a 100644 --- a/doc/user/packages/container_registry/index.md +++ b/doc/user/packages/container_registry/index.md @@ -513,7 +513,7 @@ then goes through a process of excluding tags from it until only the ones to be 1. Excludes any tags that do not have a manifest (not part of the options). 1. Orders the remaining tags by `created_date`. 1. Excludes from the list the N tags based on the `keep_n` value (Number of tags to retain). -1. Excludes from the list the tags older than the `older_than` value (Expiration interval). +1. Excludes from the list the tags more recent than the `older_than` value (Expiration interval). 1. Excludes from the list any tags matching the `name_regex_keep` value (Images to preserve). 1. Finally, the remaining tags in the list are deleted from the Container Registry. diff --git a/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v12_8.png b/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v12_8.png deleted file mode 100644 index 8899852ed04fbba2708371a9ef4ff420a979f0b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29683 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

-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�n7#&3 zqQy+OIiE!pupTljE=eaz-CTli=ZmAbV8|@8MHg0}h~E9a!4!X1>3uucBYBx6J_dd` zwZGtQF=ZsX7Hq>N>M27EpR`1-S(MS`FB6$O_C}$#oG|{a^yTbeo?JtO?i4VT@Y?%F zIV72VoFHD7ke9W|LPIV4se;|y4eSpP2$!ex2c)TPd>T5CB?_XRD))NyGp$h_j~~e7nW94hW)=iZk{2oDZ-v^Thv8l% zE)qNIO=_SA2bmsKnI0982>W6_lgHCT9KVo^*eCXPot+Jl34H{ySpGlix*lpNm{5*5 z+b{Z2yM>Y3>Ft1?&R>UnKx+Fq;+)kKi2nb&fW3>TvEF`zf2&`>W@Az%BAWDv3k&ZE zW}8vvEx6rk%j61}tmf!~dO^H}IZ}SrV3TQG**j#u&%tI(;Q2U05~D)T-ks7~n?gxb_Cq`V% zLL5HPki3#~D`}Q*wJ}!4NXHe_GC>-|Gi|)m57!lsx|0B zF6?yvc;KHaw=7=3a-7C>j=Dw4Yt-UEaj*D;#aNeCcP(WWD|-6#y6g;j(}a>_a-D`% zk*?^f7-zQiuM;;tSl=8R^hAeaddtf<*doD2Mmf=B=Har!@g{G(`sjThr=E4FV(>&` zSG2TCJ5v>W+6Kn0zLee(o((_i*{-=vh=Omnr!swwl1N zM~Hg-ig_D<7;_;4DUKR210!Ce`#~LNvKF*O%Opx6N_&Cfv3_no=dmhzJ3sPR2}oh2 z2V9wiF@rNoZ>`#U%pd=Zut~sI#5bd-7`qXWnteq`S@nJ`v z#}K7?I!>O%wX%m_`zyl^qn1oU8=t-I)Sq8Km>2LP5MIujuC~e~ z6#(U|2QT1*mlb1MY?1NT=Tg^-Whe0bQXX;%CIrgY`Y}X};P=E(+vmwVG)b6VK%F^| z`%%slYouNx=YaIAdB_fAeKj|#Y|KdGUfU|V3V2s0?)7mmh;sk;ml&6apvcs+jeW(@ z&Yfy+g0c9Y(xc1zX%WUS+c}WVTYXtV*GSVBJ;~=Zlp{ba1C?zRcItN>Zy$4W&&;sx zkIPY{^Hp!d8Yua1a&xzh1}CnxSTCA4oPvtRUY&KteHym&WM5;fi0+$JTSugl~z@buz( z$Wd@Q4i2`m1m0IRXahQ{d`3&Y(-mDZAimnq2e-=~aG(bF`f2r9$bZpn>w~x z(<&Qd{hTRFT=Y8N`ue?M3<3V=>GI;YO%A2y?m9;OFrB4glJMAx&mLw_)a1q^{VMns z!BEqrlDT*JN=yHj&V=zv(1|H5sKL4w9a7Y^+D$ULs6z2cyk*g_EU$kZZ^@N;HTg7> z9Q%0tzAe}oe@Q{~{P(^IB+^XHj&y}ah`Wv8Ix$2gf{NehZ|0J|1rl1!`#B4g0^H*d*iWRa*2|Y zLeGw{?xu*%IRCcp&k%O|AB+D_9n2TL>k6B2k}E-f*4+h4DE@Qa+5hx#z@L@N@(k(a zh(e%FjpR-zaU$o}&MzJ37fr8RVodH=Kx*920{r3hh13mm5TdV5k^SQ)5j>fBw>8ay z5zlck*_hOkwTH9Ehs!nw2J#%quejt5{#mtmRYlUO1thYGS&y`*!y&&f*^Ov5g2AaQFxg+=Z?-B(h^Mg07; za>3>LBMZX;Umko!HEzs`M!JtYAoRmBccQbs(AZPh{fhTV_c0d=$cdaVxmdy!U7zV{ zyQ}+cV+uJ_u*G4!%IZK`JsIACHD+>J;B1)0>o04IJR8{yu^#1#Ky0eEhmpqLUVU&! zdgp{b9$5Waq{f#bLBae2Uu}o8as@MlEwa!!SPGrX4P@pqDSMImmg^>T?} zsy2g#W1(#$;C1E_Y$sXwjL22(J>&9DTA|J^8qQ{4B7v^9KQfUlZRQ`%*${}l&t zMxpR+@F@L9i)lOklBr)b?7X8BF{)t6J0Zhm!e|c$NQ`mtGM0S-*fGIwm4VDlQ@@t` z&nrzcnqb1xv`Ub%akq?sQ5sK2Q1EKt{x92Lla^1NXmUTO6h0h3=}Cj34>rol2FS?cOXCmx6`)ZctW5BQjY!8YxqYQT5+G zf75@Ah?)-pF&J@^kHeXc6-%&KKu!ZTeQH-v8M7_cD(F#7)sx6x&(DQ!x0(E1k~9lL zBDNTtYCd!_SJJ|+l3c$PSBEN;SSxyz)>h-5P`+~kKD5qjg zc$TVQ5Hv16tPc{5M<4@=b8<4!vLy-TA22^>w;&cwPF4S;A=jOjXZZtOeg%_`wiW3n zS~RADNTwGJ3w{Q>h59shL2rGbxAtLX@cI)W@n@=qAS*Z9Bq4ZP4+ex2NxY)aG?=W+ z)VaHxS$hCS_1CnFXw`ZVm2EQACkGP~U>&}SQ&bB{-Bpwk zt^;UHP`n~qHTrLZVdCFCY8vC&yYCD0>gNHn(CQ%_9Q(D8qfe5j-loqDdnWAPS zRsc@nB)wEP#h*+{V(jBSAX)9_XKS9)qGb_!*KYM@Q%DgRw$KGlYXf~Y3@zp*P=FV> zeEsm6IW$jdT`ypud$CnZf3vu_gpHGAThick2P*>mCq@X)wGm5^=L_!;m0dxstopm> z@+RMW?a5rNl!7gAzFl21LDOW`#p)z)df2Q@XEj_iRr=WruVA}0NxNUTFA7k-0AHdo z3cyM_Fr*{`+4q#@3*cTuhTv8w+@?EdDV-baF07@*_6G{gi&=~{FOA;!C{2KJQ@$^?`HZ<#XRD3c zA84 zS*ZQ>cycDU?bjteQ`EJFgTW_;Q?eh1@OwY_y+~g*NPMPM1(O!rco3hN*Kn70kP!Vs zpmR`hh)6uVa zWhnuFZspQ&*<-vKQ?LM%ZRdpDh)1^h#U6%1u!S&?>jed8C;a6cF);_k! zvw(OxUZQA}tIpBSbB9sy>O@c2S69`D@mk#e7(=|?c&=|jqbR4YoNh)IXH^~fSiI7n z>Op>r^59tgR{ze&c4FP_cf#pk>D})C?6__XhU^)q5yYIQ2tC$7{n_23glpB`uv!T> z3?5fysLwN(Q-ql50snQy?5zfo{w@CBH*l_h*Zi*=s2QU3-`TKWockAwU zPgSjHsr9tfYE8YWmK3HSC-E5p9{~UWeEuORsssQ)fdBxA0XV3S8nx-KI3GXI=0dVU z06P_?sk=4a+*_8UDl3{0QQwj?N#xhj)fH zUS6*6f;aZSo12@ftE-!P;GV(lhlhvR#T!)zu(~67W@cu8e}8@FZTkSMs?{qXRxprAn69;{>s{`2S0&CSj5@bDf8{Q3s&?d^?=i>s-r zG4cXWFWmV1`}dFRnR}(xZu%@PFOiawy z9$3K!EH5vAeSLj)306{48Xq6m_W*l%c#MvY`Xqq+`}^0n!A?$2iHV8k=H?C#4w;#m zwzjsqy1G_YR-K)l;^N{}ZD70K;Gd!3+}zxim6he?Wt%|o+}vDQGdL|Rjh~<2$jB(U z80_ikY3UEHtgLhn2d`{_&Hcbn&tN$#a7#-|Q&UrGYpX{zI6ORjVjf&kQBhY{x3sjx z%E}sF0AAbxFDxvSm6e62gAb0uz-4eiGI()uv81G=rV~5_1gDn0cXxN^*Mjx+_3OLA zpi^+y2zY)CEG#T6BO~ML>KdF1E@}X~MuMCAzynj@n|p9f9(ZaI%*4b*Lqp>g2fn%i zzrBM^O--ewq{1`79Yf%+U%&QEfVsK38yXr$XTg+|lq4i1$;rt%f5AmXMT3KbQQ2S) z4h|U$a8?zVo}PYg72G-ij*5x`&R?CJgT1}ItE;Q~M-SGw!SCv3UGUSd(Rkn zZ3jFuxnEj$*xq+|cKI^9bW`8H|MvD=SbLLEcIg^%XX^c8?f>APc)h*9?%U4Z3w~MPc)vdR)%l8`_D_582lXJK8i(7vR_Af3@ z$0rw7*3aKwpBL8OCa0J74$hB`FE@A2!*!5$002_J4^bf%_m$I(DeD~>+#$*p(N{W2 z7e3AMoUL51Wo>A>64cOs?64dY#s2IX;#g6sFVM8JR;Skzjxe*v(F)^WuK8i5@(N&6WgE?XP4iLK!T*vCIH(??m ziJW|^N*~)9pBvLBfj6Uk>a>_}%j53Et0Ph1APsP7;(lZAxr1 z=~<;Q(%8}zQs)qH?2_scQ}F|C);MEmeevHQ1IvmFjzV(snJ4fW0td`Q57k8)CMOk+ z4=L*JUD9H?u%W7%-v#mTGCBlUCL3Jy_k@~syFl_uuRr998ebGFr_Tmm__LZUXsp7k zXZr(~<_xup!w5X8Ogmm8ImgP*& z8C$Rv7Puf+ss05jHHCY2g3>MY%@Kg3VEK*p>6O*b!LMm3P6St z3dsTM3oY7ji^Fk$RJ`X24UJi*$;uESq(FYO2J7bRzC0ir-@ojCcU^ZI`o0sP=DASX zctQ-(YNrT(NYFU5htZ9C&6)Sby^XR;y-FG3Uj3t#6ZR|I|K?|+-C9U4Bqo)nWqzlr(rb7#FlJHHt?T^&rEy(Zt-T;?0p ztl+dXU!Dv2ou9(+y0}sm>HRFi9ZqHPTT7Byrr1ikDuPNc_@yYtNjfKQ50z{16%kvc zZ>QVwk04X-ulR*`X3*Fg!(6$xihuLSgs&{3KsB7-M8=pv|D&(fbcoJh8Itf~Gl_^5 zmtnWBM@{VS;?uxsS=n~Bz|Wn(p4t(Ge9>}3-la~6KY2e`>mqR?ImJ=L<&NEUn0P(# zcygn}xr@MQ5;c;64rUrH!HG;zi;2ym=1iVOMJ;8~;UZTlC%x-8HXn(`R&n;}CsiV=LILl1khu@zw89|~RxO*iRR6^4&muUr3 zB5E{b@XDL~N^q&XjWQgbgNR{5vaF8v>1}7PENR1iNS&dDBcC3!N5;YyNrhe^5Don<>J6f<`}}%#GzkO+Siwf3vIC`fjXKrFck4 z%jAkppmEB3m;l|e8D*liV^NTg81+*+%VdmrvP*uoo8Ee)|9aJ^?rTiCB$XxEc~ye8 zQqBulk6td3KClN)$oD+Q8a|%-Zd4}yi$^Ls=w)wphkEI7a9)^_-)O8)L->_b`_HAb zhoqh+Vw@GnzR@htZ*&)y{QU)jL#vcOX%pHDej0~zSoUH;)#3QAx=wHsh5o+xYU96wy^EYhbfx%C+(qu~ z%=KPntQW?ld~RLjNG$kGNWfr5bAcOn9mDN@{4QJuLyps!6PGF3Qp*%RV!}s9oCBSt zZ}&#K5)<^ecb-afBM9}+EPQR4JY0~>+T%|NK=?5oSWm6oFK40SvkX*D98dgX?##}B zGI)yLsCJe?=#UsdQc}$w^86NEm&G!IT%`uPJ~3A%4Q21`7j$hv$wz!^<}{4~sp-d$ zI`%n8wJ$Uh1p_ZH|EHO7OIWZRBu0yGuTi%G{y@;I+1Tn4D5rkg91XPtYdAM0=POU; z&2FuT<8kLV=CLdt>>zGtfDX1q0l~26g}E-0Xjnuex`Ec#g%R%I1A=M1t*Z4WlksJ# zNW+8Pr^Om2$Efo$&(G$+1nZ?a{5zcnNFW?0@NicNZ>a#EYL;7v;-Zxg53y(|U|J7) zZS?f&$7`?x-cJ`ngJ{d_Q0+K8)6!MIIOj;3`UgH?3wy?^JXpW{C;Utv2r{YV_Z&A? zI20i=6nYCT_w}C#MLPn%I%v)~JE8rTnwEVlynrST)H7}lsXE(1{|z5&`_JK;2E z2_!kMil;2l&aItj?VraIE}mRcQ87G!}e zfVKTDH!MKW0rAk~9=QiJm}ImQEYFU2I=$q`POo= zl5<`6^Q|%exEletG8qxwoapq+IO|%~h*lD{ZqE`0sl`tgyYlob*B?W+Olc8ZzguKn z%ZfJX1u2hhpeq}DTk36uqp8uHG26Evxg|FFwhHS;NtRrilEUwddJoa4R!=w3D+|cR z=b!Fh7M)E;gHRdN8N?MuY>v0g?sd4=5R6WHM)7n>&BkuKtJ=Peng+3r@aDh3Of%d! zqxN(NKkYP2(i{tyF+@y=6So2F`aYCD{Cao3vD)xTmDfWGc!zXdFJ(A$J;DH^c$weK zG%tL*OjyV;m@N=)J~L5W{lpy`Y}YE?gP=;K@+#=qvm=I9xv~taFrydj9PzUK<#6JEQ)UI*0ak3WOF=hYd;KpMmLw}M>RxZFRf;Q8fWaAg>!L;)f=ikSSw^9cq^NcM6Xd3j2wJQN0Nx2pjTekrTPYe69_* znehb>qO$*n!in3jH0_PiS4UAYNLMmG6LQQVHs+PH;?p%!#OU^yr3NhvQHdh%hIVy? ztv_E$QnzB%UFR{ZS9^KTIk)5L)0ZYcYOgubh7+_CT4Pb?Z2CCrl~Q<79<-GK{IcI_BP zkc(%bT*C}O+hr37Yl!S4pWvy85#y;yrZ~(I3)t$c1~UUC5`22X&`iIH!P%YMqB<#) zMM%1hABQ`v!^tg-Bd&UA)!^N`h)JydZF&g|YjHC-@^+hib8HtGiKp|(;f6v`9@|?N?K;GU66)$qmi`Ar_ zaH1qsz-%v0@dYm?r>-ucJ5P^3OeU6&c5~3FMMRl4RL$oy(+>EDUa!IwY-|#=BM~_>GtE6DP+5i zTrwmA%?lN=a0>?69?4T<%acfc`+Xm|{zWysi$k36EBAntcOcq@bqPO34_~{Kh{I?@vkH@^6RN^u{t{F70{hz_wr0lEdREwdv2%xKym(cXq?|ESj}1d8(b#RPv%AN}3+El`?qU zoFPAMYBmM#cG&ZWV8eGaHDr1c25Rbyv+b2x$taRr+M0mbv~P+YOlacXL(c~JyqbpJ zW5}1<)>oZEFKGWnuVey#Idw+-@cOc%J=zRsE#ww;p4E1O(5lwo=CT~9lfH6|>yZsO z;ovq8{nmMLP0!hr=3Ck5<0kJ`6Me_9P~4H;9@E`eUje9eGhpOHNy2Npl-LoN>z@jZ zez#FUFc+zdYL9X9l8M3%N$6b@Ua}6ytFn@a^tcZddnLA6$VC2)pF$-gVXvUlk`dHrgln4MgC zMd~3ItcX%QDeAkNd5k_>>;ilMF0wSH^pzaP5fN4<vsyvV7OjiB# zz8hL7FwHeANAkn<;p*(7y|=vSNN5b0Z`R7uhV0B7Z3=VMc<3a@1gEbu;*-hl`f9-V zIwbARVG}h9O`Yi`3g#E>+_1NspmjoX%9)Vj)Z1;)(bKzlqzM#3YlS>#$%#~cd}j7k zmfgs}g4-<2TFSs4#bjo=rfSDo8uaeD3mvRYq;U*@jcnw z&v1+jr_)!Be5*@Ss+^yb!-R*G6035SJ347M`(6!?BPBPPPT+pFHUS4J(sL17CBl^v zZ{*S6u&2>)XE@8pFw|9cx)zfbewW%s_hy_kxGbx~h+e2_8PWNAd{b}|Hf4TtSM8pk z+J(1b=j<9{cC1=H;#YUKa#m);{vJ|$=WQf0k$sBAJ*Z$(n965tN3gQk>??UDnSHZz z7vf&2_p7=@B2J0U@a_CJKg}_(cw5x3sv1J(w#{3QI+O4!sv^*eBbWPh$z!1Sp;@&~ zOSqHt-QG{e3~Q5}a!=)PqYb~pEC zrRr+}*-XQTyFx&;HI{&N*oMqyzYEJmO{JOAtC~KIcevVd1gO=+Z`!u+59JllJnp;7 zR4|hZa|1pT{t1V*HGdl&aN*i#0rTx6HtBnsxh_q%PSQPl5cQbsImE}@%qjc6&{ls1 z*5~X2il=SY;|clKA?xEA9 z{_RfuMWZt~;25IT25}LFzadQgL<*~ghA(UP5z>4^4FgWML=%zu7y27|u1ABvg2ukg=hE(< z84liI=ltOtc&2d_&k&X(h8MBHKTi1E8csx1#hk73I9{m5;DBi$lVkq;hz-OqR`vA3 z4Bs?Ql+M#Vj^Jweg_ea&$OlrJNQ_4y(D@~H$NP>df4+Z#L3BAp1-|%0Wxd~ z@zHU!6X{KoCD&LQ=XcHW9#p4TR@&o`l4q9l?c%hjte;4)v#ptdG0lWw}U*YKR~&YO9=%I&PEb8S6^vbXKA zPtbHYRniPiQ;rK)&7|~0D@a$@*;sVqsK)gUEz`CnwaWF_P_0#6u~U^mgoH*GDipb0 zYnJI|zU|;5)J}%g=~Ma5y%v}FX}pp(HeE@Yw&U|`I47T43Z#&=ZmOI1=o!y*D%!f& zx2v)HBnxKIqVqG$`vlOtLbZprW5J%22>tON1S%L?9wgZ;(ob)u8DXs@^?BGdrDlYk zC3*7e3B)I+<&Mef{irOCi<9Y{sBco?*?2^8_vC3QoFra3jx4V7ZFt!tO-gm3+Ij6|$r_yW4cb^ZrcxqNlW$$f_Ury#Qg0XSk%+|D zFp3onlku8h?&4vu@9dd_(76d|12(A`%tgSbX43w{w_CYwBH6=%-zj?MCYhqn>`Kjf zN3>7TMHd4qvBzf6Lc_MprB^b=c1x%$#+V)BPIAwuMPK0t;^SK8Jtt+3A!`-c3`IkX zMuipMgZ|t;;lRYT?d?Qc(!0iD1AWsOZI8CyzN~4ic7VokpI1a7yu+09dDfWp5JdW{1yZBNSwLWuxr@Y*?0uAO7Z4?c|{zEH)Pg%VmN$kIBDPzgEu)W5Tc8L zZR3o8z5Ww%@L=7}$LV}`CjeO$ftZ!8MWQMsjivcFHTa;n)5UkeBz1{|dv&I|`#gQz z%~o$b1MfFu<9C8JT4t0sHAMTZ>NR~&s&U3xZop<>%-jje5pXl-@P%O3kdCK zrS@Qrc}awZsWbQKZv(%U3$G&R&$5T`Gmg=yc6q3+{G)yXLf z-b=Gx`!qr#8FQdWpPTj!E`3i2Ng_jpoB*P*9Dpr*EFu8lV{iZ8k>JNEmR>$c?hU5` z0JvOvlyMGmfdlw04lS)21J&310DyL3!fe@fCKy2XNuY}sal|Cq2jYv*ht7Yn{}cVQ zd;Smd7eLs%v=4X}K=tl_cE)4dFM2(R9m@Ws4ppUZ7omTEFD}vLWE>qSY@{E#ec7`6 zAa-$ov!d^1eJF6=b$9)TFlA9LtGZR4mwBzy*1q}C{)k^+Dm3qDpXRT~>tZ}otXCp-e)oQOx73t8^@YYDLH-6-6FtoQ8wGfRj_KB?H zS<0t_mIA`vy`URvFGP+#_f;B!?4^=+uYRXI!kA5@^C1ljh0%Vl)-@!NJiVYWnd|!x zbEGG{f{IRPByvkv1LFyv`r7vA6Yl=9^VEl^LDjK7E3AB8BT=U|`D~p$dAkw2>(vk$ z@K9dN&fJ?gi=({vPJ4lCHYUW1#ovrO>!nX^@>igKge^vdv%A&K3mJv}E|}$9s6x&OcGhhOy^fMoi}9 za+eYGhrW2sCuprOGiu)fH7XHhbRoptnLs{-y>23ZBEf*)n?LX%Squ1iuT!4H(-~MP z3`9=#gdbmjy+sV&ux8i5tWx2uk3Z@U3gsZDFgBt?$JwQ{kSK9`M3+Jo%gqjt$uZXS zl9^)NjNi>wVc)p2|@QTE(e38{dt%T<2Bu zZ4G7c@Jn7D*D`#|t7g0Mpne)WTtGrmCJ;b#<{Lc>&X2&f zsBow6nPrh5{(^pBeS68<9Ek$gxUpAP$#Q_x!R_z3t}>&?Kwvfw5+WWU!6|~3 zl5?&v;P^7Cp4SmovB6yE3FO;ti&UhK$gk^7ef>qacu+rwzxwHAc$h}nfP#@&NGGXglZy9TrPieMjQs;> z^07eKLKCYJGSyVw!;Ewxv98l}_Y>K3ysI&j{;DRy!JHC~7=^`90tj>W z_ji2)Z%P7pY29C3vV7ng39maP6c%EpMWu-p9|JXf`gexsc?ZMK^4!rGYTHG_EcZn{ zto>zmrF3GHWTl4&e77SJAo8|e*3>+kfw{RI3@a5gK3oP*i{^lW1%KM~hU#4B?9*}Y zOeZpoMFCgyd_}fYlQWB$Z$Kz%)n*|6b!|HN#Mv;`H+?%RU*gfimc!}4dDs(j0z>jT zS9;_F8w!2oINol>>e+E7TL+~Af4vy;NM;`3lAe=SrlX>JW271QYA^G6aB)nYq=Lqr z-|4)Z^DcHh1L_Z4nTUg~WhR9pVvF46qK9b&o{Y*Lnh#$czA%Z^0xhol-SCg5ld8wr zgfoxi8r#T6XatyI2rEv+ZfR(RLC(T^e-KtCOp<*(@5#Ag@~T7DJ**l&0Z(2=Jl(>A zcjJ-y7^6qz+d&j^w_eFB`O0Q%989sdF#1)po?=8`;vSFHZ_QpAc6Mw|1jt1S2KbH4 zPIX4;Zk4Wlpkixr9BR+9%RdVdAlJcM*1Nu)6~^i=Q}M@85A1b$0m0{5A(0m1l|*sb>9*Jc}u2CgClB1W_fBeGZA%vC@)_Afe+i(3uJ#{zHQ>PwKt1b@fF z*@f5V1QGv^4O`vOXD(pVy)Zpiy^7pMNwu#(nwv%95})rf*>p;m( z*k9|tx$D8_t`nKu$L}-iH+UPWpIG!M=;e9&aSwsWZ8fo+SUw1EhM7xbXS@Ya`-|>6 zqKT-0UF@YpPrxqz`6Q;$Qwq&68jTwif&oI zf-a<%Po8_E-xe~O2pvuYz74`L9LD;4oyKO0ZiLz${4xt?ycvR6s1&D6cZH7QJj(X6 z#z$1mqC23l9ou%ucC`)1df=ivx#<+>tLENoA{|#b8^;kYu%t*UGvjjDnka>otydHX zn&r}$9^bY#u=mKn<#cd8!1;lOCPgmJUZ1wwEU%q-ICfSn+w2JBlIF32BY-{FfHMD{ zT|(?GrsmcI+>vtg9@D-TAPL3rIe>)#(c)BiI;B$SYsR`NHd9lS!XH&NV*=m~cER zFVcpni&?37lV$Rz(h1{5C`2u;W2cP}KVBwno1HxI?gAi8sD9mZ&1D(b{DeZSDwG)|03&Sk3xOS* zTqVf0D}{J&<>xmNj;nUPuuOqBNciTBz`5E(1JzGlIP^F+NFydzj*gH*mFCPDKq!n2Ra0Nq_*i-)iOv6O zQz4GbT&qeDwWXxc6#}9M57yvxxl6i6qpn=p**yp1c$J4t_#@-r8V7iLGA1STyda{u z_%^2^aWafk!CCq`1Ko7v^Ai=L_6ZPz?$MRJ&C{>v+H;E}VCbHOtljQN3*t*Sl7CA< zJ9)Z%!D;ObFnij{I|(jd_QyPe6h9}a1G@s9=&GAWDMeESB_Z2+1ak9nJJyg1Y3In* zF_m6oBssXZ7z7b)-$>wJWb?{T6D30xN_whAPqZ4)Q_vFntCh!p2A$b}{M<|zUok`l zNC#f&{NPl+#=ScX%?dZU(*J^cS)X-%=LN2pS_6wV;+sV*jOE4cs$WOTe(cO^VsI+a z!gRmX7V35#dNTO_Jl9tGIPA+y(#QBh@`?r%FKpe#Gm}mAJZ@)?V5)-j1sG+dNYy;2 z&ix}{deu~6yhGqPTcMRl#r=^6S-S$%x^z{&-$iLi;9Mr%4 zH~V_Qe}efR8}mmJuS4QlmE@tTzWfGSIFl1CNp@u_q-oQOfkNp*84}@KSF7CN{6?y! zTqw@{FLVK>zd497`!8by#EANrEj>~b6(#4Pp$+}T&<7SxWX;?tFjx~#zn;H0fo&K% z1!KvkEz1vYV1p@|TAngrj`$88&L0GGK&Wug;mH2~Fp;Zw9h<#0AM6F^jqSQDU*%t9 zR35Z-b4rYun}?f+hyM3xtW-F}7HV?!vB7?r59tf4_i9vd^WpY7{L?`fvMDX5;@|l6 z9wZX1!p8Y-VZl@3TMLLI1zxUZ(5!tLghS~Vic(OMax_OsZ}XuGlYu8tyNf{_)O(Gm zfgY+GdYaK^pa8w| zu21f_0G1@!98xX3Uh1ei4~0&ex58_6uzP3SZjti5;5*_ruk(t~wr%;f+p+$Um=TlK zz*tfW;;s1CT#kznP*w$|Jq`d9@#oZp=6jag^|va9-K@Y4Qv1GykTjC)H2oj)S-)a< zU)QI0VC6aP{nbLfD2k9$=GNg1sof79u=@J)6*3-#Z+xDO7No zK6np=Tc^k#1n)N&KU-SN1h~NaSDQgGU^ai7%`I51FXzi6Csg}t;=jqMT&HRt?}6U* zVKS)5#=9F>K$Q5tb#+YLfC0XjVuPPkZkc(~Quv{DAJedYG=BVZmzS7iLAew?<`<@+ zfy(l>9G&}XRxhgBdQ|VdRv4_Jppt0d3U#p&- zesw5I{((QIPK=Cn=3(s~#!$tdzELlBH`}M+gpNIXQ*Jj?{#*8>S zbZ4jX+}ZDgU;gI8)l#P*b~00fhJ5=uEGe*e@ULK1nzCsOB^S>rv};}HS<__uQhX`Q zYCOE$@KV}m`;oa{*NGR%ZUWW6Kb7REh5?Ji$tZ&6GgqoSY5dEL^=tbQZo^1mNWpSD zr_M&2;%EGMK@aIcN2q>*%HJE!`m~wR^08_bYo&BT&!@%8m5fb7y&j*dXsCN+L@C=g zkmY9*8nFBV>%tRVo7%p$>0T{=oCac@JBS|;Eya&8JP5A&uT|R%VpNX97`8}?rN=A5 z``^>H&Z?cRz>%{2>`rK(g_T)kUVqz)9B*U9lW5^ePw_b}C)D^#%Mw&3&$u^rerN{t zibaOyJo?qV@-)9x&NdMz7Sq{!Gij*cipO5i5CZBQ$*n8Wo#Leo`us%~*ll3jh{{c_syL&LBBJl@VfOy6N59e8ne4lsv0egO6%GEPikMNdu%?dc+WWL+U;=x?+X=XTSk4{9XxY&xj zqVC4ZRb|KWo;rNjW)6ivVtfSB^n;Y2bZ(}Ovwj>K0Si+=U;lDP2dd?t?_5f>CP&w? zG+3vZ(h@Ojm7$r;6y+(~T}zIGXt@|6SGe=WxNcD<-q@eeCnoabXATTp2!p#%I@02Z zk##Gym?xw0l&h#wDioE=4)cdy(!=G}9$ePc)!*xl{)EcMSHn)mjNHa(aoQYWFYQ@V z-jK1oD9=s^$&6Ii&%jZ&?mBkX3bLrjhSxqx_a9sX+4!t^OPEG!2z=wPl09F)Usc)&eO-d?<3OK;b z7VSTmuI<^|8y@ z7*X2TI+9RyF1IkVsT9Tg%32aHf9LkT&Bp(n?J)knll6u6VX`&OsPR{1;0)SX{15g|#t43JKhq2Q zmO~YIMg**tfe@t6@$KAt(Zm z=Ybu*I-?sG@9+63>jQiuYUi2M%gnA#8GQ!~VKCvqSzK0b2n4*^o{PWj8laGh;5D+A@Q}4UGXTIz2++E=6ndY8u z8}sJdZ5*mYiE{up(jhrhI4xFWQZ5q<45H=Xt6|&5P>V zjT$b!Ntj-cvE<+`530*jwR&FJjE1qBvUP&v^m^u`sLTjda^>cRaD8Nbi1Ex56E{AA??s%ZtZ zVZ@JyrBC=Z9F5eqAu!(`j@Fm6?YR1O2YSu=xzB|^1sLST)Fap6_;N|i9JUUv`pJD| zu6Q=UPvP$wP?L)cQ`Gu1AxepDN^)g4`HaLrSK9&_<8hAKkHjESRp||Hy7hdwY~!(v zA&oz&6cLLjV>s-8%*TU=$nEsI?UcY04GkJN=;RqyYf3{Ux}W^D(u@8e9qK7+6RF4o z%2Um6D+GDef&AxA=54eJJ`aJyrz9|L91ZP%-Pl1;RFw*rpp4lZpOVB^opODNRai6g zEsh>i|GPHntvq~PzV8tPCmF7&;B~-fKN$g9-Y^P^CR48Lkc7C8Zv6b>_G~YEIw_N1 zYZl;ND_ia@NMW^gzS1C#zdTX%jA2tAcAl0+>_!d~J;ZMBK1rfH%6a&;WM+J1oWos? z^i*loes#0u1!1^59V;!*LbLswvgG57^vu`27g&M6zJf<6B)rc8UW+8@CO(7ubJUX< z=JXpz$sgy~x&7_cCofsmh31=!7*(B$-#y6?8aU+UJh|y|j8A{V1#|7C`3=QHktum$ zOIc!+Bs+YqS?SKHG_&28OOS1{tcoaa`a?1KeJsAiw$xQkFSuxi#OvKJ=s_YY<>KL{ zee>{%f9lZx9J@kW-2v8D)W_R+(9YZYf*}SREwn^bMzBU<&-mSUFn1M(tE|TAD#*Xn zVm6ts_~4Z!8zUKt9~%G?@mujDLoN@yozSd^nPQ*utAjyQOU$H! z!A`;|&}OF7cwE<{l_#zt@usbemS#n1BPKhh++%PvcFStN%k~o9BiYmn20Lz%-Y)to zt!)!r%Bia_Znn0LQ#~@OvtiR`Gfr=EDyz17Z#s*qqqvP)poj3T+cor2Q?lwMbo}{I zjH#%=^JP@f&JLyXW-x4$*4~u6)uQB^^2AkkO5*$Jb3+=D{rNJB{m0EKH;XzA758Hw z^3>R;lnstA^q-;z9R}8rv?M2!MQyF7$zagn<`9_mz{OOc7JUtk=GzV}oMfZDvcXq) zDDRtrn+_6r?caD25iDY?@FSn~SOO$jMZNmTjXIzYotJ2{hl^;`lL%T&E^;^I8GMtE zK=GUL>;{MPy6RnBuS?r~*8VdyQ}(B6iW9BP0XCmac<_Udd<~9~|88NMa7KMZT!;|{ zcjsNTd6x2QRem^>)l>|;5mHcp=M0m-Po}||rfpKaKVNRNNJGvzY?!<0iXRa|4O%>i zFU<(MV+iJgcebt?7wscckaY4WWSMk(zcuJfmI<+R8gA*)XmE8Q$}CDdY9YGL^P9HqFn^cY@_A{P=cgnyj2gu#j3c zywI#dze$loa+{}hF-@dJQ|;q1CB*&cnZI=MLV8a`S$CMuHl}8=VP~Uz7Oc3hxNWKT zJ;F`D#EKSK=nNn-R*0lQ5Lwttt4lE}=F#Ku;pngXoZl?3D$?aJnut7ZpPU@BTS+AR z5##3iJ?4k-S>FW)sXnYHyuf-yB`^U;HyxxCo0;09_Zk@ zEPg%RjBc9iS4|V;8JsC*IzwjZioMFGTZAJ}bFDK%BoS;Y{FgLPX|?|WB0xOQn8xNW469agX42Cj-?wT>7gn#tKOsLH*{!rDE3ZBS;(Jr&*uP&RMV7Q6qyL1 zw$760=IviqQk7lwWlIpNQ#6iV)2vJKvIp+Io?;~aGhz$|1 zxVMUvBx%^T_kDt$;a+|RUO5*H_lTz%$f4)|C9undC)R!DxrVz9_$^IB*dgR{m*zs? zw@)DHkwq()V&W;t8dof&Ot2S#KrE+m&F_6nU0BOr9?a9?>=uAJd}0^<<8JQ+PbR7* z6J}fB!j}h)f4JJI_Dkp#*lJi^Dafc0Si> z?L|%haeK>Qza@Z{fWyu=`i*bzTmAgfiF^Lyvge>ztx%xCeqg{aC+p7Qm|`t7dNWga zX8~w`^i1^%cnBJHes*j^BK`e6bYs%8o3Jk>vO5l5X);o9ZU=eCHM{8?*_jRX>pJBW z^PKg%+tG@Q&829<1P5>x2qcj6b<>Y5IT0F4u?%S9JCfQ8Jc-{S${(xlzH`DTA^kp~ zo=#mEk@K2Fx^39sCrR>kz7+|Nm^#yF=(0Hsn;(+Hu2@oGxu7hb364N3M;$_g%p8wQ zLRkKbr|1@msNf_kT&YwFFTOYP%5{|Mz?4&sfy+kinao+-X9yQGt@U*>1fo1PcI6~{ zrS>l_zV-ty=-0$dP#N+@iBi&Uoq+4{P~LoTVvH$s91^@4Xi;Q!Nw+v&cl2$n`l==HdrbdCYa_R z6wp(;jwoXeS6RWZ_J4ytoYZ&PSKlnH;MG-gEOQEynxQ^$aX0lgFhR$XM*;^z4saG@ zxsI@vA`;724wp=jOy{FF=$YQe+37TX7(opg%ow8v*AV26Tq^p7=yUfx*OEbhGOlNt z-?~w_mg0kab6)GlFnPpQ))cy|ae5Mr4m6I-k6^FgGNU>UeAv}EKs{$9AaY#@g zW}A(Ur7?lo^JeK7PF8=ITY(V7*|SOa22RB5j35g~&!L7pOb5hxX-igJ)kR8s`g zmR>(RcF9!{P6LwI%K3>%Ed&sO4ckLq)vZ@jVf>c$_fhdCk~`R970s~MTV_kkQNAu z!K2V!*KV|YV4zlWazfUB zb6^rI=l#s+sm`14rT6x@K+@FNc1Q1O?Qmx@vZdSCF<;)*l!Wr;aCvgPwd>}~`1sf; z!pG@;*tM4FErVf6JY??OQ$}c~v-mme$~pLW?I88fq@HElPqPQmXoY%H?O4QjW&k}JR3gd_UkA7Q=6~ZB@*e1cbnW$kj7mj7NgZHJj z^cfh0deQRW;7yWPSFaNX)FMWXo`Mo0#zvVhwZS5+%!18h9-V4=4_%j=b zyQiH;j+0X+5B(Y%=oI1-BR!o8a99eCWv$PXL<0&WZA?MsRKmHRdcQbQiIP2n>^ILZ zP6!Ai+wTUW0=)?~-{*bfOX16<-1f7Vx-5hkKJ7y4vWwl1k6{(mP~^d?QlV06VV~3| z!~N3bY@!8dwc$&)D%(eEn(YrmH?C-zRUz#z3`By&gbGwMN%60=@-un}QB0KPr*J^k z7xXkV&#&V)<>!Ye>w5Rk;S-0AB6v?2j#DqQb;-P1O?K-|F*O&pN@kmzw$?iFNp}Fh zkWB$V@1?@y`$uGx?-!vXKW=C^mG4QxdpcW6<88<7pmgwbrvTbO%@p(UU3WBZR5ZE0#b{Y??^8 zBpi9f*vSQFgg_BvX{4K#C({!8C?hk3;FOqF$oAH(lU%t z=ayHY8mixfnwvx5Z^G??VKZRdTYc^~_pWYfgj@Od1~X~J_dJ;ODh{L@o+0=7DJ1Jt zc7U~ArJpSRH+Z2%JVqVrKBkaJ-2o;=9gp=nr<*|p$b;o{;}3%<5MV@KUAiHydP9=; zF)$}_KnwRV@vdscRh^_L^P){l(_MOd>L1MSBx;0T=>ZxbMiJRiod>dfW7YfV>rnkRhU zX;;cwm|9!8Hzxg49%pP*iu%L(SlAz<&xD@P`WA6a^t*m~HD#6>Y68cAJ!EI$AOK-V zUcoRG&>^bC;+tcyc_*BszFi96F-vXwicqQ+&OY~~m=Y*Dkp!V!Zy#tZBJ}YF2d3k< z11qc69%MuVSNe#%B1`IEZnPRMu#SUh#J}?z)WYWx@xZz^=IIfvRo3>2t@M^9Qzy!3 zZqiWdr>Hb~IJCDlU$9{#X*8F2fEL=A*oekYX^*r6fK4}ABb{9sYw0*s&X7P)?vLeo z&*_`0HI4g-Jt6xZ29!FbzsbX7n6hf36n%=qg^V7bKQYkS6>vyMO;CeWo7of&e!^;d zx<}%0a6T~!Ddlu|IK3@oMl3-!idN51!DYjj#f26>bvBrzq_+rjM9d1Z{3t^YzTu!| z+^U5V#KXKL992<$k@?nNy9Gz~2X_^_`Qvd59VV+x0DT4ocNgw?5O0Yw=YCGt{{n|V zc)$7K@hg8j`B7TZpx3d~WiPqBDheT&7}c0nCJ)7C<5K3WmZ}8G$sBX4w=AZfYnaSA23Mk#5ZDi=`cDjK2)bCa#Ifa>TQ?y{{8Cij$}axb(L)|NeZjJJ?aCJYw;DD0b--**-f+6 zA}(P?Ca?*7##6p!G3A}@q$4|$6PPjImJH}8&m2rkJ8|Y{g3Fobzx?uCIh0X;e9QX$ zyqiZ?yp{>AUPy^!vct3Bx-f4C{{Q|PPP3kdWAIY3=B=zhoxu&FT+d<$@^ z6m=R{RAnGAg*mQnM^lNdT>{uuRU|;fU7Y6#QSx&gbPF*a$l1fz`p2Q?p#IrFZzt3R zI<=7PN;&9%IlE)orZt~Fzgy%u=w0qM<&^J}_UA3Zm=NSp)OV4MD!JV!kke4nqh!r3 z=KO=MGnVinofWgOmV!7Lu0@eleW6y4PVFl>fn^%-umR@Mx|npmtYH7QgwC?BZBuc%!KC(bPj!yQn@pUXRrbX?f=*7kENf8UYu?(ZOI`Kt8`!k(ImhZcm5 zfDnZeYSoWVV=nzj;S^f^=%2Jbsun!H%YE>4`s4rS?s{XJIPdVKYtwYo!VqgHpXg|t z#6s_>@vC`0)|_GI(G$DLu$Uu02zBSCbQu+QhIt-!&Dk--vZ$QlHA{m|Vxe{55iC6}ZL`+c#jJHL0f?|I+n{r!1< zPu2LC>3`?|dHXhvY2dwYf3gVs+rMr<0M{Sh{>y(J);xS5GXLu{3+2U5;Eykkk z{>O^&eSsZ^nKa9waEy=V`SF4{@>d1)4rn299wyfcbC(%M-%wNYm{{tLUB?jQz*Eod z+E~-vw)4Y^ox9KM+5NIO0X!L2VdB2;mztSFh+72e&&9_Q7Mw=eTlvDlSgO^EvHCB3 z{*DPVcGJM#)e#Juk{yewMO@#|aLa>ER)mkl^<-a-2B$X8l?Hdr;okx zTj6m8v?OG#A}UN(rBZ~MWf>P;)qQ9IJIA_5F8RE8L{!we6^ZMv84D?O$H zq{lE)9ZYOclLE<0{L^CIvd=BOB^3ODkMn>%r+kwL+m-GdPz8^b7C3 zBieflj+kwJd1Zc0zez1V&4J}cyAn>Sx0&f-7T_AwC@jfA>7yyM;9#j$j5&Stm)DMR z`30$y7Dy+=!>zLXFa`%_A;l?%Pmj8FeqQ6#woeM3aSb{!pBa~fHW=-3!=wjFN{9N$ zWu%9pJ!YZ9UJ~`sx#acXdAzRszRj=g`SDhnKv%Sy1+U9p6v^&ZDeaOC|^C7k5uIH#bkbvC#7?S8Cd1 zVu)5)cCo)Pj3pGdpkquhYl6M1*5dIAXo9}NzDuDr6*{1{$MJj~odX?7;wToE=Z8_e z;)YNMaXt#6rNaiy`iL2~hBYuS5A+l*pt+7=o-|>S>NFdTAQ^@Z!CpnF2b*;niDd_R z+wlu;9X?mCW#%{PHj5nYJM~hr`qrkVrWbdV0s1zxkaUHMWP3s`*pH-Uv2QCmRMy5j zhY*5x4+ICTI3DDnlU7lK%2fxtwzF?;KawL&RTdT3Z+PN?zV5ZU6Gt1jUtI0YbTpen z+QXLRE>cM2Ikh4dd!@?b2T>Lc=8BG8RZUt0hT^u>k`CdWP6_RL9>=5=br^I9AfSUX zXLN;tgD8hPIb3A_F}GcxaALe2FDO?i(>h8dhDs}iqNoQ!eB?MHV6+=f8TjJ%1YE^x=*wnL{YU)Xu{&`SvN-R;|dwd-Pep!=kv@xq_T;2y;4 z$~XJe3a(P!4eixODalYzFoIk~xj1lAW{T4V)9h$&5izWl0=nK8oqG&-V2$H61X$3Z&X9>dQhGzrFI&n%BcMD6g~NxT zm=)2QXyT3=71#fMWxTjKt_=dTL`1zW?q534D}K`0cIBnAJg;ucr%lbL>Kg0Cwcyys zS-Iz*p7?DM&}$W8-h|E6{1LtVDXYUm;%Skak=7QeryV9vT57A*%POH%I{X7+>!aIq zGueXl0~&I^-l;GIA+@7pF&gPB1@somlK<%=tkuq2Xezz7h`U^%pL=uP_K!}iGR}vD ztPRmyoMp-0Wk1Qv8T4`@V$;p0Gu2i(l-&TQMheS{2XqsP5+^P#vf~(I%m3E^=e@rE zQOy*Qu?!nz&gg_!0|o>PMO7%PBy42B3!N$y80RHwM4)TzA~7UJ86(UfdNDxck;G*xxBlVOGlveH z{PgIhi5&%?SE=I`w`QiZr&Sf?bYbXK<-|o0)v+lyq@(HH&R)Q311THNn@I{c~rD9RFn=1wMP92r!BEz&1Ob*!mt&0B(puh9;x8Gd#-fKgq ztf19fsIs2rJA%BvnR;8ViJPZ_ihP3%UB~?4;Sx1h$%(5{N*!AyXYn`*fRlq}iXK)E zr)8%^sYf*+&_e^@WxEu_B$-j6K5=B@oUgyiFic|n)!HhxmEpsjKEmPsEu@*odkM9V zDllJdoNxom}diT-~cWsg0KE3B_Gjh+*NpjB> z6&26iS}!F5n4Dpa?rwEOMZ}Fk)GgRjFx2kGP~2`OjkH^(3)-`$6h+Y_$GL&V*{QA8 zCVINtXGNm#8dV+DDGh+ByA8Ke=FIvwOY`rX?pZrllq;V$208G|P5Zo5#3iYRj^O5+8A$NWLUI3!I2kH|f5tgrvYk7neSjng=Ky}tgR*We8r{o}Q3f4a%_=%!U9fPbawzk{1M zZrq@$n>VKa{a^0RKDLSTj^o!=Aa84@3KhC(Qqcx@c-nKT?wKyOA?FEa?6w-YMcIWj z4fAjfr7f%NKdu&7#%J8l%O?3IzaTqU#@-gc#FlK=CkKtVuT0h=b& zR&=VgKZbT^L;RAA;X5``o{{GaOu_+0=##Lf7r7ZF7>OK{QTdk=cUU%KlPW7pMUnNcVFD%|C);^47o1ex~Tu) z(@($oomDu*$vuDXXB&3xdHErOKAbYRCkw{^0J>FNwaBcIL_6A~VI>s$(YA0)9W=T@ zuc~;Gd^1AO_&fzr9P*&sSSk5aEKN|Ez_bdlD+OU_6rvzKWdKW!S_BPA!xSdyuc<;~ zM#rqtQ(8cMl)FZ29UblVCY_;$j6>5=YL=eK7fwqBeaDfJqa%A(_@$GF-um&^KlkF> zCw{np>waYWa=GWG`0z)5fIFSWo7etzmApAU|BuDRMGNE3$D)>O^{>h3&1$T4{d(1r zE*1H=p1xjmq2yJl2LN9E@bPQ6H($F+fR8V~4^;WZZ#AWi`xQ<8XdHj{6UiFRPh6(1 zzJKM~H?0ogiTPp?QzI*Q2_g`8+IQYvazkL#U?iXuTl6zjat(5Zk)+1B@VX4~4eF#`aGPy-#8Z4)`O|M3tb_q_eLzu)`X;a47ZdTrDRC|Q8g zW6N@yKL609TO~>yEJ1Y5Tw&2BGhRLY=G8d2bK`Jx;{pC7RzBK>I@aDWgM4Cv+Wd zc~u3NS*f6(+xz7cZ*E*Ey|!u7rq4gN=4;Qrggm(!xhwa)dCl4>Za@ualYAr^c zH5;T`m17F^`KExQ;?7r@To65M*+dF8JD-o*GcijAWt@<7Ly`iFX(}f+1foo$tn{RL zj?CAmp=lNw9vwm|9^SP}5=P2Jy7ZCN7HyYQ0{hJ1xu2eV=7CnP2cmroiJj6p@mc^< zvSrSDii(yQji}oTW&QxIcYr>o*TwLqTi(Y*Zm#RN)`p1;vY@Ao0ffy16ha<$jYBC3 z^qkIJ(}n>lgxRqS1RAQWOz4>Q(xxNPRtR39peI}n2yolP7_FAe=$f;g3#4IHDVLi% zisP~>!Zj=v^kaYA_4+O`ao85D-mPSB0c2E3EZojcA#M|ZuO zGEFp)BI>2&NS)sz+-`t^nW!|-Ik%J3#sHZUKrch!^#?J|-2uA%{L*C!Y|0u&378I= zn};J-5h51D%{&AP_+ww06x5}LwZi|l;MJ%?b5cQHe{ko{gKvumU8ZKua=Dq6-ESPD zd0{|7bMro5Y<@bJn9oWPNEZY8a6Z)S1=hiIjn-NSQ#wi1ZlpYQBm#YAmac~^wCs@r z{l$GdfBwcf(V!1|mvy6`pRx9P0Yi>fjMfwm#{%+}^?usliocCI2@OLMqLdQD2HsL` zn_qNL$Be;hE-sveai0S(cAI8c5!8_?HIC;HyNXh!QW~I7)g_s4a`n`dSz8Bg!6~O} zCQ~G5rrDHtp}o4>A}UIsGYWLx#GUO&X(xin@v2XlZBA(S#Je8T2-0u~aA{-u#We__+>FNhDLk@?=c3l0xc=+~ek#&sGLg%c+4M01lEN;RvK z=9DC)Ak+gvpZNpeHDOOVNJx; zss^FFw8M^OQXGTopo1qRWH5w!aHAt2jO1N4T?O%x!5UYNS&C9S?+8m7YXI9F1+RsAK@o_uG za{KCZZ{!TvhpZ;0$vWwGa+pHBzheNUil$Yjv>89R#r)0j3#0st&!#;R;q z!wEU{z`Oy}(!T|@+Nw-I&=_^PP(T8RlH`h z@`%eHkoAU*;i3DfuG8|nnotgVcVF6)*8qnOK)!GoV~}a@s5foG}F?l>=4r5F2Tq z8LA-Gf#4deofWk#5$Jm}GcW$A;@ruX80fZV1bTkyoQAY$NYFdhj)cvjn2zzZ$sQIS z4cn*}fDYQceTEm;2Dc=jcVB%wCciIOqsj{*~rv!n8U+u6)?t>iPVoJpx+o-In!~BXyQ-F3!pWkC)8$0~Z0(5DZ zppv;@q^%SP&@>5Qxl1S5=_S>jR?1{;LktYy^W;kf`fG0=`00TIZ68K>u_1sZ*!AUt6R*`?E8@IbCq{ z<2NdfHB@?o~PrbIwtkTD?Nq*s~O`Lti#0R7B-}m z*$1qtA#akXT`AC|OI)$9=5qwPSYG!`yo~q_DDxzZtME|3s&bj_&_mC@me{D-#@hp> zyiC@FFB#~WA6z~D^Y^>oTX{flPqG^2&+1nM5gSA8yh=bbPc^$ZldnNXyXAAcv%CNa zKtS;7OI9e*_Z`p3ipgS@SM<>8BcFcvXirvI+0o+Fxqr#M_HCr+w{vkZHX*^dnFGyD zS6T;w1~Wdg!_%^)luQ+K zluRg!*4uO~XpWa7b!yIOq#6iUd1b6Q=K|EiP|g#w2x`^V!}A()3?L}o#fCJ{+KXGX zuFpRYIvLOz+c%N?Mz+y}HPcOKem;ukw~Xa%S3{K~>GC;I2*oMGT~O1Vn33s_?n;$< zy*A1i6)Ej()X`*eXO-u}fkx>;KxkufD z>cEgd8+3~pftRmOEKZYj9jb>C+(b;?& zt#^r=qa$B={<&jf=<=QZ9v?bNF75pObkyxEJ`C=?~UGqlS65GhHl>6 zS~N6Fg5h+%%Pm_UKAb-p!9a9#=r#i zG1#4%jEt;|v@-J#z)U6j{xjWw=dO_YyZ>(w7;XP6Q*F%Mk-H>DOsYsgc1*p}Z-&#l zKtFV5%{(CQ{C%1Tfbp5c<+3Ja*n^pcV~k@^2dBUMa(^26qC@=vdZyC!^!NAg-#>K+ z5Yy>;mtDr^O?PUV0K!bh&Gzx6DUM$v2twBJMgLNPe&p&OfBDugKB`y|K=)N87C2Hh zQ#B*+~xfJf(E(+PHC-g9(T?;vFOg84QCi!o}M>_{LprjGH%yWju-oZGO}XoWPMd zeSNLfin-B+V+1LT(Dt%v(|M&;svGbUzG#|rAEtKS|2p!F=chm4cPk0N1n-x329ulf z9JH0@Jksb=m+o5%3yX_O3e)bGJA;*5FlI8A|0Abp_?|$b3;euSOyky~MH{KwtN}wXx0IwxiotBR}Z*aTap0X4{s` z*^>Vrj_|8pT2mt{?NI5+7&c`>YFLPB=!CYaP*+!nJRT@FHqV!KL4g>!w4)JVls!3h%#`*ihEv6Lt3oZ1G?Jca~q5k!L-g)FW_2n2B%GYq6=t}$E{ zo}NQVF$lfTpjeDZ2@evqFrBYk*lKSZrS8JTa#3=##G*0ixk1H}jd9t#ckj;4&CN)2 z(xI|r6$R+e_MO-luMxZ9V8IIsbRX$^G@~jaVW4#YEMy^ome#ur?cVljvztO=YTS&({7x7 z-wssGi*NDp?H&#!S>-hxMgYCwfQqSbm=#GQ95GwAPY? z{7eJpOSsWWy@Vgq#)XMB1}5TJtVpvWf*IiAj3BIo(OX^wt=NuNade1{!F+yud9{{{ zEFI`iGSNOR_xvs4@XWh=kj$Qf%p+$%e8GSoel+7&ED^flqex#TFlqgrp=wql4{IFN zq7^0b{{iJ(?&?JDii`*_K+r^m5ikNWfy#BkaTx|fYRYb6w6^$TkP}JuyxYZg@L%@M zH@1ztjN@+8HU_~40?{{!7eK5X=y%iZ*!eC}?kEo97;e3e?AE)g>#4W2babliwVtb) zU^}L|Mw9H~_%u5+ZcOJti7h27u}m$I$;5I{iWJ;LeK8?~T2*3Vdr?i3c!Ri~oy33Q zv}H+?IQ8=;krO+1e)qZG^ZcIY`95)(1}iSt{H&8!pSUE}+TX9!VrEt@a}FOYPs)y_ z$r02|8;3Q?nY^aNn$fEEN-*ygXGNNA>~3(dY2RAO5<{FQ5y7=V4-8D`x5a`QraiXe z>bn)+WfkI&6!fy(^NYWFqaydb=fZ^^&2y)IbED@cb#l+!2=rb*C|?0s@|b!}P;^WZ zlUbL(+#$E6FK4#kCXdrCkkRG*%; zm}n6%{ImY zkRNYotQlBbQ;gkUCsNfphpP)*T*=Yx;pXwVl)Y>9TS4>_f}LD9=s!ON?MSoP9i1K5 zFG0EISD)XbzQUyw@4VJ|_-03)-19cD+Zm8qQfS_*&_(z)VoLAYRiZi5Kx1{JRyPE31)aT5Nz593q+4+7E;iFs(<2gPUO(uU-}>FPYuB2dx_7+P z^Cpyg{yvm@-gEM`L+?HPm#Wnu1GRT%fmsBWm2*hi9+xEay2bY z#e4(C55Gd!6>%gO14cfUGsOs$C$|aL4Wea%dcL%_;#}r*mqA~Jh5l@ z;ft4_KYs2P$17NW-4;j3+j~{0xhq zVH|e1nRUy)*|HAJB&!q?3?=dPL9*XX_`SKBQK$XdVxAs~c#Lxi*=KY*mV_w!EEE&( z9&kfhm|7bqO5}ZFJ5EGfpc`@R4=}|f$qk6npL+e}Gp}4~b{Ka7%00i?({mllJ@0$s z#Jl^hKdbrc7dn6YjT*V;ULnT_R=P4%EFio8clFz`og%)?WCEJ=t9~JsM)vx`&;Ks zj$uhKd26vlT$!v5M548aX$ZnEfTY>OYAuRO{afbcom*4_i>XwaE7ZNYC~Y^a%}JIZ zQZBxQK~FImYy&`lmGuS=SP&z@uE;hR-QOH4MVa#=uzY*2a%h=s66OuO^lR>3o(>Aj*}>Bm?l zt<|Ojt^t2twqCs{ti5CNL(W*Bm9GWTA!IiK^iv0qocz--I$O0e4jZfZabersxRIKU z2SpTT{Bd*v)3!n1I2#|xXK`BPwmgu8$a9vEk1viEp`ZglmYT&di2^xw89bG#=W{8$ z364aFlR7No6geCPA<{Bsnl|JzjcIGX-$^ts7vi$Srah*NsYFgYO)*Vcwuhp_oYw%m zx^xru;+|$SwDyjT^p6ektz14qhS|_Yfd1pFr>>qoy|-mS4-sX@E(MS|mQJuXcmQlk zG>U$GEBBZpBnMy z6xuC=(J0Llc0>27gg2s`MA?b_{*#OYL^XvT=4}YHdn%f0*9D@G7pDxaczyy^eI2#}wysi!UMuN`fF;~P2 z(^ObaG>&p|w|-gvuzXxhPBBzOqj3mjna8;#U}41@fR!pbel$Fq0g)Vy0yC*wwJ?Zw zVio9Gvcy>cs^CcsA@gEE9N+}mhsMcDX-S!!Tg2}e+UYC5$)F#@9VG7?^HpkBgV993p`46N2|`$9j$%VbJ2IC z={5lLy*K{&=Yt2&zR>DB`e4G7K{x=c@zGMeKM>XH+MsWw_1QE0%A66Gt1Fvp1T*Os z?BEk-*9K&Dw942uz~d~d#AW^fLO>JP9C&V+ei%(g&P z?h|~dw$N77XOnmSZGF9h_KR9B*2=Lgq~YepO_x2*v>hp0yx8 zCq9OeUe>Wx_@cg8zAmhYk!{c)6r*>3@q-&Dd!B4{(2p5C<|qKP*?=IA0p*(xx~8vw zv71ENP#nn!hmzvuHWgqKr5L>&dm}Du%+K1ISFZ45k=4F8nHMZhL52#>`dPCNAxBU# zQEB=>wAP7gCoE>*ylv1Qd>D89=v%-1!%M9W`W4pW$N+{L@HHZBD-_So`Hjc8@(gmXk`dOWV{UTm_>J3P*b8OKtL53@`RurG}y#N=vztsv!y za2xc8$fLh2B$M%tN`iKv)lTfXq$S42CAv_XFe(9b@-|Mbf(TQI|? zxl&*6-6&3@N;s73(zZe0D$o~Y!3lfW%8omryfBJd@$kth6o(=(5B>QJaY_nBsv7BJ zkl~i6rIIoCaw5Gqf%>^D)&~7S>9wzY`{>bwzyDxg>w?Z&r-B7PAy4I8k4bp`s6pRV z-;4f`plcDuBavNJ06lk+V+w|PPn-hg|7YXHg3N@rzvcy!4EsO!&Nim0EREyO?JK2k zxZP6fI@6YRd9ho{6pP{(Y-?KFu0dM1ZZRYX!dxv`GFq6@j2*-%_);QtqF@GhvXh{$ zj+5DJG%h3^YSuV)=m)IE-AvXG+ib!xtRSUeA=L!KmAQxTie^t*BSJheV=@C>7&ka z1bVv8QKlC2T)t&UZT1h@TNJaE{aUaLE*&IuH7Vnr#;nZdEnayQ(hf5a_Q4{k^WPuKmWvt`ZfL5})+)-b7xHDXNF)V@ z#jK>w^dqdvfF&$ndi?dkdF ztIe%8eHHia+Vs`e56MH?URe(pIDu{Y%h&&!KmX;Uii+I_-~6`c+edXf9&UUy`?WFM zom#~2HNEVjaHC8+D|5vXcFz-yei0Of>s!r1M<#(@^5Dw-tvN?IMWADm0FmU`+ZCd4 z15Ywba|K1XTL4TN?dgAh@oIOgyU&t`XDecsb@%SV)4x9t`^`V9HJX}7PkB%OR?+t? zn+?O}eZ%hlAx+Rl1=5#YRH_9AY4_|KC%0-*T4woR#fLJ@?l~`S^VX6)1p11|)F=U% zY4iEUIX-+YN^Z$C*O)L4yV|*wU4|ChY>0wAjC41ub{(ubM-=P!?o-V_$^ms!=S#8Z} z(96rW-`-YzqN@7DRs?#QpuZj~;}GaM2|DQ}UsrWu@1Ap;5$FhX1bP;O{*h+Kl_PsD zmLt#+=m_-e1zmTe;{AaS|9oACKu4e>(6boyE1JvY_b>M~BhV4(2=wd)z4`2+d%A(? zk5TH5Ku4fwG3X_oSFV+p90fh^`HoNsbObsAJ)1$#L!cwj5$FhX1Udp8 zfsQ~&pd-)`=m>NKIszSmj)Xu*LZBld(2)@6NErpXx=exrU9Z=ZwsK6#58dSu=-CE3 zCe!O>N&u4zfGw#+pyvkYbdMVk2m&srhX){y8bjk;1bSA3&UYGp_F7EgoB(Ms6tW=D za{~0RT_&DYhK71%Yyib1!|RtbI_lfaK`#P5J3$weO0=`BrrNFmI2y{@8&$=XAQ?rV zXF2GlVqi=fY!TxSk+Tc!Zf7GO$7BB5K!({pBhXh&ELQ)F8k1S;Vah5{+X~!f7z`rN zvmA7$DlivQ*G`0OS|X3Phnx+{ld%?mQNCYJyvSs-AFoeMZ>^_RRL5VJ8S(#0!6P@h zO-B55M&Yy*1dU$YlGu`oXzi=(bF{THL==Lqa?gwjP3?ScWDr2yU{Kh@t_60_-~A*t zrFtETzu;Z}rU3NQMl1pPlnc}iGHW*kYXL+(Jw2m2+S=b!9RIte#s9vAI?%fhOodyU zTw#V^J8YJ`Z7%YA=Zaaj0#VZLSy}u>YGNqfpi;CV4yExq3>u~J6^y05kH7Mqb7#%u z!PgIEZQ+1japffp(#V5_ z0n!PN(+gI-KTxY8=kB1Cq*SS(E*4N)TPE=aO5^93QQDcnPzo#9+9`o9k_g|(7^7r!+j(OpDx0~;d8 zl`R}*{3T9lib;Z)MQM>uUTUj^Rz_`nMd?aLqhw_qrb_Wb6-I5{@u&q+prW?;mr_cX~2?+ zEHPu3jS?qH?MqT-zAQ1StK>w#5mhFKFgcMEvAqW3PKVRXUJ9EM8-5m&MKV<;?^Q1$ z{&F#gxM4?AI?+YMO=E__MBN$4J5efG$*hz((+?BXX-H$XVB!+>AXmggN-OC^eHilN zf6LL@>NSCcOdXrXu+^trnV?*t#6T*~PbOnxH3)|F#BY+}m-JAYEYSe*T2jfA6;mb$ zXen+XZc&?`9v6m0#}g>>=bM~78&(pti()?6yGafmR%4W{G=`k< zVz6B&)u2CcnkepMG>tr(<_QCH${HfKj+RF8kQh3wp;){MN4t&#jJFXT&grM6nt5{E zy}%EK@FAk}h-PqK8EeQI>L5<|cB9kk=DTesz;L^I)j1cRRK}0(5x#mRgtx~}VqIcj zM&_izwMP~odwOx7k8F*wH8doU;GyyOxZcv>6Tn!Pg$UafPHWy2!>v&QMpidbOGJ~0 zqVaXv%C;E*OIHzqnJ8iEd3qBr1G*>Vmc{#R$ZcTuRM9gyEONrUij@wA3`SG082 zB5kF+0zGy|zq{bS#F{;e>RK0oml`8}3*uK5%?Jt>+Dw;#3Pwl~l96yN1X08sbM8!| zGK4{_juO;Dn@M4tUoc$?iKUPf!9R3&PVEaX3Nsdp5m)wJYd!00r@r~?aMpl?*#{ei z)j#(u4k+<;1!b-}5*nr1p50$B6hBJwe`6KBKpwAr9HBUPeY#WrbNv?yS+?A_yyenR zE!$Ft%MN*jN>5MKGJ2W$>H{$u#J`*KboX~2-a9}E<2dFdTD+U(a+kpr0^C;u62G{c z-ky{Gl<0CXn?_n<6N*;u{(WM8v>0@N{1*{I|8sq4{$gb@od{Jaw%-@>U1QE?-ODSB z3n4>`xJUYTc)#>_=2rsNYWbkVs+7@9(B_W)Tstm36=$G9a`C$apI`jFp!c1L7Y@?1 zeaT^IQ_e`+Ge2)jespK6RvTHJ@wfo3kNVGo{x%gxK(4^h*w5!dJT`DmSQJP$1@eON zll-dHtQRl}mqMb}-N`dvd;cPhq3 z{4BQwTM%w~ds;V5yO&>9`KZTPaeMsWdab{EW!iu(_>NCltRI>h2&Tq1GRDx=($S(~ zvKz%K>RD}pu@JmZ{GjM_o^tqm9>sm)+F!!hv}xqtmQ7PI(F$6hD?z zeh!$0s=3CXebA#bPNPeXDLx|JF;Gnc0c+=r$R1i>8rX&4)HxO9@NHik@0iO_*7CgC0Ym zH%t+8M>6sON|qrY_}|@(o+XF|?hNbNWzIIfm-Cp!)30I${DL!m)zWY4)fhD=MeDR= zrJObF+Fg>r2|6_)qS67`mql7KtPE@v*LMa7aZ)0k^QHc#7>_J$Zgpxr(tcBg7|Q4o zK*1LohFdCn(2$NNsmVM7dQYDL^9N>&9NPuEh^1I81A@45Tp@2Z| z)DLra3ddDp%^;Ig97=pIgA!2-huE2_O-Is?f?gx{939OJOXSO7`*gxu?*2>T&q8g{ zs%x{?Zsd094zgTQME}t%(K~ju63Pnd(PPTAP}mB2y`X$ySLYGa#~162bEve6j=i^b z+Npe5qD^*}g@VcK^~mM5Y}X%=ueM<~z^-g`N0N&dLoHaXzLiH6j$SShI(BNMzNDgl zKj>^9l|^eTm8INQ6Bo$yhe<8I8FZMXvXhplpZI(qPRN-w*Dk0Z zdSj_VYBFC`S0CHCbrbXoyUy?}Z!5?h`-751&v?|}CAn6CVoZ!LTH}JWePmskacVyx zsU~GL&m5(;_X`rhyT}$Oezm;>bt|H_9?2S$9jy4dDC5nJt(NQB=i+6nA}m)tRmkck zE^mLVU)Z}rr%>rmvn{L~7(GpuvTB^Uohcz8QbF z3hM0gWSi1MM~)npMBfjP764!Q_4N}l4W_Cv{M zB+GQZv247^iXEn=GL8D>D2*sdOcQkAEa!#~jeqPugjceX#fQhrR#vK>k*r+N*2xXh zE+a<5G_nF^4b&vU@^b@R8 z9>33w7in6YyEFGUw|P%#&mE?d*KT?{PKx5PK`nD^09}T zDz)bz?g@GV6yXCrNQ7`#G+Ij_SV==N1aaR(bKWQ_qdT=6+9vdfd;r~#a69I>yJ}z0 zSHXi7Jaqp#w>Jz8ilPc0Uk@S#<$-ADKlaY1wQX#TtF{EHg}PA}!7JqxB&#mUYzvvi<$j_2963(x zymb=Cc82QT)=BJGw$5{Y&+~uIQIn<$*Q{QY%!Q>zYiYVR{)=c-I4gJ6$Jtrk6Y9+@ zsPnGi z@7{QO^dCNcLJSjmiw^hdlk3r^?+SgP#P@HDhAzw%f-&Z)DH$K`XqAf4=f}DhM`}N8 zVyCp~Q9a?FJ9vN7Ri^g41PjA*y$}syfGah!FgF>{=O1kBtlWP{YbC*#Cv#$Ts{xL* zG)!ZYF^6fIR!@d%d@9+eZ%==Hi^qid!iW1SJ8!ffGuQ&7h?vc$X0mV~Xs(%JpxnTh zcQv}l!kB3ecdzRSbnO|y_MtHW&>P$PK4^c#ElIz~=&4DeyCxz;a4Ah~Ky`B{&VPH^ zYWsfc<%6+ort_7K@3;NUNB{g)8S84S0m3wL7|XO&s-Ov4RA_Y&?4_FKc(tY$N7%g# z)39EIoSD+T7Uue2n=tx*X9tZP^m||Z&i$>{Ki z{gJC^o56pc=8t#Uuj*sqTs#R@*MilZcIV4Ky;q}#rJ{!QI^k8Qj9)?#^)8_hr{Pb-H_1wfxl&EibE9t&d3| z9%NfZnGy<4nI{6!<25p3qj40e5d+4rIGZvJrK@>keq|ei3fX*)>RwvO%PSf>Z);JU z$ge_w!T&Zij%Z)bIhy??Zt>J-dVg&{hBGwLLmOy=Krh5<|8Q@57qQ=~_A;9hqof_M zae25=usA^x`%BKzxxlx2%HE+`>x`-G_yZ<;L(4d>2%9YFfY6`95#r`OFf>7&cHYz3p79mG^KyqaA>I&&+5V4W=s9nxoVa_u)Gnp!hUKdX&d;pAwYxFe!(=9>bI!3 zlTGO{+q9h}z`Z@>k5fy=$;)A=(O<(<$($%yncMo&)-yk#rw;R&cT*}Z3+?i%lnsy~ zZLpnS>gD2N;1ARgu~~>yY8`GlW$ArqT|BT@{;P1HfYO>ScWKj*ysa#X=&ChS>=*B? zhma9Qz_>=$8n12K1~YZp?DjNG&?aqnnhZCp1irMY`LYQ;m9=5@nT~*rhq6ke5PG9Y zTAJDjZ}O4Tj1W5?DIT4kedw7F;|y&$uB%(TxnwjU|q9(UWw#bpH#f*0I%$8x$6f3_9JV15 zePOW<$&Zh-icL_Gp!9k{>zYZ2i<7)#64?9a`%^;*7s4|^ZCOb!F#9TX9sHFpdZor5 z0fE?0PEt&R|KIn1jyXBpMOEhGA@dAzInN?A-LlIXeQ-{~BN_#xh=Q}TqxgnOjljU2uppX-~ zwM4asML^JWU9$;|jAGrPOl=NAjowFBU(v7vjl{rJlG?~B9rS&@S(N}!HFq^vV;vQm zmeDKvpVQPhy7>=J`fHBQ4F>*e69Z@u(?&-A6Iy{jvCTc*ww}`gpGzG!dEfOCd+A`O zepScHVj)Z_3C&3R{d!mX`hPMk8sAwADjFEyS$9r-cxAd4@e^k}p z_W$B)m^y!5(Cg#$_oL$6ix6(eoII~>L_rpQ=m!qYX^#(iooiZoNc!eukMsq;U^_yL)EXOm>+hLB#Se9L9DIlwXAO+{5?$@s<(m^os zt}rf7yMf>JXjCZ`dIwOH(J&A7Mlg? zlQCipYr{PV(c(lB%SBls?*e*hEg&bo%pAJz!yk^2?qb#JA5s#0zhS|*A1m^p7d)Q| zc6|Xg6 zbyIFyE_t&TJ)^9e(deKw3w?0BtzNwdjCmP+yst4P=1FxtI(Fyoe9mpZ^px9KhTWxK zAU#9K7hqCQs5IG*sw8K-N z7Rz4zEnzR0QGW8b8W&&__tb7;T5z^i9- zU#sTsv=d{_`l|W874H&f`4`K~C&P^0eX^HAO-FcN>&eo4Ftx|h^V|ArRiI4ngYz6l zNWSUe>B*0PwDUcJ;R8?j(3LLY!t9RI>c-GZGV9NnYuD66PqHr*Z#Ps!>51C=iC3k9bMxWr~>gDVLT1b$TYJcuzmZ^}8*0u`+>gvOiNUbdq0|H+)gUAdX}U0Btn!7o(L-!@j!C?& z0*qElPoFtTa?LjS6#jbDtum9*7daJ;NfhE@w$^1oP@?2dzE?G&*zX^e{};t1xKgdf zM8sOy6;50&vC2Xyu^Ys1%^(Jn?M);kC1-t2hl$8ogMa)e4!1MJEL6|U6 z{%yOp?wQA@NMhB-VX}CQjH^H#z_(;>h` z*;j6AphaD8w68B2DQvzd<(BB3l3V;rgl0$j56R{KL_#Z5tXATfbZ|lQPgv;cgxB@K zp8Y(|!F1c4ZA+IjsulO_g=mpBD zO=m72y4IA#k@AP3J;(uBzWH%IR76cw@6?<_Qa~kil?Q~9PUjP!^;T2olq9uVpMNo{ zE=8}A^)(wIndq^1pV$>vaQk?v;CRo4(jqyOXnRaEp<}$PGIKLwTADepgoLGeE6RPa ze+R1$A6jNeSTSzt)+y-X1Ej*+IpJb0nBLZR^>c4cb&fpW912_U>cuGreGm>i^kpW< zc!WKSJUbQqg^0S(jwTEqf7agAu|_yP{X4J}P#$Fw=OV7qIUK%z zOC0XzcnM#LA)R7dR#^Ep(bPC38lG?m8RZO$({;lPeDmSO2yApQJt?a-A~KsMU??=2 z(EUv!sGIM!kGWw6?VS8DicVf316|osfDM1CF8Dw$MKMQYCO50FBqr+F`c^Oa4L{gS z#IAvAm@_9e)8o^iczNSnoSrz5cR3|fr@d$6eg=ECyr`4F!K_wIv&q=&ZP6b~+YJn-+Km2`rsl_H zK+m%?X%-s!Ns1`mH)gzoH8O$xMlq+vx3Y%z>hGP~)qy8b`9Jw=m>*&Tc2wCF2o0lV zZ*(#S7fIPjZA)ICj`-)*=_3ca5l{Wp95`F9$Bj#(>~hps8lNA5{L$1jEGEyKTQ~*VVmMVT*8@KSFIYC4ITGvQdZ2XuH^?DIeon# zwk(dfO*pJa_hwZFQ--96CHR8(J2qzxb$IG_Fq^A|mCnj9rc^-O`F?A%zH6naT|nBD&;@>|X}PZha=^_%+tus0dE_0y$8k_)bkd zxz)i+_xZRPv*5jMbWD|Q#k@nOA}!HuIxkBHb<5IBzG)jlY~rHZZj7p}9U^}6XZqvf zkk1ByVl>0otIu{8i4C5m4E<@y7S5FK>SDDr{w!9&KUCCYkb(wDkYQF_i`IC*%;OnusWV+lvj> z$n+7>eOF>r=Hbx~w#U7ed+K8$BPNUd&a$mNRF?w^!;#RfD<=8UOWfMK)0wexemIuH+(ew|NYY((H zjl;s8j~{AVy;_n{AFLWG)1Z&L#@Gk$x7Y#%K+Uoagwi~)T2TP}@|~t)^9iTx?9?kY z{T7K|jSJeM4uSrA%3A4Ahv59NEpr8lpqFFrCdt1y{Qvb?ShTa04t}^&%@ZaXC&}Zm zHD4x{E3hYGaudC5wxSvRB7#81#}%Ov*l8vxXcdv3+-rcI-wdLUQgA_I;I;;}GgESe zZZVRG^B`x z{$)geiOzYkXZ_#W-Yp#3gGgMDX|Fs9p9K1lL-}Q z#`#K(!ydEM6JYZi50IH<;E_=K8n$r}!0NDIN+h(F_pa-FA|CU8vrg0aNMm~kK;l@U z(F!wzkjkfiV{`QxERa#msLXKcU*Xx?J7&R9idW{wt3TT5p57Fk-g0r1)Lq@!oDN1& z+tAvZH{nibq%gdhz8?~&w#(SzA|vjb_+zd}kYPto={>`5^zKWBYi7(R^$1bFd;U=d z-AO&OH~CIF%K3SX%X8x?paL^D0 zPpeiL!q{y;Bet+X*4N#<)2cf#-HEMP_y}`1@2%ymmi!9em_njdqVV!;{MO%v-#3wv zFat1q8rm@b3_J|g^|%(}1DnRZ`U2V~W#7pn-APmo$7Fe3-hDg_ky&toyq&a*pk~wD zh*}hcky5~z2w%~YjMWVH2=>P+KL)~&25KC8(O-`!M2;Yo{$>z4oI&Kcq&V0 zbC*Oq<*3Q|X0J}0pgc0qo^K6~RiuP}=kb1bwXNqwwbU<7XADrF2JxF_h~6STEc>my zJWj6XixG4rRkGMs(Ri{B=SWv%`;-?Z2{q!6r(NDa1 zJGJDjyw5FE?7GcVk~4(Ybm$~3=0MoW4|^l|WvLmV0&kICsxp`~y%!_|DusP|d=oDx zpnb5ksOuhrv{Q?E7>Oy|!ODDL7JeKcD&g z3^gDn>?6MY6m%qgG7+GxHyyt$?TV))O3)Fa=5@269&7#Y*&lv#OR);yc3NLiU?`H0 zJWjKbcIg=9lHti}^`T?ROP#Pf*xk?B68ORs7*#)@*+0Kuk|a1B+!F%V^!^qt(}l-P zsTfQXmbHM#0=B50wAlzsb8{P}t+>WL^qxA=ed4p?bb0jX`IVWFa*j*D+t4!N5Hl@_ zi7=DJ{#m70!(S^?7?$gBKgt4_L8@T)K!&V8?>`#*LT>#i{FM++HT&!ErX6yNU5NK$ z&8s5X-g<3c`L{5=5q3WjDl?o%++|CdSS*Eah7^jg!oPKFGg(l{iT*5R`6-WTqQHdhmPM1nw<08=oC*2E=VKjTPQb5BI>*tx&Ze@xpw+mFfmXqFo6A1*@`xN9&yeD-(Xxdz^M5sFNN7TvZk zrS+dO6SednqwwdD8HfkhzZ*R3U}TW~sTp@r&vlKJ&>bo}6eaNOL-0pEJzaG7Rab4n zQx9Iq`paFWh|eq*&z!gN7sxTl>Q0=coo$%gC2Vy?2Ze^j^%X5@?+ao{&@cICGJ^qnX zd4W*z^@>9zjE4%{ig?SgT~((wC8@0QHWS=E-hM6?=_YJB6RYmBNWuAalD*Rx*U{tC zj&|qFN?n6`MS1#zg`z{QmmN)msFA!!_w1Y*joKB#KP(39y7K>?CTu_BTTL&H5)Ffo z8M(;M5(FCqybxKE?Bf`}Kk_U?$=YP8z?3>qLA&?>Uh& z`%)ucb)qM`x3ujn)Rde$u{58GbKf?gFRujHTOc3^uC6yav(jcU!I-s3+@QvoW}zgF zKH&Mw!ztc`IxXaHN`-o><8MU_ISuIT+8d_A#_uT?IL~#PDCUZ%je?cdj7pC-AdX8u zZXKY0IM^`Q+38wKkPsJQJV7T&_RUX$6E>cMACRCaVfsxiJB+yZaQ^ zE4la^)1XeTu~q28njuOy{Gq<_nYgSd`V#aomGXG*eqHW!5x9IeZt!A6EBw@!wao0) z$yOd|7YK77m|mJ&yIG#tS+nHxz2M^jnO#+1`wSln>HobkeYOBNdlotN~=z1PAAc^NLRXA zYEh&%$w9|Ab-Yt@mBjFf#8*Ed;o6X34gh#AxsCCEp=E>uVz2aM!9=IloF~Pt4EqdT z+>F56@sG)v>Pp53MNA>L$WP}Oi)2?nujJggp7v+nPU0`#trQm!5 zP^~yT&@tzzvqOQuc|+@4$`|S$+eZEP&f{nMrR2XhA7iZ+3hk(6T^~b0=yHaO!p-Hx z00W14&2I(mzt~3XLXU0R&IjVhs6EqMfmk~j0tBqzy3#Az2VAS#2eQYvtII#HSxoRn z%B*(#R27UG%zVxMoA06Z59YGp@{-O^JQ#$Lm`)TJt04U*@fu;=g^h|sLnVy8&`VXY z8nA9pudr}&?stoR6+Z6k@cUY=*uW&eV9K1n4GgHN+$0&N*8D17TKrelx#WZk#ZVO% z4xkaPVzn~Ps8&nrMUu(qt!>-j%T&`O_-%Q47F#85Fe}AQ6RKLlt0!vlb?%`H2v_Em z@tgunYtn2551SwVnwtUvBViLSqb%Q_BGn?XJ)Z{mx}vkA#_#8v&a>@E6-KsGDIo)~ z|1$5_fho~PAb=d(!cN2SG4RBp>ao7D)R@O?QYK->OTwGAz*xg1jv6bG4LQ=t}-jAP^tq&_pIwh?X~~kAp$bl|I+?X`Ttt~?{?pfg5eAR3WR{6eq=j@ P*CHqNN@^4T9`OGF$NUo> literal 0 HcmV?d00001 diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md index c999eb32546..0d17ff51372 100644 --- a/doc/user/project/integrations/prometheus.md +++ b/doc/user/project/integrations/prometheus.md @@ -61,7 +61,7 @@ will help you to quickly create a deployment: 1. Navigate to your project's **CI/CD > Pipelines** page, and run a pipeline on any branch. 1. When the pipeline has run successfully, graphs will be available on the **Operations > Metrics** page. -![Monitoring Dashboard](img/prometheus_monitoring_dashboard_v12_8.png) +![Monitoring Dashboard](img/prometheus_monitoring_dashboard_v13_1.png) #### Using the Metrics Dashboard @@ -361,6 +361,13 @@ When **Metrics Dashboard YAML definition is invalid** at least one of the follow 1. `query: can't be blank` [learn more](#metrics-metrics-properties) 1. `query_range: can't be blank` [learn more](#metrics-metrics-properties) 1. `unit: can't be blank` [learn more](#metrics-metrics-properties) +1. `YAML syntax: The parsed YAML is too big` + + This is displayed when the YAML file is larger than 1 MB. + +1. `YAML syntax: Invalid configuration format` + + This is displayed when the YAML file is empty or does not contain valid YAML. Metrics Dashboard YAML definition validation information is also available as a [GraphQL API field](../../../api/graphql/reference/index.md#metricsdashboard) diff --git a/doc/user/project/merge_requests/merge_request_approvals.md b/doc/user/project/merge_requests/merge_request_approvals.md index e61889a400c..dd90449cd86 100644 --- a/doc/user/project/merge_requests/merge_request_approvals.md +++ b/doc/user/project/merge_requests/merge_request_approvals.md @@ -248,6 +248,11 @@ enable this feature: > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5981) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.0. +NOTE: **Note:** +To require authentication when approving a merge request, you must enable +**Password authentication enabled for web interface** under [sign-in restrictions](../../admin_area/settings/sign_in_restrictions.md#password-authentication-enabled). +in the Admin area. + You can force the approver to enter a password in order to authenticate before adding the approval. This enables an Electronic Signature for approvals such as the one defined by [CFR Part 11](https://www.accessdata.fda.gov/scripts/cdrh/cfdocs/cfcfr/CFRSearch.cfm?CFRPart=11&showFR=1&subpartNode=21:1.0.1.1.8.3)). diff --git a/doc/user/project/protected_branches.md b/doc/user/project/protected_branches.md index 1ad80e04417..d0baf57f169 100644 --- a/doc/user/project/protected_branches.md +++ b/doc/user/project/protected_branches.md @@ -2,7 +2,7 @@ type: reference, howto --- -# Protected Branches +# Protected branches [Permissions](../permissions.md) in GitLab are fundamentally defined around the idea of having read or write permission to the repository and branches. To impose diff --git a/doc/user/project/protected_tags.md b/doc/user/project/protected_tags.md index b134d283ba9..e80b8098bec 100644 --- a/doc/user/project/protected_tags.md +++ b/doc/user/project/protected_tags.md @@ -2,13 +2,13 @@ type: reference, howto --- -# Protected Tags +# Protected tags > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10356) in GitLab 9.1. -Protected Tags allow control over who has permission to create tags as well as preventing accidental update or deletion once created. Each rule allows you to match either an individual tag name, or use wildcards to control multiple tags at once. +Protected tags allow control over who has permission to create tags as well as preventing accidental update or deletion once created. Each rule allows you to match either an individual tag name, or use wildcards to control multiple tags at once. -This feature evolved out of [Protected Branches](protected_branches.md) +This feature evolved out of [protected branches](protected_branches.md) ## Overview diff --git a/doc/user/project/repository/reducing_the_repo_size_using_git.md b/doc/user/project/repository/reducing_the_repo_size_using_git.md index f0c0ba3add8..124150c441a 100644 --- a/doc/user/project/repository/reducing_the_repo_size_using_git.md +++ b/doc/user/project/repository/reducing_the_repo_size_using_git.md @@ -5,32 +5,34 @@ info: To determine the technical writer assigned to the Stage/Group associated w type: howto --- -# Reducing the repository size using Git +# Reduce repository size -When large files are added to a Git repository this makes fetching the -repository slower, because everyone will need to download the file. These files -can also take up a large amount of storage space on the server over time. +Git repositories become larger over time. When large files are added to a Git repository: -Rewriting a repository can remove unwanted history to make the repository -smaller. [`git filter-repo`](https://github.com/newren/git-filter-repo) is a -tool for quickly rewriting Git repository history, and is recommended over [`git -filter-branch`](https://git-scm.com/docs/git-filter-branch) and -[BFG](https://rtyley.github.io/bfg-repo-cleaner/). +- Fetching the repository becomes slower because everyone must download the files. +- They take up a large amount of storage space on the server. +- Git repository storage limits [can be reached](#storage-limits). + +Rewriting a repository can remove unwanted history to make the repository smaller. +[`git filter-repo`](https://github.com/newren/git-filter-repo) is a tool for quickly rewriting Git +repository history, and is recommended over both: + +- [`git filter-branch`](https://git-scm.com/docs/git-filter-branch). +- [BFG](https://rtyley.github.io/bfg-repo-cleaner/). DANGER: **Danger:** -Rewriting repository history is a destructive operation. Make sure to backup -your repository before you begin. The best way is to [export the -project](../settings/import_export.html#exporting-a-project-and-its-data). +Rewriting repository history is a destructive operation. Make sure to backup your repository before +you begin. The best way back up a repository is to +[export the project](../settings/import_export.md#exporting-a-project-and-its-data). -## Purging files from your repository history +## Purge files from repository history -To make cloning your project faster, rewrite branches and tags to remove -unwanted files. +To make cloning your project faster, rewrite branches and tags to remove unwanted files. 1. [Install `git filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md) - using a supported package manager, or from source. + using a supported package manager or from source. -1. Clone a fresh copy of the repository using `--bare`. +1. Clone a fresh copy of the repository using `--bare`: ```shell git clone --bare https://example.gitlab.com/my/project.git @@ -44,84 +46,92 @@ unwanted files. git filter-repo --strip-blobs-bigger-than 10M ``` - To purge specific large files by path, the `--path` and `--invert-paths` - options can be combined. + To purge specific large files by path, the `--path` and `--invert-paths` options can be combined: ```shell git filter-repo --path path/to/big/file.m4v --invert-paths ``` - See the [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES) - for more examples, and the complete documentation. + See the + [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES) + for more examples and the complete documentation. -1. Force push your changes to overwrite all branches on GitLab. +1. Running `git filter-repo` removes all remotes. To restore the remote for your project, run: + + ```shell + git remote add origin https://example.gitlab.com//.git + ``` + +1. Force push your changes to overwrite all branches on GitLab: ```shell git push origin --force --all ``` - [Protected Branches](../protected_branches.md) will cause this to fail. To - proceed you will need to remove branch protection, push, and then - reconfigure protected branches. + [Protected branches](../protected_branches.md) will cause this to fail. To proceed, you must + remove branch protection, push, and then re-enable protected branches. -1. To remove large files from tagged releases, force push your changes to all - tags on GitLab. +1. To remove large files from tagged releases, force push your changes to all tags on GitLab: ```shell git push origin --force --tags ``` - [Protected Tags](../protected_tags.md) will cause this to - fail. To proceed you will need to remove tag protection, push, and then - reconfigure protected tags. + [Protected tags](../protected_tags.md) will cause this to fail. To proceed, you must remove tag + protection, push, and then re-enable protected tags. -## Purging files from GitLab storage +## Purge files from GitLab storage -To reduce the size of your repository in GitLab you will need to remove GitLab -internal refs that reference commits contain large files. Before completing -these steps, first [purged files from your repository history](#purging-files-from-your-repository-history). +To reduce the size of your repository in GitLab, you must remove GitLab internal references to +commits that contain large files. Before completing these steps, +[purge files from your repository history](#purge-files-from-repository-history). -As well as branches and tags, which are a type of Git ref, GitLab automatically -creates other refs. These refs prevent dead links to commits, or missing diffs -when viewing merge requests. [Repository cleanup](#repository-cleanup) can be -used to remove these from GitLab. +As well as [branches](branches/index.md) and tags, which are a type of Git ref, GitLab automatically +creates other refs. These refs prevent dead links to commits, or missing diffs when viewing merge +requests. [Repository cleanup](#repository-cleanup) can be used to remove these from GitLab. -The internal refs for merge requests (`refs/merge-requests/*`), -[pipelines](../../../ci/pipelines/index.md#troubleshooting-fatal-reference-is-not-a-tree) -(`refs/pipelines/*`), and environments (`refs/environments/*`) are not -advertised, which means they are not included when fetching, which makes -fetching faster. The hidden refs to prevent commits with discussion from being -deleted (`refs/keep-around/*`) cannot be fetched at all. These refs can, -however, be accessed from the Git bundle inside the project export. +The following internal refs are not advertised: + +- `refs/merge-requests/*` for merge requests. +- `refs/pipelines/*` for + [pipelines](../../../ci/pipelines/index.md#troubleshooting-fatal-reference-is-not-a-tree). +- `refs/environments/*` for environments. + +This means they are not usually included when fetching, which makes fetching faster. In addition, +`refs/keep-around/*` are hidden refs to prevent commits with discussion from being deleted and +cannot be fetched at all. + +However, these refs can be accessed from the Git bundle inside a project export. 1. [Install `git filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md) - using a supported package manager, or from source. + using a supported package manager or from source. -1. Generate a fresh [export from the project](../settings/import_export.md#exporting-a-project-and-its-data) and - download to your computer. +1. Generate a fresh [export from the + project](../settings/import_export.html#exporting-a-project-and-its-data) and download it. -1. Decompress the backup using `tar` +1. Decompress the backup using `tar`: ```shell tar xzf project-backup.tar.gz ``` - This will contain a `project.bundle` file, which was created by [`git bundle`](https://git-scm.com/docs/git-bundle) + This will contain a `project.bundle` file, which was created by + [`git bundle`](https://git-scm.com/docs/git-bundle). -1. Clone a fresh copy of the repository from the bundle. +1. Clone a fresh copy of the repository from the bundle: ```shell git clone --bare --mirror /path/to/project.bundle ``` -1. Using `git filter-repo`, purge any files from the history of your repository. - Because we are trying to remove internal refs, we will rely on the - `commit-map` produced by each run to tell us which internal refs to remove. +1. Using `git filter-repo`, purge any files from the history of your repository. Because we are + trying to remove internal refs, we will rely on the `commit-map` produced by each run to tell us + which internal refs to remove. NOTE:**Note:** - `git filter-repo` creates a new `commit-map` file every run, and overwrite the - `commit-map` from the previous run. You will need this file from **every** - run. Do the next step every time you run `git filter-repo`. + `git filter-repo` creates a new `commit-map` file every run, and overwrite the `commit-map` from + the previous run. You will need this file from **every** run. Do the next step every time you run + `git filter-repo`. To purge all large files, the `--strip-blobs-bigger-than` option can be used: @@ -129,110 +139,106 @@ however, be accessed from the Git bundle inside the project export. git filter-repo --strip-blobs-bigger-than 10M ``` - To purge specific large files by path, the `--path` and `--invert-paths` - options can be combined. + To purge specific large files by path, the `--path` and `--invert-paths` options can be combined. ```shell git filter-repo --path path/to/big/file.m4v --invert-paths ``` - See the [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES) - for more examples, and the complete documentation. + See the + [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES) + for more examples and the complete documentation. -1. After running `git filter-repo`, the header and unchanged commits need to be - removed from the `commit-map` before uploading to GitLab. - - ```shell - tail -n +2 filter-repo/commit-map | grep -E -v '^(\w+) \1$' >> commit-map.txt - ``` - - This command can be run after each run of `git filter-repo` to append the - output of the run to `commit-map.txt` - -1. Navigate to **Project > Settings > Repository > Repository Cleanup**. - - Upload the `commit-map.txt` file and press **Start cleanup**. This will - remove any internal Git references to the old commits, and run `git gc` - against the repository. You will receive an email once it has completed. +1. Run a [repository cleanup](#repository-cleanup). ## Repository cleanup > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19376) in GitLab 11.6. -Repository cleanup allows you to upload a text file of objects and GitLab will remove -internal Git references to these objects. +Repository cleanup allows you to upload a text file of objects and GitLab will remove internal Git +references to these objects. You can use +[`git filter-repo`](https://github.com/newren/git-filter-repo) to produce a list of objects (in a +`commit-map` file) that can be used with repository cleanup. To clean up a repository: 1. Go to the project for the repository. 1. Navigate to **{settings}** **Settings > Repository**. -1. Upload a list of objects. +1. Upload a list of objects. For example, a `commit-map` file. 1. Click **Start cleanup**. -This will remove any internal Git references to old commits, and run `git gc` -against the repository. You will receive an email once it has completed. +This will: -These tools produce suitable output for purging history on the server: +- Remove any internal Git references to old commits. +- Run `git gc` against the repository. -- [`git filter-repo`](https://github.com/newren/git-filter-repo): use the - `commit-map` file. +You will receive an email once it has completed. -- [BFG](https://rtyley.github.io/bfg-repo-cleaner/): use the - `object-id-map.old-new.txt` file. +When using repository cleanup, note: -NOTE: **Note:** -Housekeeping prunes loose objects older than 2 weeks. This means objects added -in the last 2 weeks will not be removed immediately. If you have access to the -Gitaly server, you may run `git gc --prune=now` to prune all loose object -immediately. +- Housekeeping prunes loose objects older than 2 weeks. This means objects added in the last 2 weeks + will not be removed immediately. If you have access to the + [Gitaly](../../../administration/gitaly/index.md) server, you may run `git gc --prune=now` to + prune all loose objects immediately. +- This process will remove some copies of the rewritten commits from GitLab's cache and database, + but there are still numerous gaps in coverage and some of the copies may persist indefinitely. + [Clearing the instance cache](../../../administration/raketasks/maintenance.md#clear-redis-cache) + may help to remove some of them, but it should not be depended on for security purposes! -NOTE: **Note:** -This process will remove some copies of the rewritten commits from GitLab's -cache and database, but there are still numerous gaps in coverage - at present, -some of the copies may persist indefinitely. [Clearing the instance -cache](../../../administration/raketasks/maintenance.md#clear-redis-cache) may -help to remove some of them, but it should not be depended on for security -purposes! +## Storage limits -## Exceeding storage limit +Repository size limits: -A GitLab Enterprise Edition administrator can set a [repository size -limit](../../admin_area/settings/account_and_limit_settings.md) which will -prevent you from exceeding it. +- Can [be set by an administrator](../../admin_area/settings/account_and_limit_settings.md#repository-size-limit-starter-only) + on self-managed instances. **(STARTER ONLY)** +- Are [set for GitLab.com](../../gitlab_com/index.md#repository-size-limit). -When a project has reached its size limit, you will not be able to push to it, -create a new merge request, or merge existing ones. You will still be able to -create new issues, and clone the project though. Uploading LFS objects will -also be denied. +When a project has reached its size limit, you cannot: -If you exceed the repository size limit, your first thought might be to remove -some data, make a new commit and push back to the repository. Perhaps you can -move some blobs to LFS, or remove some old dependency updates from history. -Unfortunately, it's not so easy and that workflow won't work. Deleting files in -a commit doesn't actually reduce the size of the repo since the earlier commits -and blobs are still around. What you need to do is rewrite history with Git's -[`filter-branch` option](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#The-Nuclear-Option:-filter-branch), -or an open source community-maintained tool like the +- Push to the project. +- Create a new merge request. +- Merge existing merge requests. +- Upload LFS objects. + +You can still: + +- Create new issues. +- Clone the project. + +If you exceed the repository size limit, you might try to: + +1. Remove some data. +1. Make a new commit. +1. Push back to the repository. + +Perhaps you might also: + +- Move some blobs to LFS. +- Remove some old dependency updates from history. + +Unfortunately, this workflow won't work. Deleting files in a commit doesn't actually reduce the size +of the repository because the earlier commits and blobs still exist. + +What you need to do is rewrite history. We recommend the open-source community-maintained tool [`git filter-repo`](https://github.com/newren/git-filter-repo). -Note that even with that method, until `git gc` runs on the GitLab side, the -"removed" commits and blobs will still be around. You also need to be able to -push the rewritten history to GitLab, which may be impossible if you've already +NOTE: **Note:** +Until `git gc` runs on the GitLab side, the "removed" commits and blobs will still exist. You also +must be able to push the rewritten history to GitLab, which may be impossible if you've already exceeded the maximum size limit. -In order to lift these restrictions, the administrator of the GitLab instance -needs to increase the limit on the particular project that exceeded it, so it's -always better to spot that you're approaching the limit and act proactively to -stay underneath it. If you hit the limit, and your admin can't - or won't - -temporarily increase it for you, your only option is to prune all the unneeded -stuff locally, and then create a new project on GitLab and start using that -instead. +In order to lift these restrictions, the administrator of the self-managed GitLab instance must +increase the limit on the particular project that exceeded it. Therefore, it's always better to +proactively stay underneath the limit. If you hit the limit, and can't have it temporarily +increased, your only option is to: + +1. Prune all the unneeded stuff locally. +1. Create a new project on GitLab and start using that instead. CAUTION: **Caution:** -This process is not suitable for removing sensitive data like password or keys -from your repository. Information about commits, including file content, is -cached in the database, and will remain visible even after they have been -removed from the repository. +This process is not suitable for removing sensitive data like password or keys from your repository. +Information about commits, including file content, is cached in the database, and will remain +visible even after they have been removed from the repository.