



  

<!DOCTYPE html>
<html
  lang="en"
  
  data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
  data-a11y-animated-images="system" data-a11y-link-underlines="true"
  
  >




  <head>
    <meta charset="utf-8">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
  <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
  <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
  <link rel="preconnect" href="https://github.githubassets.com" crossorigin>
  <link rel="preconnect" href="https://avatars.githubusercontent.com">

<script type="importmap">{"imports":{"react":"https://github.githubassets.com/assets/react-e27d1b3e03961e68.js","react-dom":"https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js","react-dom/client":"https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js","react-is":"https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js","react-reconciler":"https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js","react/compiler-runtime":"https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js","react/jsx-dev-runtime":"https://github.githubassets.com/assets/react-jsx-dev-runtime-ea55d68667d559e5.js","react/jsx-runtime":"https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js","scheduler":"https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js"}}</script>
<meta name="react-profiling" content="0" data-turbo-transient="true" />
<meta name="react-import-map" content="react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@777f63f87cd0" data-turbo-track="reload" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-e27d1b3e03961e68.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js" />

  


  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-0f910d8806d5761b.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-a7abd4d4c49ac593.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-5fc4c4a9cb41e596.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-ed0cee9214dedabd.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-78a2491d538dab5a.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-c26b63d7c532d0a2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-a6f60cea68c08405.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-f66faf28b2ea18b6.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-6701f6218c53cf5b.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-7037fa46ae124d97.css" />

  <style type="text/css">
    :root {
      --tab-size-preference: 4;
    }

    pre, code {
      tab-size: var(--tab-size-preference);
    }
  </style>

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-97df7784617ce1ea.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-9be9fe6313f476af.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-62747e27e61258dc.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-7a418ea859d1654d.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-72bd7d974b5ac1cc.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-4c5c0895f723f870.css" />

  

  <script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_caches_react_shell","actions_enable_background_steps","actions_new_hosted_runner_image_select_sizes_and_versions","actions_runners_react_shell","activity_diff_file_tree","activity_repos_file_tree","activity_repos_overview_header","activity_repos_overview_sidebar","agent_author_search_expansion","agent_author_search_expansion_ui_pulls","alternate_user_config_repo","async_conversion_coverage_enabled","billing_billable_licenses_cost_center_bucket_fix","billing_budget_expiration","billing_cost_center_list_assigned_resources","billing_discount_threshold_notification","code_quality_enablement_banner_targeting","code_quality_remove_preview","code_view_raf_sticky_lines","codespaces_prebuild_region_target_update","coding_agent_third_party_model_ui","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_automation_repo_mcp_servers","copilot_automations_pagination","copilot_base_model_policy_row","copilot_chat_auto_mode_v2","copilot_chat_clear_model_selection_for_default_change","copilot_chat_early_task_provisioning","copilot_chat_persist_session_drafts","copilot_chat_vision_dotcom_chat_ga_gate","copilot_css_textarea_autosize","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_removal_on_marketplace","copilot_fix_failed_workflows_all_skus","copilot_hide_hovercard","copilot_immersive_task_hyperlinking","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_merge_fix_ci","copilot_mission_control_agent_merge_resolve_conflicts","copilot_mission_control_awps_batching","copilot_mission_control_early_stop","copilot_mission_control_managed_sandbox_environments","copilot_mission_control_needs_attention","copilot_mission_control_reasoning_effort","copilot_mission_control_sandbox_remote_bypass","copilot_mission_control_task_alive_updates","copilot_mission_control_task_sharing","copilot_org_policy_page_focus_mode","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_swe_agent_authorization_status_ui","copilot_swe_agent_automation_resource_scoped_writes","copilot_swe_agent_discussion_comment_trigger","copilot_swe_agent_discussion_opened_trigger","copilot_swe_agent_discussion_updated_trigger","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_issue_assigned_trigger","copilot_swe_agent_issue_comment_trigger","copilot_swe_agent_issue_labeled_trigger","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_pull_request_assigned_trigger","copilot_swe_agent_pull_request_comment_trigger","copilot_swe_agent_pull_request_labeled_trigger","copilot_swe_agent_pull_request_merged_trigger","copilot_swe_agent_pull_request_opened_trigger","copilot_swe_agent_pull_request_ready_for_review_trigger","copilot_swe_agent_pull_request_review_requested_trigger","copilot_swe_agent_pull_request_review_submitted_trigger","copilot_swe_agent_pull_request_synchronize_trigger","copilot_swe_agent_sub_issue_added_trigger","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_task_scoped_alive_channel","copilot_token_based_billing","copilot_unconfigured_is_inherited","copilot_user_can_upgrade_plan_field","copilot_workbench_sunset_redirect","dashboard_agents_module_auth_token_check","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","fgpat_permissions_selector_redesign","glc_code_quality_repo_settings_workflow_config","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","in_product_messaging_datadog_monitoring","ipm_ubb_individual_budget_banner","issue_fields_multi_select","issue_inline_avatars","issue_pinned_views","issue_pinned_views_team_vs_personal","issue_relative_time_micro","issues_dashboard_sso_structured_errors","issues_expanded_file_types","issues_hide_closed_sub_issues","issues_index_data_router","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","labels_archiving","labels_archiving_info","landing_pages_ninetailed","lifecycle_label_name_updates","marketing_cookie_consent_banner","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_queue_restricted_pushers_warning","merge_status_header_feedback","milestone_closed_issues_prioritization","milestone_show_data_router","octocaptcha_origin_optimization","primer_react_css_anchor_positioning","primer_react_merged_forwarded_refs","prs_copilot_app_open_action","prs_css_anchor_positioning","pull_request_copilot_attribution_header","pull_request_overview_merge_control","pull_request_overview_panel_edit_description","pull_request_persister","pull_request_stacks_navigation_shortcuts","pull_request_virtualization_image_estimate","pull_request_virtualization_loader_batching","pull_request_virtualization_scroll_compensation","pull_request_virtualization_scroll_intent","quick_search_lazy_suggestions","react_blob_isolate_code_lines","react_blob_ssr_content_visibility","react_data_router_tanstack_allowed","react_logged_out_repository_header","react_query_props_with_key","react_sandbox_future_tanstack","repo_app_turbo","repo_issues_sidebar_layout","repo_pulls_dashboard_declutter","repo_pulls_dashboard_ga","repo_pulls_dashboard_persistence","repo_pulls_dashboard_sidebar_links","repos_contributors_limited_default_range","review_involves_filter","rule_ignored_file_paths","rulesets_actor_list_editor","sample_network_conn_type","security_center_artifact_filters_popover","see_who_reacted","semantic_similarity_duplicate_issue_detection","session_logs_ungroup_reasoning_text","set_sha256_on_repo_creation_form","site_banner_desktop_copilot_app","site_ghca_pixel_mona","site_github_app_ga_page","site_github_app_ga_page_highlight","site_github_app_mobile_native_share","site_global_banner_dev_days_attendee","site_global_nav_spark_models_removed","speculation_rules_ui_service","suggest_custom_property_values_copilot","suppress_automated_browser_vitals","swp_forms_disable_octocaptcha","thread_resolution_reason","update_issue_suggestions","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workstream_plugin_bootstrap"],"githubDomain":"https://github.com","copilotApiOverrideUrl":"https://api.githubcopilot.com","cmcApiUrl":"https://api.github.com/cmc_internal/api"}</script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/high-contrast-cookie-b752d992928a526c.js"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-runtime-8b4dcdc2cb6562ff.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-foundation-2f08c823163591a8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-runtime-633ad94fa06c334b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fetch-utilities-0fb4c544a797ec0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ser-7c872b58ac9f1b39.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tp-7e9817cf5c068979.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/environment-8bdc8c2592df853b.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-runtime.bef03fb24bb03be8.module.css" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/catalyst-52ed81112a548e10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/selector-observer-e8810f64c443fb9b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/relative-time-element-0417f617ad744a0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/by-9da36843ba9d191d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ja9-9a1160b939f2cd52.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3h-55903cf2303047ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hk-f1498fec45311acd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jz5-7aa1ff0a0e750f41.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hj-1d800d09e9a8720a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j0-9697c1c8f5cbf523.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/github-elements-3f257b2433f975f0.js" defer="defer"></script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/element-registry-95b267513b87193c.js" defer="defer"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/runtime-helpers-5e0b3ae3c4036207.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/aria-live-524a06aa946df6fc.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hotkey-b1ee53c2200b172a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-core-7bf7b9d689fe3d10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a9-ca3bc10b816bcc1f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ur-21ec1e439ee2d87c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4t-4c39f7195fc42cc8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pb-53cfff089eaac51b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6n-afcf86ccabc4cad2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zj-4d9cf83cf08e1643.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wo-6991af5b3829ffe8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/nfv-a6c14301d3ea6d67.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b5-a2fde30ce0c692b9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sw-9d0489dbf9a9c942.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ttf-7d5abe1b447ced2c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sj-c7a44023ee90d468.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0pd-c46d8dfae89c2b64.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/behaviors-2a35428577a46a82.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.255cab819a92f7e1.module.css" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-menu-baecde86e879facb.js" defer="defer"></script>
  
  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/primer-react-8503588299651923.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ncx-66e64888bc4615bb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qmp-c7cfba40cf5a93b0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j6-148a74299e5a01ab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t7l-a9404625ec30bbc7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4u-8f9f1d6be01d6a22.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/s0-68d09e5e8a80cb94.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y5-0cb3f75cec297941.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/n4u-cd9039ad946274ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j8s-00bd469c4017a543.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/la-27679061f16e1495.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/iu-2d03f5e6d4fdd54d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gru-2b0fac8887ff8c57.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a0-234e967e7c6d22ce.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gz3-5bdfbfceac967bb6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/15m-64f3034430471048.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/1e-c15441bdb94d54ae.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gzu-6ad9a0527a5d7afd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bi-3a42b8714e06c4d0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tu1-37e16844272ddefa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b1-ac66ededed061993.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gmn-1e5497c041b66231.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0l5-d1b2a63015b5eb6d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/c2-e85522be441acf73.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/f9-baf0a4193779952e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sp-87dce99c82a27004.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zkm-116b01b8485bbe3f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/og-518d12c9e011601d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b9-947db365ea875cfa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/14-8c7b4ad3c845664c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dsj-2e7d883cb843e9e6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ec-38012819307fd539.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/du-6607da3b8b579202.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/20-f43eb09c2be69457.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ql0-107312645ac2b72d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-fa7cdc0f7656d876.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p0l-fe491d943adf7508.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/v1e-d099d9fd21ad25e5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fn-7b298a45c55fb6fb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7cw-6e493a20eaaa04b5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ok-290e4b9465ba9c5b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6d-ca6d584a0fd6368c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y8-e2f18f5a24733f3b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xc-3fd4a2e7dcbad8e2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/vjg-2874f95f389c4d3f.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-view-b187f9df797cfbc1.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/xc.de2b1dde0494f261.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-view.30fafa560a1eee5e.module.css" />


  <title>revdiff/README.md at master · umputun/revdiff · GitHub</title>



  <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient>
  <meta name="route-controller" content="blob" data-turbo-transient>
  <meta name="route-action" content="show" data-turbo-transient>
  <meta name="fetch-nonce" content="v2:591424df-5346-f336-5a74-4865b278c1c5">

    
  <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">


  <meta name="request-id" content="9F40:3E78D5:38D236:35A063:6AC7488E" data-pjax-transient="true"/><meta name="html-safe-nonce" content="64b5ab8e4f1410bba07faf551c486598f262ef926e0c8abec12c4d58ff4c4941" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5RjQwOjNFNzhENTozOEQyMzY6MzVBMDYzOjZBQzc0ODhFIiwidmlzaXRvcl9pZCI6IjczODMxMTQ5ODYyNDEzNDU2NzgiLCJyZWdpb25fZWRnZSI6ImZyYSIsInJlZ2lvbl9yZW5kZXIiOiJmcmEifQ==" data-pjax-transient="true"/><meta name="visitor-hmac" content="761bdd1ce37807560a0e7a186072896fc47b06b8e33b4a64cfc8996387931373" data-pjax-transient="true"/>


    <meta name="hovercard-subject-tag" content="repository:1198207465" data-turbo-transient>


  <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" />
  

  <meta name="selected-link" value="repo_source" data-turbo-transient>
  <link rel="assets" href="https://github.githubassets.com/">

    <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">

<meta name="octolytics-url" content="https://collector.github.com/github/collect" />





  <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" />

  




    <meta name="user-login" content="">

  

    <meta name="viewport" content="width=device-width">

    

      <meta name="description" content="TUI for reviewing diffs, files, and documents with inline annotations - revdiff/README.md at master · umputun/revdiff">

      <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">

    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
    <meta property="fb:app_id" content="1401488693436528">
    <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/umputun/revdiff/blob/master/README.md" />

      <meta name="twitter:image" content="https://opengraph.githubassets.com/cc4f39b8100093b5aacb52ed232a7e82f6b6420c019d1247a364a9a1666f1b84/umputun/revdiff" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="revdiff/README.md at master · umputun/revdiff" /><meta name="twitter:description" content="TUI for reviewing diffs, files, and documents with inline annotations - umputun/revdiff" />
  <meta property="og:image" content="https://opengraph.githubassets.com/cc4f39b8100093b5aacb52ed232a7e82f6b6420c019d1247a364a9a1666f1b84/umputun/revdiff" /><meta property="og:image:alt" content="TUI for reviewing diffs, files, and documents with inline annotations - umputun/revdiff" /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="revdiff/README.md at master · umputun/revdiff" /><meta property="og:url" content="https://github.com/umputun/revdiff/blob/master/README.md" /><meta property="og:description" content="TUI for reviewing diffs, files, and documents with inline annotations - umputun/revdiff" />
  




      <meta name="hostname" content="github.com">



        <meta name="expected-hostname" content="github.com">


  <meta http-equiv="x-pjax-version" content="8a04ed058e34f1ad63cd2ec184ddc8db8ab22004d2ce8345ee86788432baa4cf" data-turbo-track="reload">
  <meta http-equiv="x-pjax-csp-version" content="c4a65e47b0c850e1157ae8e66298070851d7e3b558038de5a3b4ff7a93e630ed" data-turbo-track="reload">
  <meta http-equiv="x-pjax-css-version" content="1ff3f1d4e1abd61f6f135b47d3b815e2f7169f8dd418f0118c6b1cf4de6cbc86" data-turbo-track="reload">
  <meta http-equiv="x-pjax-js-version" content="31760b6cf01794eaa3898a84a5be66fa89579904959fd0698672e3cbcd9741ca" data-turbo-track="reload">

  <meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">

      <meta name="turbo-cache-control" content="no-cache" data-turbo-transient>

    <meta data-hydrostats="publish">

  <meta name="go-import" content="github.com/umputun/revdiff git https://github.com/umputun/revdiff.git">

  <meta name="octolytics-dimension-user_id" content="535880" /><meta name="octolytics-dimension-user_login" content="umputun" /><meta name="octolytics-dimension-repository_id" content="1198207465" /><meta name="octolytics-dimension-repository_nwo" content="umputun/revdiff" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="1198207465" /><meta name="octolytics-dimension-repository_network_root_nwo" content="umputun/revdiff" />
  



    

    <meta name="turbo-body-classes" content="logged-out env-production page-responsive">
  <meta name="disable-turbo" content="false">


  <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">


  <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">

  <meta name="release" content="abcc1c729a3dae04e49a5be4a885c179f1620884" data-turbo-track="reload">
  <meta name="ui-target" content="full">

  <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000">
  <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
  <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon">

<meta name="theme-color" content="#1e2327">
<meta name="color-scheme" content="light dark" />


  <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">

  </head>

  <body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
    <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
      <div id="__primerPortalRoot__" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
      

    <div class="position-relative header-wrapper js-header-wrapper ">
      <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a>

      <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full">
    <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span>
</span>      
      <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qc-1bbbe8787ea1cd4b.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-a3b4cbcefa4e617e.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.b8afe3d106c9bb64.module.css" />

<react-partial
  partial-name="keyboard-shortcuts-dialog"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>





      

          <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-install-banner-partial-173a78d38983be1c.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-install-banner-partial.882c17396978a47d.module.css" />

<react-partial
  partial-name="app-install-banner-partial"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>


          

                <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2l-e468179ba7123a2e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/rwd-069fc3d9814ff9fe.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fz-e662bc3745e171e7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jag-3559ee48016881a2.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3d-7f22b36f29a9dd94.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tua-4998592d21eb16f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/8i-ea1b3f2e11ed8cd3.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/marketing-header-b6853fcac2424bda.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-brand-css.05b219cdb8e80c43.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/8i.5d9e6dcb0dade694.module.css" />

<react-partial
  partial-name="marketing-header"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"color_mode":"dark","logged_in":false,"marketing_page":false,"home_path":"/","login_path":"/login?return_to=https%3A%2F%2Fgithub.com%2Fumputun%2Frevdiff%2Fblob%2Fmaster%2FREADME.md","signup_path":"/signup?ref_cta=Sign+up\u0026ref_loc=header+logged+out\u0026ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow\u0026source=header-repo\u0026source_repo=umputun%2Frevdiff","signup_enabled":true,"is_signup_controller":false,"show_search_and_nav":true,"hide_search":false,"private_mode_enabled":false,"should_use_dotcom_links":true,"auth_hydro_click":"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/umputun/revdiff/blob/master/README.md\",\"user_id\":null}}","auth_hydro_click_hmac":"9d33cee8b418b81b236d3f4b612f9f94036a55dec9ed1a387cae4af8960adeb6","overlay":false,"fixed":false}}</script>
  <div data-target="react-partial.reactRoot"><div data-color-mode="dark" data-light-theme="light" data-dark-theme="dark"><header class="MarketingHeader-module__root__Tk7n3 HeaderMktg header-logged-out" role="banner" data-marketing-header="true" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-is-top="true"><h2 class="MarketingHeader-module__visuallyHidden__sqKsl">Navigation Menu</h2><button type="button" class="MarketingHeader-module__backdrop__sw4RU" aria-label="Close navigation menu"></button><div class="MarketingHeader-module__bar__mBSyE"><div class="MarketingHeader-module__topRow__yeury"><div class="MarketingHeader-module__toggleSlot__hDxbh"><button type="button" class="HeaderMenuToggle-module__toggle__i8EiC" aria-label="Toggle navigation" aria-expanded="false"><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span></button></div><a href="/" aria-label="Homepage" class="HeaderLogo-module__logo__UFyHI" data-analytics-event="{&quot;action&quot;:&quot;homepage&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;logo&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;homepage_link_logo_header&quot;}"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github" viewBox="0 0 24 24" width="32" height="32" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path></svg></a><div class="AuthCTAs-module__mobileActions__NNzeV"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fumputun%2Frevdiff%2Fblob%2Fmaster%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/umputun/revdiff/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="9d33cee8b418b81b236d3f4b612f9f94036a55dec9ed1a387cae4af8960adeb6"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_3dd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_3dd_">Appearance settings</div></div></div><div class="MarketingHeader-module__menu__GIy3y"><div class="MarketingHeader-module__menuWrapper__owstH"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_nd_">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5knd_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>GitHub Copilot</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Write better code with AI</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/ai/github-app" data-analytics-event="{&quot;action&quot;:&quot;github_copilot_app&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_app_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"></path></svg>GitHub Copilot app</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Direct agents from issue to merge</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.52 1.12a3.578 3.578 0 0 1 6.078 2.98 3.578 3.578 0 0 1 2.982 6.08l-3.292 3.293a.252.252 0 0 0 0 .354l.843.843a.749.749 0 1 1-1.06 1.06l-.844-.843a1.75 1.75 0 0 1 0-2.474L13.52 9.12a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0L7.731 9.03A.75.75 0 0 1 6.67 7.97l2.85-2.85a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0l-4.799 4.8A.75.75 0 0 1 .72 5.92Z"></path><path d="M7.52 3.12a.749.749 0 1 1 1.06 1.06L5.731 7.03A2.079 2.079 0 0 0 8.67 9.97l2.85-2.85a.749.749 0 1 1 1.06 1.06l-2.849 2.85A3.578 3.578 0 0 1 4.67 5.97Z"></path></svg>MCP Registry</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Integrate external tools</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9knd_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path></svg>Actions</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Automate any workflow</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg>Codespaces</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Instant dev environments</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Issues</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Plan and track work</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg>Code Review</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Manage code changes</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-quality" data-analytics-event="{&quot;action&quot;:&quot;code_quality&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_quality_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codescan-checkmark NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.28 6.28a.75.75 0 1 0-1.06-1.06L6.25 8.19l-.97-.97a.75.75 0 0 0-1.06 1.06l1.5 1.5a.75.75 0 0 0 1.06 0l3.5-3.5Z"></path><path d="M7.5 15a7.5 7.5 0 1 1 5.807-2.754l2.473 2.474a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2.474-2.473A7.472 7.472 0 0 1 7.5 15Zm0-13.5a6 6 0 1 0 4.094 10.386.748.748 0 0 1 .293-.292 6.002 6.002 0 0 0 1.117-6.486A6.002 6.002 0 0 0 7.5 1.5Z"></path></svg>Code Quality</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enforce quality at merge</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dknd_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>Code security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Secure your code as you build</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>Secret protection</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_hknd_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Why GitHub</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Blog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Changelog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all features</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_17d_">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_17d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5l7d_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Enterprises</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Small and medium teams</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Startups</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9l7d_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">App Modernization</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevSecOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">CI/CD</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all use cases</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dl7d_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dl7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Healthcare</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Financial services</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Manufacturing</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Government</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all industries</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all solutions</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_1nd_">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_1nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5lnd_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">AI</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Software Development</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all topics</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9lnd_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer stories</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Events &amp; webinars</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Ebooks &amp; reports</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Business insights</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Skills</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dlnd_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dlnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer support</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Community forum</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trust center</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources" data-analytics-event="{&quot;action&quot;:&quot;view_all_resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_resources_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all resources</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_27d_">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_27d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5m7d_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/open-source/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1Zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105ZM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75Z"></path></svg>GitHub Sponsors</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Fund open source developers</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9m7d_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security Lab</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Maintainer Community</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://stars.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_stars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_stars_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Stars</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Archive Program</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dm7d_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dm7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Topics</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trending</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_2nd_">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_2nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5mnd_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.122.392a1.75 1.75 0 0 1 1.756 0l5.003 2.902c.83.481.83 1.68 0 2.162L8.878 8.358a1.75 1.75 0 0 1-1.756 0L2.119 5.456a1.251 1.251 0 0 1 0-2.162ZM8.125 1.69a.248.248 0 0 0-.25 0l-4.63 2.685 4.63 2.685a.248.248 0 0 0 .25 0l4.63-2.685ZM1.601 7.789a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0L1.874 8.814A.75.75 0 0 1 1.6 7.789Zm0 3.5a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0l-5.248-3.044a.75.75 0 0 1-.273-1.025Z"></path></svg>Enterprise platform</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9mnd_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>Copilot for Business</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg>Premium Support</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></span></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="MarketingNavigation-module__navLink__hUomM">Pricing</a></li></ul></nav><div class="MarketingHeader-module__ctaContainer__tBmPz"><div class="HeaderSearch-module__searchSlot__oVOUS"><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderSearch-module__trigger__zsF9q" type="button" aria-haspopup="dialog" aria-expanded="false" aria-label="Search or jump to, type / to search" data-analytics-event="{&quot;action&quot;:&quot;searchbar&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;context&quot;:&quot;global&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"><span class="HeaderSearch-module__content__kMpxU"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search HeaderSearch-module__icon__wcrHX" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg><span class="HeaderSearch-module__label__d1iWG">Search</span><kbd class="HeaderSearch-module__kbd__HNG0o" aria-hidden="true">/</kbd></span></span></span></button><div class="d-none"></div></div><div class="AuthCTAs-module__signInWrap__q2P60"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq AuthCTAs-module__desktopActionGap__UZuXT AuthCTAs-module__hiddenBelowLg__BfKBw" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fumputun%2Frevdiff%2Fblob%2Fmaster%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/umputun/revdiff/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="9d33cee8b418b81b236d3f4b612f9f94036a55dec9ed1a387cae4af8960adeb6"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a></div><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--secondary___gHnw_ Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=umputun%2Frevdiff" data-analytics-event="{&quot;action&quot;:&quot;sign_up&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_up_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/umputun/revdiff/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="9d33cee8b418b81b236d3f4b612f9f94036a55dec9ed1a387cae4af8960adeb6"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-secondary___eJ0_a">Sign up</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_fbd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_fbd_">Appearance settings</div></div></div></div></div><div class="MarketingHeader-module__bottomBorder__uZT38" aria-hidden="true"></div></header></div></div>
</react-partial>



      <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
  
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>

    <button id="icon-button-d7752afc-3330-4ebd-9578-ca72b009f39d" aria-labelledby="tooltip-514aace1-7db1-4319-b69b-bc3c407dcaea" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-514aace1-7db1-4319-b69b-bc3c407dcaea" for="icon-button-d7752afc-3330-4ebd-9578-ca72b009f39d" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>


  
</div>
    </div>

  <div id="start-of-content" class="show-on-focus"></div>








    <div id="js-flash-container" class="flash-container" data-turbo-replace>






  <template class="js-flash-template">
    
<div class="flash flash-full   {{ className }}">
  <div >
    <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    <div aria-atomic="true" role="alert" class="js-flash-alert">
      
      <div>{{ message }}</div>

    </div>
  </div>
</div>
  </template>
</div>


    






  <div
    class="application-main "
    data-commit-hovercards-enabled
    data-discussion-hovercards-enabled
    data-issue-and-pr-hovercards-enabled
    data-project-hovercards-enabled
  >
        <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
    <main id="js-repo-pjax-container" >
      
      








  

    <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ym-1a7ce813a378e1f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mn-bb458474353a279e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t5-26d19272bbf73ca3.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2d5-9abb2f6ba5c935d0.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/24-b11e1c4108322883.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mrn-12afac2ecd2be980.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dgq-bbf7670f9cdba2e0.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7w-740b4e942974ccba.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/we-c9f93392098ad6c9.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/775-f58305f9bcded6f1.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bn-fcef0645a47703fc.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xgw-677b1ad5da5c3c6d.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ge-ca1c0ba8656f9680.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/9f-3f61950dd9225c4a.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/global-nav-bar-76f3d16d4cab2423.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-nav-bar.679bccc49e90d4e2.module.css" />

<react-partial
  partial-name="global-nav-bar"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"contextRegion":{"crumbs":[{"crumb_type":"user","label":"umputun","is_root":false,"href":"/umputun"},{"crumb_type":"repository","label":"revdiff","is_root":false,"href":"/umputun/revdiff"}],"localNavigation":[{"id":"code","icon":"code","label":"Code","href":"/umputun/revdiff","selectedLinks":["repo_source","repo_downloads","repo_commits","repo_releases","repo_tags","repo_branches","repo_packages","repo_deployments","repo_attestations"],"popoverTarget":false,"commandId":"repositories:go-to-code","reactNav":{"appTarget":"code-view","anchor":"code-view-repo-link"},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"issues","icon":"issue-opened","label":"Issues","href":"/umputun/revdiff/issues","selectedLinks":["repo_issues","repo_labels","repo_milestones"],"count":9,"popoverTarget":false,"commandId":"repositories:go-to-issues","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"pull-requests","icon":"git-pull-request","label":"Pull requests","href":"/umputun/revdiff/pulls","selectedLinks":["repo_pulls","checks"],"count":11,"popoverTarget":false,"commandId":"repositories:go-to-pull-requests","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"discussions","icon":"comment-discussion","label":"Discussions","href":"/umputun/revdiff/discussions","selectedLinks":["repo_discussions"],"popoverTarget":false,"commandId":"repositories:go-to-discussions","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"actions","icon":"play","label":"Actions","href":"/umputun/revdiff/actions","selectedLinks":["repo_actions"],"popoverTarget":false,"commandId":"repositories:go-to-actions","reactNav":{"appTarget":"actions-workflows","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"projects","icon":"table","label":"Projects","href":"/umputun/revdiff/projects","selectedLinks":["repo_projects","new_repo_project","repo_project"],"popoverTarget":false,"commandId":"repositories:go-to-projects","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"security-and-quality","icon":"shield","label":"Security and quality","href":"/umputun/revdiff/security","selectedLinks":["security","overview","alerts","policy","token_scanning","code_scanning"],"count":0,"popoverTarget":false,"commandId":"repositories:go-to-security","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"insights","icon":"graph","label":"Insights","href":"/umputun/revdiff/pulse","selectedLinks":["repo_graphs","repo_contributors","dependency_graph","dependabot_updates","pulse","people","community"],"popoverTarget":false,"commandId":"repositories:go-to-insights","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}}],"localNavigationUpdateChannel":null,"selectedLink":"repo_source"},"owner":null,"headerLogo":{"href":"/","aria-label":"Homepage "},"notifications":{"indicatorMode":"disabled","websocketChannel":null,"fetchIndicatorSrc":"/notifications/indicator","fetchIndicatorEnabled":false},"issues":{"href":"/issues"},"pulls":{"href":"/pulls"},"contributedRepos":{"href":"/repos"},"copilot":{"show":false,"showAgentsButton":false,"showRelaunchAnnouncement":false,"copilotChatUrl":null,"copilotApiUrl":"https://api.githubcopilot.com"},"search":{"show":true,"showCommandPalette":false,"isSearchPage":false,"isJumpToSearch":false,"searchContext":{"scope":"repo:umputun/revdiff","current_repo_name":"revdiff","current_repo_nwo":"umputun/revdiff","user_id":"umputun"}},"commandPalette":null,"enterpriseBar":{"show":false},"globalTransactionalMessage":[],"payloadsUrl":"/_global-navigation/payloads.json?can_toggle_site_admin_and_employee_status=0\u0026is_admin_mode_on=0\u0026is_ui_opted_out=0\u0026show_ui_opt_out=0\u0026v=6","contextRegionUrl":"/_global-navigation/context-region.json"}}</script>
  <div data-target="react-partial.reactRoot"><header aria-label="Global navigation menu" data-component="Stack" class="GlobalNav styles-module__appHeader__YzYWk prc-Stack-Stack-UQ9k6" data-gap="none" data-direction="vertical" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="none"><div data-component="Stack" class="prc-Stack-Stack-UQ9k6" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="center" data-padding="none"><div data-testid="top-nav-center" data-component="Stack" class="styles-module__center__R3QRv styles-module__withLocalNavigation__rjTJ_ GlobalNavBar-module__loggedOut__Jv1rk prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="normal"><nav class="styles-module__contextRegion__VbSp2 prc-Breadcrumbs-BreadcrumbsBase-3Gb-B" aria-label="Breadcrumbs" data-overflow="menu" data-variant="normal" data-component="Breadcrumbs"><ol class="prc-Breadcrumbs-BreadcrumbsList-BKjpe"><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/umputun" data-discover="true"><span class="">umputun</span></a></li><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/umputun/revdiff" data-discover="true"><span class="styles-module__contextCrumbLast__tI2e3">revdiff</span></a></li></ol></nav></div><div data-testid="top-nav-right" data-component="Stack" class="styles-module__right__mlBQg styles-module__withLocalNavigation__rjTJ_ styles-module__rightWithResponsiveCreateButton__SKn2W prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="start" data-padding="normal"></div></div><h2 class="prc-src-InternalVisuallyHidden-2YaI6">Repository navigation</h2><nav class="prc-components-UnderlineWrapper-eT-Yj prc-UnderlineNav-UnderlineWrapper-GWONT LocalNavigation-module__LocalNavigation__b0Xc0" aria-label="Repository" data-variant="inset" data-overflow-mode="wrap" data-hide-icons-breakpoint="medium"><ul class="prc-UnderlineNav-ItemsList-oj8gN prc-components-UnderlineItemList-xKlKC" role="list"><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a aria-current="page" data-tab-item="code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg></span><span data-component="text" data-content="Code">Code</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="issues" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff/issues" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg></span><span data-component="text" data-content="Issues">Issues</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">9</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->9<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="pull-requests" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff/pulls" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-pull-request" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path></svg></span><span data-component="text" data-content="Pull requests">Pull requests</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">11</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->11<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="discussions" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff/discussions" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg></span><span data-component="text" data-content="Discussions">Discussions</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="actions" data-react-nav="actions-workflows" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff/actions" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-play" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path></svg></span><span data-component="text" data-content="Actions">Actions</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="projects" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff/projects" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-table" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path></svg></span><span data-component="text" data-content="Projects">Projects</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="security-and-quality" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff/security" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg></span><span data-component="text" data-content="Security and quality">Security and quality</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="insights" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/umputun/revdiff/pulse" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-graph" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg></span><span data-component="text" data-content="Insights">Insights</span></a></li></ul><div class="prc-UnderlineNav-MoreButtonContainer-Dnrq6"><div class="prc-UnderlineNav-MoreButtonDivider-dN0a-"></div><button data-component="overflow-menu-button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk prc-UnderlineNav-MoreButton-Y8soj" data-loading="false" data-size="medium" data-variant="invisible" id="_R_2ktl_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3"><span>More<span class="prc-src-InternalVisuallyHidden-2YaI6"> items</span></span></span></span><span data-component="trailingAction" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></button></div></nav><div class="d-none"></div></header></div>
</react-partial>


  



<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
    <div id="repo-content-pjax-container" class="repository-content " >
    



    
      
    








<react-app
  app-name="code-view"
  initial-path="/umputun/revdiff/blob/master/README.md"
  style="display: block; min-height: calc(100vh - 64px);"
  data-attempted-ssr="true"
  data-ssr="true"
  data-lazy="false"
  data-alternate="false"
  data-data-router-enabled="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-app.embeddedData">{"payload":{"codeViewBlobRoute":{"csv":null,"csvError":null,"headerInfo":{"toc":[{"level":1,"text":" revdiff  ","anchor":"revdiff---","htmlText":" revdiff  "},{"level":2,"text":"Features","anchor":"features","htmlText":"Features"},{"level":2,"text":"Requirements","anchor":"requirements","htmlText":"Requirements"},{"level":2,"text":"Installation","anchor":"installation","htmlText":"Installation"},{"level":2,"text":"Claude Code Plugin","anchor":"claude-code-plugin","htmlText":"Claude Code Plugin"},{"level":3,"text":"Plan Review Plugin","anchor":"plan-review-plugin","htmlText":"Plan Review Plugin"},{"level":2,"text":"Pi Package","anchor":"pi-package","htmlText":"Pi Package"},{"level":2,"text":"Codex Plugin","anchor":"codex-plugin","htmlText":"Codex Plugin"},{"level":3,"text":"Integration with Other Tools","anchor":"integration-with-other-tools","htmlText":"Integration with Other Tools"},{"level":4,"text":"OpenCode","anchor":"opencode","htmlText":"OpenCode"},{"level":4,"text":"General","anchor":"general","htmlText":"General"},{"level":2,"text":"Usage","anchor":"usage","htmlText":"Usage"},{"level":3,"text":"Options","anchor":"options","htmlText":"Options"},{"level":3,"text":"Config File","anchor":"config-file","htmlText":"Config File"},{"level":3,"text":"Themes","anchor":"themes","htmlText":"Themes"},{"level":3,"text":"Examples","anchor":"examples","htmlText":"Examples"},{"level":3,"text":"All-Files Mode","anchor":"all-files-mode","htmlText":"All-Files Mode"},{"level":3,"text":"Context-Only File Review","anchor":"context-only-file-review","htmlText":"Context-Only File Review"},{"level":3,"text":"Two-File Diff","anchor":"two-file-diff","htmlText":"Two-File Diff"},{"level":3,"text":"Scratch-Buffer Review","anchor":"scratch-buffer-review","htmlText":"Scratch-Buffer Review"},{"level":3,"text":"Review Description","anchor":"review-description","htmlText":"Review Description"},{"level":3,"text":"Markdown TOC Navigation","anchor":"markdown-toc-navigation","htmlText":"Markdown TOC Navigation"},{"level":3,"text":"Beyond Code Review","anchor":"beyond-code-review","htmlText":"Beyond Code Review"},{"level":3,"text":"Zed Integration","anchor":"zed-integration","htmlText":"Zed Integration"},{"level":3,"text":"Review History","anchor":"review-history","htmlText":"Review History"},{"level":3,"text":"Key Bindings","anchor":"key-bindings","htmlText":"Key Bindings"},{"level":3,"text":"Status Bar Icons","anchor":"status-bar-icons","htmlText":"Status Bar Icons"},{"level":3,"text":"Mouse Support","anchor":"mouse-support","htmlText":"Mouse Support"},{"level":3,"text":"Custom Keybindings","anchor":"custom-keybindings","htmlText":"Custom Keybindings"},{"level":3,"text":"Vim-motion Preset","anchor":"vim-motion-preset","htmlText":"Vim-motion Preset"},{"level":3,"text":"Output Format","anchor":"output-format","htmlText":"Output Format"},{"level":2,"text":"Contributing","anchor":"contributing","htmlText":"Contributing"},{"level":2,"text":"License","anchor":"license","htmlText":"License"}]},"issueTemplate":null,"discussionTemplate":null,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"/umputun/revdiff/blob/master/site/assets/logo.png\"\u003e\u003cimg src=\"/umputun/revdiff/raw/master/site/assets/logo.png\" alt=\"\" width=\"28\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e revdiff  \u003ca href=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml/badge.svg\" alt=\"build\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e \u003ca href=\"https://coveralls.io/github/umputun/revdiff?branch=master\" rel=\"nofollow\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/9a886abdcd335a7a5d197d30137e474e98627ce5472249d292957b53f78b98d2/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f756d707574756e2f726576646966662f62616467652e7376673f6272616e63683d6d6173746572\" alt=\"Coverage Status\" data-canonical-src=\"https://coveralls.io/repos/github/umputun/revdiff/badge.svg?branch=master\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e \u003ca href=\"https://goreportcard.com/report/github.com/umputun/revdiff\" rel=\"nofollow\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/fc0af9bf876e1195f867c8ab8ee0238f1e4e98d9f715d83cdfbcd71adc02cf3e/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f756d707574756e2f72657664696666\" alt=\"Go Report Card\" data-canonical-src=\"https://goreportcard.com/badge/github.com/umputun/revdiff\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/h1\u003e\u003ca id=\"user-content-revdiff---\" class=\"anchor\" aria-label=\"Permalink:  revdiff  \" href=\"#revdiff---\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTUI for reviewing diffs, files, and documents with inline annotations. Outputs structured annotations to stdout on quit, making it easy to pipe results into AI agents, scripts, or other tools.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBuilt for a specific use case: reviewing code changes, plans, and documents without leaving a terminal-based AI coding session (e.g., Claude Code). Just enough UI to navigate diffs and files, annotate specific lines, and return the results to the calling process - no more, no less.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFeatures\u003c/h2\u003e\u003ca id=\"user-content-features\" class=\"anchor\" aria-label=\"Permalink: Features\" href=\"#features\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eStructured annotation output to stdout - pipe into AI agents, scripts, or other tools\u003c/li\u003e\n\u003cli\u003eFull-file diff view with syntax highlighting\u003c/li\u003e\n\u003cli\u003eIntra-line word-diff: highlights the specific changed words within paired add/remove lines using a brighter background overlay, off by default — enable with \u003ccode\u003e--word-diff\u003c/code\u003e or toggle with \u003ccode\u003eW\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eCollapsed diff mode: shows final text with change markers, toggle with \u003ccode\u003ev\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eWord wrap mode: wraps long lines at viewport boundary with \u003ccode\u003e↪\u003c/code\u003e continuation markers, toggle with \u003ccode\u003ew\u003c/code\u003e; optional \u003ccode\u003e--wrap-indent N\u003c/code\u003e for hanging-indent continuations (handy for markdown lists)\u003c/li\u003e\n\u003cli\u003ePage scroll overlap: \u003ccode\u003e--page-overlap N\u003c/code\u003e carries the bottom N lines of the screen to the top of the next one on PgUp/PgDn, so the seam between screens keeps context; the carryover is approximate on wrapped or annotated lines, which occupy several rows but are a single cursor stop\u003c/li\u003e\n\u003cli\u003eHorizontal scroll overflow indicators: truncated diff lines show \u003ccode\u003e«\u003c/code\u003e / \u003ccode\u003e»\u003c/code\u003e markers at the edges to signal hidden content off-screen\u003c/li\u003e\n\u003cli\u003eVertical scrollbar thumb: a thicker \u003ccode\u003e┃\u003c/code\u003e segment on pane right borders indicates the visible portion of long diffs, file trees, and markdown TOCs; thumb size and position track scroll progress automatically\u003c/li\u003e\n\u003cli\u003eLine numbers: side-by-side old/new line number gutter for diffs, single column for full-context files, toggle with \u003ccode\u003eL\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eRename-aware diffs (git): a renamed file shows its origin in the diff-pane header as \u003ccode\u003eold → new\u003c/code\u003e and renders only the real line changes instead of a full delete-and-add\u003c/li\u003e\n\u003cli\u003eMercurial support: auto-detects hg repos, translates git-style refs (HEAD, HEAD~N) to Mercurial revsets\u003c/li\u003e\n\u003cli\u003eJujutsu support: auto-detects jj repos (including colocated git+jj), translates git-style refs to jj revsets (\u003ccode\u003eHEAD\u003c/code\u003e → \u003ccode\u003e@-\u003c/code\u003e, \u003ccode\u003eHEAD~N\u003c/code\u003e → \u003ccode\u003e@\u003c/code\u003e plus N+1 dashes); \u003ccode\u003e--all-files\u003c/code\u003e supported\u003c/li\u003e\n\u003cli\u003eBlame gutter: shows author name and commit age per line, toggle with \u003ccode\u003eB\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eAnnotate any line in the diff (added, removed, or context) plus file-level notes\u003c/li\u003e\n\u003cli\u003eSingle-file auto-detection: when a diff contains exactly one file, hides the tree pane and gives full terminal width to the diff view\u003c/li\u003e\n\u003cli\u003eTwo-pane TUI: file tree (left) + colorized diff viewport (right)\u003c/li\u003e\n\u003cli\u003eVim-style \u003ccode\u003e/\u003c/code\u003e search within diff with \u003ccode\u003en\u003c/code\u003e/\u003ccode\u003eN\u003c/code\u003e match navigation\u003c/li\u003e\n\u003cli\u003eHunk navigation to jump between change groups\u003c/li\u003e\n\u003cli\u003eAnnotation list popup (\u003ccode\u003e@\u003c/code\u003e): browse all annotations across files, jump to any annotation\u003c/li\u003e\n\u003cli\u003eFilter file tree to show only annotated files\u003c/li\u003e\n\u003cli\u003eStatus line with filename, diff stats, hunk position, line number, and mode indicators\u003c/li\u003e\n\u003cli\u003eHelp overlay (\u003ccode\u003e?\u003c/code\u003e) showing all keybindings organized by section\u003c/li\u003e\n\u003cli\u003eInfo popup (\u003ccode\u003ei\u003c/code\u003e) showing launch scope (mode, VCS, ref, filters, file/status counts, aggregate \u003ccode\u003e+/-\u003c/code\u003e line stats), the optional \u003ccode\u003e--description\u003c/code\u003e prose, and the commit log subject + body for every commit in the current ref range (git/hg/jj) — useful for restoring narrative context when reviewing PR-style diffs\u003c/li\u003e\n\u003cli\u003eMarkdown TOC navigation: single-file markdown files in context-only mode show a table-of-contents pane with header navigation and active section tracking\u003c/li\u003e\n\u003cli\u003eAll-files mode: browse and annotate all tracked files with \u003ccode\u003e--all-files\u003c/code\u003e (git \u003ccode\u003els-files\u003c/code\u003e or jj \u003ccode\u003efile list\u003c/code\u003e), filter with \u003ccode\u003e--include\u003c/code\u003e and \u003ccode\u003e--exclude\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNo-VCS file review: \u003ccode\u003e--only\u003c/code\u003e files outside a VCS repo (or not in any diff) are shown as context-only with full annotation support\u003c/li\u003e\n\u003cli\u003eScratch-buffer review: annotate arbitrary piped or redirected text with \u003ccode\u003e--stdin\u003c/code\u003e, optionally naming it with \u003ccode\u003e--stdin-name\u003c/code\u003e. When the piped content sniffs as a git unified diff, revdiff parses it as a real multi-file diff (review \u003ccode\u003egh pr diff\u003c/code\u003e or \u003ccode\u003egit format-patch -1 --stdout\u003c/code\u003e output directly); otherwise the input is shown as a single context-only buffer.\u003c/li\u003e\n\u003cli\u003ePi package: launch revdiff from pi, capture annotations, and send them to the agent immediately for the normal review loop\u003c/li\u003e\n\u003cli\u003eReview history: auto-saves annotations and diffs to \u003ccode\u003e~/.config/revdiff/history/\u003c/code\u003e on quit as a safety net\u003c/li\u003e\n\u003cli\u003eFully customizable colors via environment variables, CLI flags, or config file\u003c/li\u003e\n\u003cli\u003eCustom keybindings: remap any key via config file, export defaults with \u003ccode\u003e--dump-keys\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"/umputun/revdiff/blob/master/site/assets/screenshot.png\"\u003e\u003cimg src=\"/umputun/revdiff/raw/master/site/assets/screenshot.png\" alt=\"revdiff screenshot\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRequirements\u003c/h2\u003e\u003ca id=\"user-content-requirements\" class=\"anchor\" aria-label=\"Permalink: Requirements\" href=\"#requirements\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003egit\u003c/code\u003e, \u003ccode\u003ehg\u003c/code\u003e, or \u003ccode\u003ejj\u003c/code\u003e (used to generate diffs; optional when using \u003ccode\u003e--only\u003c/code\u003e or \u003ccode\u003e--stdin\u003c/code\u003e)\u003c/li\u003e\n\u003cli\u003eJujutsu must be 0.27 or newer. Versions 0.23 through 0.26 have no \u003ccode\u003ejj file annotate -T\u003c/code\u003e, so the blame gutter does not work. Versions before 0.23 also reject the commit-log template behind the commit-info popup.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eInstallation\u003c/h2\u003e\u003ca id=\"user-content-installation\" class=\"anchor\" aria-label=\"Permalink: Installation\" href=\"#installation\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eHomebrew (macOS/Linux):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"brew install umputun/apps/revdiff\"\u003e\u003cpre\u003ebrew install umputun/apps/revdiff\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eArch Linux (AUR):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"paru -S revdiff\"\u003e\u003cpre\u003eparu -S revdiff\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eDebian/Ubuntu (.deb):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# download the latest .deb for your architecture from GitHub Releases\nsudo dpkg -i revdiff_*.deb\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e download the latest .deb for your architecture from GitHub Releases\u003c/span\u003e\nsudo dpkg -i revdiff_\u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e.deb\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRPM-based (Fedora, RHEL, etc.):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# download the latest .rpm for your architecture from GitHub Releases\nsudo rpm -i revdiff_*.rpm\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e download the latest .rpm for your architecture from GitHub Releases\u003c/span\u003e\nsudo rpm -i revdiff_\u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e.rpm\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eGo:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"go install github.com/umputun/revdiff/app/revdiff@latest\"\u003e\u003cpre\u003ego install github.com/umputun/revdiff/app/revdiff@latest\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eInstalls the \u003ccode\u003erevdiff\u003c/code\u003e binary into \u003ccode\u003eGOBIN\u003c/code\u003e (defaults to \u003ccode\u003e$(go env GOPATH)/bin\u003c/code\u003e). Add that directory to your \u003ccode\u003ePATH\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eBinary releases:\u003c/strong\u003e download from \u003ca href=\"https://github.com/umputun/revdiff/releases\"\u003eGitHub Releases\u003c/a\u003e (deb, rpm, archives for linux/darwin amd64/arm64).\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eClaude Code Plugin\u003c/h2\u003e\u003ca id=\"user-content-claude-code-plugin\" class=\"anchor\" aria-label=\"Permalink: Claude Code Plugin\" href=\"#claude-code-plugin\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003erevdiff ships with a Claude Code plugin for interactive code review directly from a Claude session. The plugin launches revdiff as a terminal overlay, captures annotations, and feeds them back to Claude for processing.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe plugin requires one of the following terminals since Claude Code itself cannot display interactive TUI applications - the overlay runs revdiff in a separate terminal layer on top of the current session:\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eTerminal\u003c/th\u003e\n\u003cth\u003eOverlay method\u003c/th\u003e\n\u003cth\u003eDetection\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eagterm\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eagtermctl session overlay open … --block\u003c/code\u003e (full-pane overlay, blocks until quit)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$AGTERM_SESSION_ID\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003etmux\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003edisplay-popup\u003c/code\u003e (blocks until quit)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$TMUX\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eZellij\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ezellij run --floating\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$ZELLIJ\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eherdr\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eherdr tab create\u003c/code\u003e + \u003ccode\u003eherdr pane run\u003c/code\u003e (new tab), or a zoomed \u003ccode\u003eherdr pane split\u003c/code\u003e with \u003ccode\u003eREVDIFF_HERDR_PANE=1\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$HERDR_ENV\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003ekitty\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ekitty @ launch --type=overlay\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$KITTY_LISTEN_ON\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003ewezterm\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ewezterm cli split-pane\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$WEZTERM_PANE\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eKaku\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ekaku cli split-pane\u003c/code\u003e (same API as wezterm)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$WEZTERM_PANE\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003ecmux\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ecmux new-split\u003c/code\u003e + \u003ccode\u003ecmux send\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$CMUX_SURFACE_ID\u003c/code\u003e, \u003ccode\u003e__CFBundleIdentifier=com.cmuxterm.app\u003c/code\u003e, or \u003ccode\u003eGHOSTTY_RESOURCES_DIR\u003c/code\u003e / \u003ccode\u003eGHOSTTY_BIN_DIR\u003c/code\u003e containing \u003ccode\u003ecmux.app\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eghostty\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eAppleScript split + zoom (macOS only)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$TERM_PROGRAM\u003c/code\u003e + AppleScript probe\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eiTerm2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eosascript\u003c/code\u003e split pane (macOS only)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$ITERM_SESSION_ID\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eEmacs vterm\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eNew frame via \u003ccode\u003eemacsclient\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e$INSIDE_EMACS\u003c/code\u003e env var\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003ePriority: agterm → tmux → Zellij → herdr → kitty → wezterm/Kaku → cmux → ghostty → iTerm2 → Emacs vterm (first detected wins). If none are available, the plugin exits with an error.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNote:\u003c/strong\u003e cmux is detected before ghostty when \u003ccode\u003e$CMUX_SURFACE_ID\u003c/code\u003e is set, \u003ccode\u003e__CFBundleIdentifier=com.cmuxterm.app\u003c/code\u003e, or \u003ccode\u003eGHOSTTY_RESOURCES_DIR\u003c/code\u003e / \u003ccode\u003eGHOSTTY_BIN_DIR\u003c/code\u003e contains \u003ccode\u003ecmux.app\u003c/code\u003e. The cmux block uses the cmux CLI (\u003ccode\u003enew-split\u003c/code\u003e + \u003ccode\u003esend --surface\u003c/code\u003e) instead of Ghostty's AppleScript API.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNote:\u003c/strong\u003e iTerm2 uses a split pane (vertical or horizontal, auto-detected from terminal dimensions) rather than a full-screen overlay. The iTerm2 AppleScript API does not expose a zoom command, so the split view shares screen space with the invoking session.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNote:\u003c/strong\u003e Ghostty and iTerm2 launchers use \u003ccode\u003eosascript\u003c/code\u003e (Apple Events), which is blocked by Claude Code's sandbox. If you use these terminals with sandbox enabled, add the launcher to \u003ccode\u003eexcludedCommands\u003c/code\u003e in your Claude Code \u003ccode\u003esettings.json\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;sandbox\u0026quot;: {\n    \u0026quot;excludedCommands\u0026quot;: [\u0026quot;*/launch-revdiff.sh*\u0026quot;]\n  }\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"sandbox\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"excludedCommands\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e*/launch-revdiff.sh*\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e]\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTerminals that use CLI tools instead of AppleScript (agterm, tmux, Zellij, herdr, kitty, wezterm, Kaku, cmux) are not affected.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eDisconnect-resilient tmux window mode:\u003c/strong\u003e set \u003ccode\u003eREVDIFF_TMUX_WINDOW=1\u003c/code\u003e in the launcher's environment to open revdiff in a persistent, server-owned tmux window instead of a client-owned \u003ccode\u003edisplay-popup\u003c/code\u003e. A dropped SSH or tmux client tears down a popup and kills the review, but a server-owned window survives the disconnect — reattach and the live review is still there. This is a launcher environment variable, not a revdiff flag.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePane-scoped overlay (herdr):\u003c/strong\u003e Set \u003ccode\u003eREVDIFF_HERDR_PANE=1\u003c/code\u003e in the launcher's environment to open revdiff in a zoomed split of the agent's own herdr pane instead of a new fullscreen tab, so the agent pane stays one keypress away. It needs a herdr whose CLI carries \u003ccode\u003epane split\u003c/code\u003e, \u003ccode\u003epane get\u003c/code\u003e and \u003ccode\u003epane close\u003c/code\u003e; an unsupported CLI or a refused split falls back to the tab overlay; a split that succeeds but returns no usable pane id fails closed with a warning rather than opening a second surface, and may leave a stray pane to close by hand. This is a launcher environment variable, not a revdiff flag.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePane-scoped overlay (agterm):\u003c/strong\u003e set \u003ccode\u003eREVDIFF_AGTERM_PANE=1\u003c/code\u003e in the launcher's environment to open revdiff in the agent's own split pane instead of over the whole session, leaving the sibling pane live and visible. It applies only when that session is split — the session-wide overlay stands otherwise, and the launcher retries session-wide if agterm refuses the pane. The review gets pane width rather than session width, which is why it is opt-in. This is a launcher environment variable, not a revdiff flag.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eInstall:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# add marketplace and install\n/plugin marketplace add umputun/revdiff\n/plugin install revdiff@revdiff\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e add marketplace and install\u003c/span\u003e\n/plugin marketplace add umputun/revdiff\n/plugin install revdiff@revdiff\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eUse with \u003ccode\u003e/revdiff\u003c/code\u003e command:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/revdiff                  -- smart detection: uncommitted, last commit, or branch diff\n/revdiff HEAD~1 HEAD      -- review last commit\n/revdiff main             -- review current branch against main\n/revdiff --staged         -- review staged changes only\n/revdiff HEAD~3 HEAD      -- review last 3 commits\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e/revdiff                  -- smart detection: uncommitted, last commit, or branch diff\n/revdiff HEAD~1 HEAD      -- review last commit\n/revdiff main             -- review current branch against main\n/revdiff --staged         -- review staged changes only\n/revdiff HEAD~3 HEAD      -- review last 3 commits\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eUse with free text\u003c/strong\u003e (no slash command needed):\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"\u0026quot;review diff\u0026quot;                     -- smart detection, same as /revdiff\n\u0026quot;review diff HEAD~1 HEAD\u0026quot;         -- last commit\n\u0026quot;review diff against main\u0026quot;        -- branch diff\n\u0026quot;review changes from last 2 days\u0026quot; -- Claude resolves the ref automatically\n\u0026quot;revdiff for staged changes\u0026quot;      -- staged only\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e\"review diff\"                     -- smart detection, same as /revdiff\n\"review diff HEAD~1 HEAD\"         -- last commit\n\"review diff against main\"        -- branch diff\n\"review changes from last 2 days\" -- Claude resolves the ref automatically\n\"revdiff for staged changes\"      -- staged only\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen no ref is provided, the plugin auto-detects the VCS (git, hg, or jj) and inspects the current repo state to pick what to review:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eOn main/master with uncommitted changes — reviews uncommitted changes\u003c/li\u003e\n\u003cli\u003eOn main/master with clean tree — reviews the last commit\u003c/li\u003e\n\u003cli\u003eOn a feature branch with clean tree — reviews branch diff against main\u003c/li\u003e\n\u003cli\u003eOn a feature branch with uncommitted changes — asks whether to review uncommitted only or the full branch diff\u003c/li\u003e\n\u003cli\u003eOutside a VCS repo — falls back to asking the user what to review\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eThe plugin includes built-in reference documentation and can answer questions about revdiff usage, available themes, keybindings, and configuration options. It can also create or modify the local config file (\u003ccode\u003e~/.config/revdiff/config\u003c/code\u003e) on request:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"\u0026quot;what chroma themes does revdiff support?\u0026quot;\n\u0026quot;switch revdiff to dracula theme\u0026quot;\n\u0026quot;what are the revdiff keybindings?\u0026quot;\n\u0026quot;set tree width to 3 in revdiff config\u0026quot;\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e\"what chroma themes does revdiff support?\"\n\"switch revdiff to dracula theme\"\n\"what are the revdiff keybindings?\"\n\"set tree width to 3 in revdiff config\"\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe plugin supports the full review loop: annotate → plan → fix → re-review until no more annotations remain. The bundled launcher treats exit code \u003ccode\u003e10\u003c/code\u003e as success-with-annotations and processes stdout normally.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eAsk instead of instruct:\u003c/strong\u003e an annotation containing \u003ccode\u003e??\u003c/code\u003e anywhere in its text is treated as a question rather than a directive, so the agent explains that code instead of changing it. Openers \u003ccode\u003eexplain\u003c/code\u003e, \u003ccode\u003eremind\u003c/code\u003e, \u003ccode\u003edescribe\u003c/code\u003e, \u003ccode\u003ewhat is\u003c/code\u003e, \u003ccode\u003ewhat are\u003c/code\u003e, \u003ccode\u003ehow does\u003c/code\u003e, \u003ccode\u003ehow do\u003c/code\u003e and \u003ccode\u003eclarify\u003c/code\u003e do the same. \u003ccode\u003e??\u003c/code\u003e is the language-neutral form and works whatever you write in.\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"## renderer.go:142 (+)\nwhy a pointer here??\n\n## store.go:88 (-)\nexplain what this lock protects\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e## renderer.go:142 (+)\nwhy a pointer here??\n\n## store.go:88 (-)\nexplain what this lock protects\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe answer comes back as a markdown document reopened in revdiff, with a TOC sidebar, so you can annotate the explanation itself to ask follow-ups. That loop repeats until you quit without annotating. Any code-change annotations from the same batch are held and applied afterwards. The Codex plugin behaves the same way; the Pi package classifies questions too but answers them in chat.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eCustom launchers:\u003c/strong\u003e the Claude diff-review skill and the cross-runtime planning plugin resolve launchers through a two-layer chain (user → bundled). Claude uses \u003ccode\u003e${CLAUDE_PLUGIN_DATA}/scripts/\u0026lt;launcher\u0026gt;\u003c/code\u003e; the Codex planning hook uses \u003ccode\u003e${PLUGIN_DATA}/scripts/launch-plan-review.sh\u003c/code\u003e. There is no project-level executable override by design because these hooks auto-fire in any opened repository. See \u003ccode\u003e.claude-plugin/skills/revdiff/references/install.md\u003c/code\u003e for diff review and \u003ca href=\"/umputun/revdiff/blob/master/plugins/revdiff-planning/README.md\"\u003eplugins/revdiff-planning/README.md\u003c/a\u003e for plan review.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePlan Review Plugin\u003c/h3\u003e\u003ca id=\"user-content-plan-review-plugin\" class=\"anchor\" aria-label=\"Permalink: Plan Review Plugin\" href=\"#plan-review-plugin\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA separate \u003ccode\u003erevdiff-planning\u003c/code\u003e plugin automatically opens revdiff when Claude or Codex completes a plan, letting you annotate it before implementation. If you add annotations, the agent revises the full plan and presents it again — looping until you're satisfied. Exit code \u003ccode\u003e10\u003c/code\u003e means annotations were captured, not launcher failure.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eClaude Code:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/plugin marketplace add umputun/revdiff\n/plugin install revdiff-planning@revdiff\"\u003e\u003cpre\u003e/plugin marketplace add umputun/revdiff\n/plugin install revdiff-planning@revdiff\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eCodex:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"codex plugin marketplace add umputun/revdiff\ncodex plugin add revdiff-planning@revdiff\"\u003e\u003cpre\u003ecodex plugin marketplace add umputun/revdiff\ncodex plugin add revdiff-planning@revdiff\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eStart a new Codex session and trust the hook through \u003ccode\u003e/hooks\u003c/code\u003e. Codex automatic review is opt-in and only fires for complete \u003ccode\u003e\u0026lt;proposed_plan\u0026gt;\u003c/code\u003e blocks in Plan mode; \u003ccode\u003e/revdiff-plan\u003c/code\u003e remains the manual fallback.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis plugin is independent from the main \u003ccode\u003erevdiff\u003c/code\u003e plugin. In Claude Code it hooks \u003ccode\u003eExitPlanMode\u003c/code\u003e, and so does \u003ccode\u003eplanning\u003c/code\u003e from \u003ccode\u003ecc-thingz\u003c/code\u003e; Claude Code runs both hooks, so enabling both can review the same plan twice.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePi Package\u003c/h2\u003e\u003ca id=\"user-content-pi-package\" class=\"anchor\" aria-label=\"Permalink: Pi Package\" href=\"#pi-package\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003erevdiff also ships as a \u003ca href=\"https://github.com/badlogic/pi-mono\"\u003epi\u003c/a\u003e package. The \u003ccode\u003e/revdiff\u003c/code\u003e command routes requests through the revdiff skill, which resolves refs, files, and natural-language targets before launching the existing \u003ccode\u003erevdiff\u003c/code\u003e binary through the \u003ccode\u003erevdiff_review\u003c/code\u003e tool. If no annotations were captured, the agent stops the review loop unless you explicitly ask for another review.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eInstall:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"pi install https://github.com/umputun/revdiff\"\u003e\u003cpre\u003epi install https://github.com/umputun/revdiff\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eCommand inside pi:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/revdiff [args]\"\u003e\u003cpre lang=\"text\" class=\"notranslate\"\u003e\u003ccode\u003e/revdiff [args]\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUseful args:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/revdiff                         -- detect uncommitted, staged, or branch changes, then open revdiff\n/revdiff HEAD~1 HEAD             -- review last commit\n/revdiff main                    -- review against main\n/revdiff --staged                -- review staged changes\n/revdiff --untracked             -- include untracked files in working-tree review\n/revdiff --all-files             -- browse all tracked files\n/revdiff --all-files --exclude vendor\n/revdiff --only README.md        -- review a single file in context-only mode\n/revdiff HEAD~3 --description=\u0026quot;why this refactor matters\u0026quot;\n/revdiff HEAD~3 --description-file=/tmp/revdiff-desc.md\n/revdiff main --annotations=/tmp/revdiff-review.md\"\u003e\u003cpre lang=\"text\" class=\"notranslate\"\u003e\u003ccode\u003e/revdiff                         -- detect uncommitted, staged, or branch changes, then open revdiff\n/revdiff HEAD~1 HEAD             -- review last commit\n/revdiff main                    -- review against main\n/revdiff --staged                -- review staged changes\n/revdiff --untracked             -- include untracked files in working-tree review\n/revdiff --all-files             -- browse all tracked files\n/revdiff --all-files --exclude vendor\n/revdiff --only README.md        -- review a single file in context-only mode\n/revdiff HEAD~3 --description=\"why this refactor matters\"\n/revdiff HEAD~3 --description-file=/tmp/revdiff-desc.md\n/revdiff main --annotations=/tmp/revdiff-review.md\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNatural-language targets are supported because \u003ccode\u003e/revdiff\u003c/code\u003e routes through the skill:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/revdiff prev commit\n/revdiff last tag\n/revdiff 2 weeks ago\"\u003e\u003cpre lang=\"text\" class=\"notranslate\"\u003e\u003ccode\u003e/revdiff prev commit\n/revdiff last tag\n/revdiff 2 weeks ago\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eYou can also call the skill explicitly with \u003ccode\u003e/skill:revdiff \u0026lt;request\u0026gt;\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eAgent workflow:\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e/revdiff\u003c/code\u003e is a Pi command alias for \u003ccode\u003e/skill:revdiff\u003c/code\u003e; the skill resolves the request and calls \u003ccode\u003erevdiff_review\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erevdiff_review\u003c/code\u003e suspends pi, hands the terminal to revdiff, then returns captured annotations to the agent.\u003c/li\u003e\n\u003cli\u003eThe agent classifies annotations into explanation requests and code-change directives.\u003c/li\u003e\n\u003cli\u003eExplanation requests are answered first in normal chat, without opening another revdiff session for the explanation.\u003c/li\u003e\n\u003cli\u003eAny no-annotation \u003ccode\u003erevdiff_review\u003c/code\u003e result stops the loop. The agent must not relaunch revdiff unless you explicitly ask for another review.\u003c/li\u003e\n\u003cli\u003eFor explanation-only annotations, the agent asks whether to continue the original review or finish.\u003c/li\u003e\n\u003cli\u003eBefore editing repository files, the agent lists planned code/file changes, applies the changes, then reruns \u003ccode\u003erevdiff_review\u003c/code\u003e with the same args until no annotations are captured.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNotes:\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRequires the \u003ccode\u003erevdiff\u003c/code\u003e binary on \u003ccode\u003ePATH\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eSet \u003ccode\u003eREVDIFF_BIN=/absolute/path/to/revdiff\u003c/code\u003e if pi can't find the binary\u003c/li\u003e\n\u003cli\u003eDirect terminal handoff is the only Pi launch mode\u003c/li\u003e\n\u003cli\u003eExit code \u003ccode\u003e10\u003c/code\u003e means annotations were captured, not failure\u003c/li\u003e\n\u003cli\u003eUse \u003ccode\u003e--untracked\u003c/code\u003e when agent-created files should be reviewed before they are staged\u003c/li\u003e\n\u003cli\u003eUse \u003ccode\u003e--description\u003c/code\u003e or \u003ccode\u003e--description-file\u003c/code\u003e after analysis/refactor work so the info popup carries review context\u003c/li\u003e\n\u003cli\u003eUse \u003ccode\u003e--annotations=\u0026lt;tempfile\u0026gt;\u003c/code\u003e to preload in-session review notes\u003c/li\u003e\n\u003cli\u003eSuccessful \u003ccode\u003erevdiff_review\u003c/code\u003e results include captured annotation text; history is only for explicit latest-history requests or missing-output fallback\u003c/li\u003e\n\u003cli\u003eFor \"use my latest revdiff annotations\", the agent should read the newest file under \u003ccode\u003e$REVDIFF_HISTORY_DIR\u003c/code\u003e or \u003ccode\u003e~/.config/revdiff/history/\u003c/code\u003e instead of relaunching revdiff\u003c/li\u003e\n\u003cli\u003eIn the repo, the pi-specific resources live under \u003ccode\u003eplugins/pi/\u003c/code\u003e to keep harness integrations clearly separated\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCodex Plugin\u003c/h2\u003e\u003ca id=\"user-content-codex-plugin\" class=\"anchor\" aria-label=\"Permalink: Codex Plugin\" href=\"#codex-plugin\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003erevdiff ships with a \u003ca href=\"https://github.com/openai/codex\"\u003eCodex CLI\u003c/a\u003e plugin for interactive diff review and plan annotation directly from a Codex session. The plugin provides two skills:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e/revdiff\u003c/code\u003e — same diff review workflow as the Claude Code plugin (detect ref, launch overlay, capture annotations, feedback loop)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/revdiff-plan\u003c/code\u003e — extracts the last Codex assistant message from session rollout files, opens it in revdiff for annotation, and feeds feedback back\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eThe plugin uses the same terminal overlay mechanism (tmux, Zellij, herdr, kitty, wezterm, etc.) as the Claude Code plugin.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eInstall the diff-review skills and automatic plan-review plugin:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"codex plugin marketplace add umputun/revdiff\ncodex plugin add revdiff@revdiff\ncodex plugin add revdiff-planning@revdiff\"\u003e\u003cpre\u003ecodex plugin marketplace add umputun/revdiff\ncodex plugin add revdiff@revdiff\ncodex plugin add revdiff-planning@revdiff\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you previously copied the skills manually, remove \u003ccode\u003e~/.codex/skills/revdiff\u003c/code\u003e and \u003ccode\u003e~/.codex/skills/revdiff-plan\u003c/code\u003e after installing the plugin so the plugin copy is the only one in use.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eStart a new session and trust the plugin hook through \u003ccode\u003e/hooks\u003c/code\u003e. The \u003ccode\u003eStop\u003c/code\u003e hook runs only in Plan mode and first checks \u003ccode\u003elast_assistant_message\u003c/code\u003e; whenever that field has no complete \u003ccode\u003e\u0026lt;proposed_plan\u0026gt;\u003c/code\u003e, it reads the exact event transcript and selects the last assistant message for the matching \u003ccode\u003esession_id\u003c/code\u003e and \u003ccode\u003eturn_id\u003c/code\u003e, without depending on a provider-specific phase. A readable clarification turn is ignored. Missing or mismatched event data, dependencies, and launcher failures warn and fail open.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen annotations are present, the hook asks Codex to return the complete revised plan with a snapshot marker on the first line inside \u003ccode\u003e\u0026lt;proposed_plan\u0026gt;\u003c/code\u003e. The next round opens a rolling compare (\u003ccode\u003e\u0026lt;new\u0026gt; \u0026lt;old\u0026gt;\u003c/code\u003e); reviewed snapshots are replaced, and a clean review removes the final snapshot.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003erevdiff\u003c/code\u003e plugin installs both interactive skills. The separate \u003ccode\u003erevdiff-planning\u003c/code\u003e plugin adds automatic Plan-mode review.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRequirements:\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003erevdiff\u003c/code\u003e binary on \u003ccode\u003ePATH\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ejq\u003c/code\u003e (required only for manual \u003ccode\u003e/revdiff-plan\u003c/code\u003e session extraction)\u003c/li\u003e\n\u003cli\u003eOne of the supported terminal multiplexers for overlay mode\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNotes:\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eCodex treats exit code \u003ccode\u003e10\u003c/code\u003e as success-with-annotations and keeps captured output\u003c/li\u003e\n\u003cli\u003eAutomatic review uses the opt-in \u003ccode\u003erevdiff-planning\u003c/code\u003e plugin; \u003ccode\u003e/revdiff-plan\u003c/code\u003e remains a manual fallback\u003c/li\u003e\n\u003cli\u003eScripts are portable copies from the Claude Code plugin, not symlinks\u003c/li\u003e\n\u003cli\u003eCodex plugin source lives under \u003ccode\u003eplugins/codex/\u003c/code\u003e in the repository\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eIntegration with Other Tools\u003c/h3\u003e\u003ca id=\"user-content-integration-with-other-tools\" class=\"anchor\" aria-label=\"Permalink: Integration with Other Tools\" href=\"#integration-with-other-tools\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eOpenCode\u003c/h4\u003e\u003ca id=\"user-content-opencode\" class=\"anchor\" aria-label=\"Permalink: OpenCode\" href=\"#opencode\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003erevdiff integrates with \u003ca href=\"https://opencode.ai\" rel=\"nofollow\"\u003eOpenCode\u003c/a\u003e. V1 provides a tool, slash command, and plan-review plugin. V2 provides a CLI plugin for \u003ccode\u003e/revdiff\u003c/code\u003e and automatic plan review, using the shared launcher in the client's terminal environment.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eInstall (automatically detects OpenCode v1 or v2):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"cd plugins/opencode \u0026amp;\u0026amp; bash setup.sh\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003ecd\u003c/span\u003e plugins/opencode \u003cspan class=\"pl-k\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e bash setup.sh\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe v2 CLI plugin is discovered automatically under \u003ccode\u003eplugins/revdiff/\u003c/code\u003e. It runs reviews locally and returns annotations to the session captured at launch. Automatic plan review handles live completion events only, deduplicated between local clients using an atomic marker per event ID. Markers older than one day are removed on the next claim. Clients must share the same state directory and local checkout; the winner may be in a window the user is not looking at. Restart OpenCode after installing.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe installer uses \u003ccode\u003eopencode --version\u003c/code\u003e from \u003ccode\u003ePATH\u003c/code\u003e; use \u003ccode\u003ebash setup.sh --opencode /path/to/opencode /path/to/config\u003c/code\u003e to select another v2 installation. The v2 integration supports OpenCode v2.0.0+ and has no runtime npm dependencies. Its config directory follows \u003ccode\u003eOPENCODE_CONFIG_DIR\u003c/code\u003e, then XDG defaults. V1 installs only to \u003ccode\u003e~/.config/opencode\u003c/code\u003e. Upgrade removes the obsolete v1 plan plugin, Markdown command and exact JSON registration; JSONC is left untouched with a notice. V1 code remains unchanged, and rollback leaves the inert v2 directory in place. See \u003ca href=\"/umputun/revdiff/blob/master/plugins/opencode/README.md\"\u003eplugins/opencode/README.md\u003c/a\u003e for prerequisites, ownership rules and migration details.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eCommands inside OpenCode:\u003c/strong\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eV2 also supports \u003ccode\u003e/revdiff\u003c/code\u003e from the home screen. A clean review leaves it unchanged; annotations create a feedback session using the configured default agent and selected model, falling back to the configured model on older v2 clients.\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/revdiff                         -- review git diff with revdiff TUI\n/revdiff HEAD~3..HEAD             -- review last 3 commits\"\u003e\u003cpre lang=\"text\" class=\"notranslate\"\u003e\u003ccode\u003e/revdiff                         -- review git diff with revdiff TUI\n/revdiff HEAD~3..HEAD             -- review last 3 commits\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe v2 plan-review plugin automatically launches revdiff after a completed plan-agent response in the displayed root session. Annotations and a line-numbered snapshot of the reviewed plan are returned to that session for revision, so the agent does not need the deleted temporary file. V1 uses the plan-mode idle hook.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eGeneral\u003c/h4\u003e\u003ca id=\"user-content-general\" class=\"anchor\" aria-label=\"Permalink: General\" href=\"#general\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe structured stdout output works with any tool that can read text. By default revdiff exits \u003ccode\u003e0\u003c/code\u003e even when annotations are produced; pass \u003ccode\u003e--exit-code-on-annotations\u003c/code\u003e to return \u003ccode\u003e10\u003c/code\u003e for successful annotation output:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# capture annotations for processing\nrc=0\nannotations=$(revdiff --exit-code-on-annotations main) || rc=$?\ncase \u0026quot;$rc\u0026quot; in\n  0) [ -n \u0026quot;$annotations\u0026quot; ] \u0026amp;\u0026amp; echo \u0026quot;$annotations\u0026quot; | your-tool ;;\n  10) echo \u0026quot;$annotations\u0026quot; | your-tool ;;\n  *) exit \u0026quot;$rc\u0026quot; ;;\nesac\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e capture annotations for processing\u003c/span\u003e\nrc=0\nannotations=\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e$(\u003c/span\u003erevdiff --exit-code-on-annotations main\u003cspan class=\"pl-pds\"\u003e)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e||\u003c/span\u003e rc=\u003cspan class=\"pl-smi\"\u003e$?\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003ecase\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$rc\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003ein\u003c/span\u003e\n  0) [ \u003cspan class=\"pl-k\"\u003e-n\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$annotations\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e ] \u003cspan class=\"pl-k\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eecho\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$annotations\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e your-tool ;;\n  10) \u003cspan class=\"pl-c1\"\u003eecho\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$annotations\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e your-tool ;;\n  \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e) \u003cspan class=\"pl-c1\"\u003eexit\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$rc\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e ;;\n\u003cspan class=\"pl-k\"\u003eesac\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eExit status: \u003ccode\u003e0\u003c/code\u003e = no annotations, discarded annotations, or default mode; \u003ccode\u003e10\u003c/code\u003e = annotations were produced with \u003ccode\u003e--exit-code-on-annotations\u003c/code\u003e; \u003ccode\u003e1\u003c/code\u003e = real errors.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsage\u003c/h2\u003e\u003ca id=\"user-content-usage\" class=\"anchor\" aria-label=\"Permalink: Usage\" href=\"#usage\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"revdiff [OPTIONS] [base] [against]\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003erevdiff [OPTIONS] [base] [against]\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003ePositional arguments support several forms:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003erevdiff\u003c/code\u003e — uncommitted changes\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erevdiff HEAD~3\u003c/code\u003e — diff a single ref against the working tree\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erevdiff HEAD~1 HEAD\u003c/code\u003e — review exactly the last commit\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erevdiff main feature\u003c/code\u003e — diff between two refs\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erevdiff main..feature\u003c/code\u003e — same as above, using git's dot-dot syntax\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erevdiff main...feature\u003c/code\u003e — changes since \u003ccode\u003efeature\u003c/code\u003e diverged from \u003ccode\u003emain\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eOptions\u003c/h3\u003e\u003ca id=\"user-content-options\" class=\"anchor\" aria-label=\"Permalink: Options\" href=\"#options\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eOption\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003cth\u003eDefault\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ebase\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eGit ref to diff against\u003c/td\u003e\n\u003ctd\u003euncommitted changes\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eagainst\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSecond git ref for two-ref diff\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--staged\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow staged changes, env: \u003ccode\u003eREVDIFF_STAGED\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--untracked\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow untracked files in the tree, env: \u003ccode\u003eREVDIFF_UNTRACKED\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--tree-width\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFile tree panel width in units (1-10), env: \u003ccode\u003eREVDIFF_TREE_WIDTH\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e2\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--tab-width\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNumber of spaces per tab character, env: \u003ccode\u003eREVDIFF_TAB_WIDTH\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e4\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--no-colors\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDisable all colors including syntax highlighting, env: \u003ccode\u003eREVDIFF_NO_COLORS\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--no-status-bar\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eHide the status bar, env: \u003ccode\u003eREVDIFF_NO_STATUS_BAR\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--wrap\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eEnable line wrapping in diff view, env: \u003ccode\u003eREVDIFF_WRAP\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--wrap-indent\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eIndent wrap continuation rows by N columns so they hang under the first row's content (helps when reviewing markdown lists where unindented continuation can be misread as a new bullet), env: \u003ccode\u003eREVDIFF_WRAP_INDENT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e0\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--page-overlap\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eKeep N lines from the previous screen when paging the diff, env: \u003ccode\u003eREVDIFF_PAGE_OVERLAP\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e0\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--collapsed\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eStart in collapsed diff mode, env: \u003ccode\u003eREVDIFF_COLLAPSED\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--compact\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eStart in compact diff mode (small context around changes), env: \u003ccode\u003eREVDIFF_COMPACT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--compact-context\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNumber of context lines around changes when in compact mode, env: \u003ccode\u003eREVDIFF_COMPACT_CONTEXT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e5\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--cross-file-hunks\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAllow \u003ccode\u003e[\u003c/code\u003e and \u003ccode\u003e]\u003c/code\u003e to continue into adjacent files, env: \u003ccode\u003eREVDIFF_CROSS_FILE_HUNKS\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--cross-file-motion\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAllow cursor motion (\u003ccode\u003ej\u003c/code\u003e/\u003ccode\u003ek\u003c/code\u003e, \u003ccode\u003ePgDown\u003c/code\u003e/\u003ccode\u003ePgUp\u003c/code\u003e, \u003ccode\u003eCtrl+d\u003c/code\u003e/\u003ccode\u003eCtrl+u\u003c/code\u003e) to continue into adjacent files at a boundary, env: \u003ccode\u003eREVDIFF_CROSS_FILE_MOTION\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--start-at-change\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePosition the cursor on the first changed line, env: \u003ccode\u003eREVDIFF_START_AT_CHANGE\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--line-numbers\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow line numbers in diff gutter, env: \u003ccode\u003eREVDIFF_LINE_NUMBERS\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--blame\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow blame gutter, env: \u003ccode\u003eREVDIFF_BLAME\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--word-diff\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eHighlight intra-line word-level changes in paired add/remove lines, env: \u003ccode\u003eREVDIFF_WORD_DIFF\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--filter-unreviewed\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow only files not marked reviewed, env: \u003ccode\u003eREVDIFF_FILTER_UNREVIEWED\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--annotation-marker\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePrefix shown before annotation lines, env: \u003ccode\u003eREVDIFF_ANNOTATION_MARKER\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e💬\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--exit-code-on-annotations\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eExit 10 when annotations are produced, env: \u003ccode\u003eREVDIFF_EXIT_CODE_ON_ANNOTATIONS\u003c/code\u003e, config: \u003ccode\u003eexit-code-on-annotations\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--no-confirm-discard\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSkip confirmation when discarding annotations with Q, env: \u003ccode\u003eREVDIFF_NO_CONFIRM_DISCARD\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--no-confirm-reload\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSkip confirmation when dropping annotations on reload with R, env: \u003ccode\u003eREVDIFF_NO_CONFIRM_RELOAD\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--no-mouse\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDisable mouse support (scroll wheel, click), env: \u003ccode\u003eREVDIFF_NO_MOUSE\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--no-tree\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eHide the file tree pane, env: \u003ccode\u003eREVDIFF_NO_TREE\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--vim-motion\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eEnable vim-style motion preset (counts, \u003ccode\u003egg\u003c/code\u003e, \u003ccode\u003eG\u003c/code\u003e, \u003ccode\u003eH\u003c/code\u003e/\u003ccode\u003eM\u003c/code\u003e/\u003ccode\u003eL\u003c/code\u003e, \u003ccode\u003ezz\u003c/code\u003e/\u003ccode\u003ezt\u003c/code\u003e/\u003ccode\u003ezb\u003c/code\u003e, \u003ccode\u003eZZ\u003c/code\u003e/\u003ccode\u003eZQ\u003c/code\u003e), env: \u003ccode\u003eREVDIFF_VIM_MOTION\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--chroma-style\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eChroma color theme for syntax highlighting, env: \u003ccode\u003eREVDIFF_CHROMA_STYLE\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ecatppuccin-macchiato\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--theme\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eLoad color theme from \u003ccode\u003e~/.config/revdiff/themes/\u003c/code\u003e; use \u003ccode\u003eauto\u003c/code\u003e to choose by terminal background, env: \u003ccode\u003eREVDIFF_THEME\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--auto-theme-dark\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eTheme used by \u003ccode\u003e--theme auto\u003c/code\u003e on dark terminal backgrounds, env: \u003ccode\u003eREVDIFF_AUTO_THEME_DARK\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003erevdiff\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--auto-theme-light\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eTheme used by \u003ccode\u003e--theme auto\u003c/code\u003e on light terminal backgrounds, env: \u003ccode\u003eREVDIFF_AUTO_THEME_LIGHT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ecatppuccin-latte\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--dump-theme\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePrint currently resolved colors as theme file to stdout and exit\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--list-themes\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePrint available theme names to stdout and exit\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--init-themes\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eWrite bundled theme files to themes dir and exit\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--init-all-themes\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eWrite all gallery themes (bundled + community) to themes dir and exit\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--install-theme\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eInstall theme(s) from gallery or local file path and exit (repeatable)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e-A\u003c/code\u003e, \u003ccode\u003e--all-files\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eBrowse all tracked files, not just diffs (git or jj)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--compare-old\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCompare mode: old file path (use with \u003ccode\u003e--compare-new\u003c/code\u003e; uses \u003ccode\u003egit diff --no-index\u003c/code\u003e, no VCS repo needed)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--compare-new\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCompare mode: new file path (use with \u003ccode\u003e--compare-old\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--stdin\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eReview stdin as a scratch buffer (piped or redirected input only)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--stdin-name\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSynthetic file name for stdin content; enables extension-based highlighting/TOC\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003escratch-buffer\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--description\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eProse context shown in the info popup (markdown; for multi-line text, use a multi-line quoted shell string or \u003ccode\u003e--description-file\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--description-file\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRead the info-popup description from this file (markdown)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e-I\u003c/code\u003e, \u003ccode\u003e--include\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eInclude only files matching prefix, may be repeated, env: \u003ccode\u003eREVDIFF_INCLUDE\u003c/code\u003e (comma-separated)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e-X\u003c/code\u003e, \u003ccode\u003e--exclude\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eExclude files matching prefix, may be repeated, env: \u003ccode\u003eREVDIFF_EXCLUDE\u003c/code\u003e (comma-separated)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e-F\u003c/code\u003e, \u003ccode\u003e--only\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow only matching files by exact path or suffix, may be repeated (e.g. \u003ccode\u003e--only=model.go\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e-o\u003c/code\u003e, \u003ccode\u003e--output\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eWrite annotations to file instead of stdout, env: \u003ccode\u003eREVDIFF_OUTPUT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--post-flush-command\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRun command after a successful \u003ccode\u003eO\u003c/code\u003e flush, env: \u003ccode\u003eREVDIFF_POST_FLUSH_COMMAND\u003c/code\u003e, config: \u003ccode\u003epost-flush-command\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--annotations\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePreload annotations from a markdown file in \u003ccode\u003e-o\u003c/code\u003e format\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--history-dir\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDirectory for review history auto-saves, env: \u003ccode\u003eREVDIFF_HISTORY_DIR\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e~/.config/revdiff/history/\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--config\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePath to config file, env: \u003ccode\u003eREVDIFF_CONFIG\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e~/.config/revdiff/config\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--keys\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePath to keybindings file, env: \u003ccode\u003eREVDIFF_KEYS\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e~/.config/revdiff/keybindings\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--dump-keys\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePrint effective keybindings to stdout and exit\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--dump-config\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePrint default config to stdout and exit\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e-V\u003c/code\u003e, \u003ccode\u003e--version\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow version info\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConfig File\u003c/h3\u003e\u003ca id=\"user-content-config-file\" class=\"anchor\" aria-label=\"Permalink: Config File\" href=\"#config-file\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll options can be set in a config file at \u003ccode\u003e~/.config/revdiff/config\u003c/code\u003e (INI format). CLI flags and environment variables override config file values. For annotation exit status, use \u003ccode\u003eexit-code-on-annotations = true\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eGenerate a default config file:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"mkdir -p ~/.config/revdiff\nrevdiff --dump-config \u0026gt; ~/.config/revdiff/config\"\u003e\u003cpre\u003emkdir -p \u003cspan class=\"pl-k\"\u003e~\u003c/span\u003e/.config/revdiff\nrevdiff --dump-config \u003cspan class=\"pl-k\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e~\u003c/span\u003e/.config/revdiff/config\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThen uncomment and edit the values you want to change.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThemes\u003c/h3\u003e\u003ca id=\"user-content-themes\" class=\"anchor\" aria-label=\"Permalink: Themes\" href=\"#themes\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003erevdiff ships with eight bundled color themes: \u003cstrong\u003ebasic\u003c/strong\u003e, \u003cstrong\u003ecatppuccin-latte\u003c/strong\u003e, \u003cstrong\u003ecatppuccin-mocha\u003c/strong\u003e, \u003cstrong\u003edracula\u003c/strong\u003e, \u003cstrong\u003egruvbox\u003c/strong\u003e, \u003cstrong\u003enord\u003c/strong\u003e, \u003cstrong\u003erevdiff\u003c/strong\u003e, and \u003cstrong\u003esolarized-dark\u003c/strong\u003e. Themes are stored in \u003ccode\u003e~/.config/revdiff/themes/\u003c/code\u003e and are automatically created on first run.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003ePress \u003ccode\u003eT\u003c/code\u003e inside revdiff to open the interactive theme selector with live preview — browse themes, see colors applied instantly, and persist your choice to the config file on confirm.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# apply a theme\nrevdiff --theme dracula\n\n# choose a theme from the terminal background color\nrevdiff --theme auto\n\n# list available themes\nrevdiff --list-themes\n\n# re-create bundled theme files (overwrites bundled, keeps custom themes)\nrevdiff --init-themes\n\n# install a specific theme from the gallery\nrevdiff --install-theme catppuccin-latte\n\n# install all gallery themes (bundled + community)\nrevdiff --init-all-themes\n\n# export current colors as a custom theme\nrevdiff --dump-theme \u0026gt; ~/.config/revdiff/themes/my-custom\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e apply a theme\u003c/span\u003e\nrevdiff --theme dracula\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e choose a theme from the terminal background color\u003c/span\u003e\nrevdiff --theme auto\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e list available themes\u003c/span\u003e\nrevdiff --list-themes\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e re-create bundled theme files (overwrites bundled, keeps custom themes)\u003c/span\u003e\nrevdiff --init-themes\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e install a specific theme from the gallery\u003c/span\u003e\nrevdiff --install-theme catppuccin-latte\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e install all gallery themes (bundled + community)\u003c/span\u003e\nrevdiff --init-all-themes\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e export current colors as a custom theme\u003c/span\u003e\nrevdiff --dump-theme \u003cspan class=\"pl-k\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e~\u003c/span\u003e/.config/revdiff/themes/my-custom\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eCreating custom themes\u003c/strong\u003e — two approaches:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eFrom current colors:\u003c/strong\u003e customize individual colors in your config file or via \u003ccode\u003e--color-*\u003c/code\u003e flags, then dump the resolved result as a theme: \u003ccode\u003erevdiff --dump-theme \u0026gt; ~/.config/revdiff/themes/my-custom\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFrom scratch:\u003c/strong\u003e copy a bundled theme and edit it directly — each file defines all 23 color keys plus \u003ccode\u003echroma-style\u003c/code\u003e in INI format:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight highlight-source-ini notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# name: my-custom\n# description: custom color scheme\nchroma-style = dracula\ncolor-accent = #bd93f9\ncolor-border = #6272a4\n...all 23 color keys...\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e name: my-custom\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e description: custom color scheme\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003echroma-style\u003c/span\u003e = dracula\n\u003cspan class=\"pl-k\"\u003ecolor-accent\u003c/span\u003e = \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003ebd93f9\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003ecolor-border\u003c/span\u003e = \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e6272a4\u003c/span\u003e\n...all 23 color keys...\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSet a default theme in the config file:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ini notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"theme = dracula\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003etheme\u003c/span\u003e = dracula\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOr via environment variable: \u003ccode\u003eREVDIFF_THEME=dracula\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSet \u003ccode\u003etheme = auto\u003c/code\u003e to query the terminal background and choose a matching theme. By default, auto mode uses \u003ccode\u003erevdiff\u003c/code\u003e for dark backgrounds and \u003ccode\u003ecatppuccin-latte\u003c/code\u003e for light backgrounds:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ini notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"theme = auto\nauto-theme-dark = revdiff\nauto-theme-light = catppuccin-latte\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003etheme\u003c/span\u003e = auto\n\u003cspan class=\"pl-k\"\u003eauto-theme-dark\u003c/span\u003e = revdiff\n\u003cspan class=\"pl-k\"\u003eauto-theme-light\u003c/span\u003e = catppuccin-latte\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eContributing themes\u003c/strong\u003e — community themes live in the \u003ccode\u003ethemes/gallery/\u003c/code\u003e directory. See \u003ca href=\"/umputun/revdiff/blob/master/themes/README.md\"\u003ethemes/README.md\u003c/a\u003e for the contribution guide, format requirements, and validation instructions.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePrecedence:\u003c/strong\u003e When \u003ccode\u003e--theme\u003c/code\u003e is set, it takes over completely — all 23 color fields and chroma-style are overwritten by the theme, ignoring any \u003ccode\u003e--color-*\u003c/code\u003e flags or env vars. Without \u003ccode\u003e--theme\u003c/code\u003e: built-in defaults → config file → env vars → CLI flags. \u003ccode\u003e--theme\u003c/code\u003e + \u003ccode\u003e--no-colors\u003c/code\u003e prints a warning and applies the theme.\u003c/p\u003e\n\u003cdetails\u003e\n\u003csummary\u003eColor customization flags (click to expand)\u003c/summary\u003e\n\u003cp dir=\"auto\"\u003eAll color options accept hex values (\u003ccode\u003e#rrggbb\u003c/code\u003e) and have corresponding \u003ccode\u003eREVDIFF_COLOR_*\u003c/code\u003e env vars.\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eOption\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003cth\u003eDefault\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-accent\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eActive pane borders and directory names\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#D5895F\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-border\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eInactive pane borders\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#585858\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-normal\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFile entries and context lines\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#d0d0d0\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-muted\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDivider lines and status bar\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#585858\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-selected-fg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSelected file text\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#ffffaf\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-selected-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSelected file background\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#D5895F\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-annotation\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAnnotation text and markers\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#ffd700\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-cursor-fg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCursor indicator color\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#bbbb44\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-cursor-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCursor indicator background\u003c/td\u003e\n\u003ctd\u003eterminal default\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-add-fg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAdded line text\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#87d787\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-add-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAdded line background\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#123800\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-remove-fg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRemoved line text\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#ff8787\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-remove-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRemoved line background\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#4D1100\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-word-add-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eIntra-line word-diff add background\u003c/td\u003e\n\u003ctd\u003eauto-derived from add-bg\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-word-remove-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eIntra-line word-diff remove background\u003c/td\u003e\n\u003ctd\u003eauto-derived from remove-bg\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-modify-fg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eModified line text (collapsed mode)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#f5c542\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-modify-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eModified line background (collapsed mode)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#3D2E00\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-tree-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFile tree pane background\u003c/td\u003e\n\u003ctd\u003eterminal default\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-diff-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDiff pane background\u003c/td\u003e\n\u003ctd\u003eterminal default\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-status-fg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eStatus bar foreground\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#202020\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-status-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eStatus bar background\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#C5794F\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-search-fg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSearch match text\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#1a1a1a\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e--color-search-bg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSearch match background\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e#4a4a00\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eAvailable chroma styles (click to expand)\u003c/summary\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eDark themes:\u003c/strong\u003e \u003ccode\u003eaura-theme-dark\u003c/code\u003e, \u003ccode\u003eaura-theme-dark-soft\u003c/code\u003e, \u003ccode\u003ebase16-snazzy\u003c/code\u003e, \u003ccode\u003ecatppuccin-frappe\u003c/code\u003e, \u003ccode\u003ecatppuccin-macchiato\u003c/code\u003e (default), \u003ccode\u003ecatppuccin-mocha\u003c/code\u003e, \u003ccode\u003edoom-one\u003c/code\u003e, \u003ccode\u003edoom-one2\u003c/code\u003e, \u003ccode\u003edracula\u003c/code\u003e, \u003ccode\u003eevergarden\u003c/code\u003e, \u003ccode\u003efruity\u003c/code\u003e, \u003ccode\u003egithub-dark\u003c/code\u003e, \u003ccode\u003egruvbox\u003c/code\u003e, \u003ccode\u003ehrdark\u003c/code\u003e, \u003ccode\u003emonokai\u003c/code\u003e, \u003ccode\u003emodus-vivendi\u003c/code\u003e, \u003ccode\u003enative\u003c/code\u003e, \u003ccode\u003enord\u003c/code\u003e, \u003ccode\u003enordic\u003c/code\u003e, \u003ccode\u003eonedark\u003c/code\u003e, \u003ccode\u003eparaiso-dark\u003c/code\u003e, \u003ccode\u003erose-pine\u003c/code\u003e, \u003ccode\u003erose-pine-moon\u003c/code\u003e, \u003ccode\u003errt\u003c/code\u003e, \u003ccode\u003esolarized-dark\u003c/code\u003e, \u003ccode\u003esolarized-dark256\u003c/code\u003e, \u003ccode\u003etokyonight-moon\u003c/code\u003e, \u003ccode\u003etokyonight-night\u003c/code\u003e, \u003ccode\u003etokyonight-storm\u003c/code\u003e, \u003ccode\u003evim\u003c/code\u003e, \u003ccode\u003evulcan\u003c/code\u003e, \u003ccode\u003ewitchhazel\u003c/code\u003e, \u003ccode\u003excode-dark\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eLight themes:\u003c/strong\u003e \u003ccode\u003eautumn\u003c/code\u003e, \u003ccode\u003eborland\u003c/code\u003e, \u003ccode\u003ecatppuccin-latte\u003c/code\u003e, \u003ccode\u003ecolorful\u003c/code\u003e, \u003ccode\u003eemacs\u003c/code\u003e, \u003ccode\u003efriendly\u003c/code\u003e, \u003ccode\u003egithub\u003c/code\u003e, \u003ccode\u003egruvbox-light\u003c/code\u003e, \u003ccode\u003eigor\u003c/code\u003e, \u003ccode\u003elovelace\u003c/code\u003e, \u003ccode\u003emanni\u003c/code\u003e, \u003ccode\u003emodus-operandi\u003c/code\u003e, \u003ccode\u003emonokailight\u003c/code\u003e, \u003ccode\u003emurphy\u003c/code\u003e, \u003ccode\u003eparaiso-light\u003c/code\u003e, \u003ccode\u003epastie\u003c/code\u003e, \u003ccode\u003eperldoc\u003c/code\u003e, \u003ccode\u003epygments\u003c/code\u003e, \u003ccode\u003erainbow_dash\u003c/code\u003e, \u003ccode\u003erose-pine-dawn\u003c/code\u003e, \u003ccode\u003esolarized-light\u003c/code\u003e, \u003ccode\u003etango\u003c/code\u003e, \u003ccode\u003etokyonight-day\u003c/code\u003e, \u003ccode\u003etrac\u003c/code\u003e, \u003ccode\u003evs\u003c/code\u003e, \u003ccode\u003excode\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eOther:\u003c/strong\u003e \u003ccode\u003eRPGLE\u003c/code\u003e, \u003ccode\u003eabap\u003c/code\u003e, \u003ccode\u003ealgol\u003c/code\u003e, \u003ccode\u003ealgol_nu\u003c/code\u003e, \u003ccode\u003earduino\u003c/code\u003e, \u003ccode\u003eashen\u003c/code\u003e, \u003ccode\u003eaverage\u003c/code\u003e, \u003ccode\u003ebw\u003c/code\u003e, \u003ccode\u003ehr_high_contrast\u003c/code\u003e, \u003ccode\u003eonesenterprise\u003c/code\u003e, \u003ccode\u003eswapoff\u003c/code\u003e\u003c/p\u003e\n\u003c/details\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExamples\u003c/h3\u003e\u003ca id=\"user-content-examples\" class=\"anchor\" aria-label=\"Permalink: Examples\" href=\"#examples\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# review uncommitted changes\nrevdiff\n\n# review changes against a branch\nrevdiff main\n\n# review staged changes\nrevdiff --staged\n\n# review last commit\nrevdiff HEAD~1 HEAD\n\n# diff between two refs\nrevdiff main feature\n\n# same with git dot-dot syntax\nrevdiff main..feature\n\n# review only specific files\nrevdiff --only=model.go --only=README.md\n\n# browse all git-tracked files in a project\nrevdiff --all-files\n\n# browse all files, excluding vendor and mocks directories\nrevdiff --all-files --exclude vendor --exclude mocks\n\n# include only src/ files\nrevdiff --include src\n\n# include src/ but exclude src/vendor/\nrevdiff --include src --exclude src/vendor\n\n# exclude paths in normal diff mode\nrevdiff main --exclude vendor\n\n# review a file outside a VCS repo (context-only, no diff markers)\nrevdiff --only=/tmp/plan.md\n\n# review a file that has no VCS changes (context-only view with annotations)\nrevdiff --only=docs/notes.txt\n\n# diff two arbitrary files (no VCS repo needed)\nrevdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md\n\n# review arbitrary piped text as a scratch buffer\nprintf '# Plan\\n\\nShip it\\n' | revdiff --stdin --stdin-name plan.md\n\n# capture annotations from generated output\nsome-command | revdiff --stdin --output /tmp/annotations.txt\n\n# round-trip: capture, edit externally, reload\nrevdiff -o review.md HEAD~1\n$EDITOR review.md\nrevdiff --annotations=review.md HEAD~1\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review uncommitted changes\u003c/span\u003e\nrevdiff\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review changes against a branch\u003c/span\u003e\nrevdiff main\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review staged changes\u003c/span\u003e\nrevdiff --staged\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review last commit\u003c/span\u003e\nrevdiff HEAD~1 HEAD\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e diff between two refs\u003c/span\u003e\nrevdiff main feature\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e same with git dot-dot syntax\u003c/span\u003e\nrevdiff main..feature\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review only specific files\u003c/span\u003e\nrevdiff --only=model.go --only=README.md\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e browse all git-tracked files in a project\u003c/span\u003e\nrevdiff --all-files\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e browse all files, excluding vendor and mocks directories\u003c/span\u003e\nrevdiff --all-files --exclude vendor --exclude mocks\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e include only src/ files\u003c/span\u003e\nrevdiff --include src\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e include src/ but exclude src/vendor/\u003c/span\u003e\nrevdiff --include src --exclude src/vendor\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e exclude paths in normal diff mode\u003c/span\u003e\nrevdiff main --exclude vendor\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review a file outside a VCS repo (context-only, no diff markers)\u003c/span\u003e\nrevdiff --only=/tmp/plan.md\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review a file that has no VCS changes (context-only view with annotations)\u003c/span\u003e\nrevdiff --only=docs/notes.txt\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e diff two arbitrary files (no VCS repo needed)\u003c/span\u003e\nrevdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e review arbitrary piped text as a scratch buffer\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003eprintf\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e# Plan\\n\\nShip it\\n\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e revdiff --stdin --stdin-name plan.md\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e capture annotations from generated output\u003c/span\u003e\nsome-command \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e revdiff --stdin --output /tmp/annotations.txt\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e round-trip: capture, edit externally, reload\u003c/span\u003e\nrevdiff -o review.md HEAD~1\n\u003cspan class=\"pl-smi\"\u003e$EDITOR\u003c/span\u003e review.md\nrevdiff --annotations=review.md HEAD~1\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e--annotations\u003c/code\u003e reads the same markdown format that \u003ccode\u003e-o\u003c/code\u003e writes (see \u003ca href=\"#output-format\"\u003eOutput Format\u003c/a\u003e below), so any file revdiff produces can be loaded back. You can also hand-author or generate that file from any other source — each record is \u003ccode\u003e## path/to/file.go:LINE (+)\u003c/code\u003e followed by the comment body — then step through the comments inline against the actual diff, edit or delete them in the TUI, and quit with \u003ccode\u003eq\u003c/code\u003e to write the final set to stdout (or to \u003ccode\u003e-o\u003c/code\u003e).\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAll-Files Mode\u003c/h3\u003e\u003ca id=\"user-content-all-files-mode\" class=\"anchor\" aria-label=\"Permalink: All-Files Mode\" href=\"#all-files-mode\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse \u003ccode\u003e--all-files\u003c/code\u003e (or \u003ccode\u003e-A\u003c/code\u003e) to browse all tracked files in a project, not just files with changes. This turns revdiff into a general-purpose code annotation tool. All files are shown in context-only mode (no \u003ccode\u003e+\u003c/code\u003e/\u003ccode\u003e-\u003c/code\u003e markers) with full annotation and syntax highlighting support.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e--all-files\u003c/code\u003e requires a git or jj repository (uses \u003ccode\u003egit ls-files\u003c/code\u003e or \u003ccode\u003ejj file list\u003c/code\u003e for file discovery) and is mutually exclusive with refs, \u003ccode\u003e--staged\u003c/code\u003e, and \u003ccode\u003e--only\u003c/code\u003e. Not supported in hg repos.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eCombine with \u003ccode\u003e--include\u003c/code\u003e (or \u003ccode\u003e-I\u003c/code\u003e) to narrow to specific paths and \u003ccode\u003e--exclude\u003c/code\u003e (or \u003ccode\u003e-X\u003c/code\u003e) to filter out unwanted paths:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"revdiff --all-files --include src\nrevdiff --all-files --include src --exclude src/vendor\nrevdiff --all-files --exclude vendor --exclude mocks\"\u003e\u003cpre\u003erevdiff --all-files --include src\nrevdiff --all-files --include src --exclude src/vendor\nrevdiff --all-files --exclude vendor --exclude mocks\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e--include\u003c/code\u003e and \u003ccode\u003e--exclude\u003c/code\u003e both use prefix matching: \u003ccode\u003e--include src\u003c/code\u003e keeps only \u003ccode\u003esrc/\u003c/code\u003e, \u003ccode\u003esrc/foo.go\u003c/code\u003e, etc. \u003ccode\u003e--exclude vendor\u003c/code\u003e skips \u003ccode\u003evendor/\u003c/code\u003e, \u003ccode\u003evendor/foo.go\u003c/code\u003e, etc. Both work in \u003ccode\u003e--all-files\u003c/code\u003e and normal diff modes and are composable: include narrows first, then exclude removes from the included set.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBoth options can be persisted in the config file:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ini notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"include = src\nexclude = vendor\nexclude = mocks\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003einclude\u003c/span\u003e = src\n\u003cspan class=\"pl-k\"\u003eexclude\u003c/span\u003e = vendor\n\u003cspan class=\"pl-k\"\u003eexclude\u003c/span\u003e = mocks\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOr via environment variables (comma-separated): \u003ccode\u003eREVDIFF_INCLUDE=src\u003c/code\u003e, \u003ccode\u003eREVDIFF_EXCLUDE=vendor,mocks\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eContext-Only File Review\u003c/h3\u003e\u003ca id=\"user-content-context-only-file-review\" class=\"anchor\" aria-label=\"Permalink: Context-Only File Review\" href=\"#context-only-file-review\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen \u003ccode\u003e--only\u003c/code\u003e specifies a file that has no VCS changes (or when no VCS repo exists at all), revdiff shows the file in context-only mode: all lines are displayed without \u003ccode\u003e+\u003c/code\u003e/\u003ccode\u003e-\u003c/code\u003e gutter markers, with full annotation and syntax highlighting support. This enables reviewing arbitrary files without requiring VCS context.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTwo scenarios trigger this mode:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eInside a repo (git/hg/jj)\u003c/strong\u003e - \u003ccode\u003e--only\u003c/code\u003e files not in the diff are read from disk and shown alongside any changed files\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOutside a VCS repo\u003c/strong\u003e - \u003ccode\u003e--only\u003c/code\u003e is required; files are read directly from disk\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTwo-File Diff\u003c/h3\u003e\u003ca id=\"user-content-two-file-diff\" class=\"anchor\" aria-label=\"Permalink: Two-File Diff\" href=\"#two-file-diff\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse \u003ccode\u003e--compare-old=\u0026lt;path\u0026gt;\u003c/code\u003e together with \u003ccode\u003e--compare-new=\u0026lt;path\u0026gt;\u003c/code\u003e to diff two arbitrary files on disk using \u003ccode\u003egit diff --no-index\u003c/code\u003e. No VCS repository is required — this works anywhere \u003ccode\u003egit\u003c/code\u003e is installed.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"revdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md\nrevdiff --compare-old=a.txt --compare-new=b.txt\"\u003e\u003cpre\u003erevdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md\nrevdiff --compare-old=a.txt --compare-new=b.txt\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e--compare-old\u003c/code\u003e and \u003ccode\u003e--compare-new\u003c/code\u003e must be used together and are mutually exclusive with refs, \u003ccode\u003e--staged\u003c/code\u003e, \u003ccode\u003e--only\u003c/code\u003e, \u003ccode\u003e--all-files\u003c/code\u003e, \u003ccode\u003e--stdin\u003c/code\u003e, \u003ccode\u003e--include\u003c/code\u003e, \u003ccode\u003e--exclude\u003c/code\u003e, and \u003ccode\u003e--annotations\u003c/code\u003e. All standard diff features work: word-diff, compact mode, syntax highlighting, scrollbar, and inline annotations.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eScratch-Buffer Review\u003c/h3\u003e\u003ca id=\"user-content-scratch-buffer-review\" class=\"anchor\" aria-label=\"Permalink: Scratch-Buffer Review\" href=\"#scratch-buffer-review\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse \u003ccode\u003e--stdin\u003c/code\u003e to review arbitrary piped or redirected text. revdiff sniffs the input for a git unified-diff signature: when a line beginning with \u003ccode\u003ediff --git a/\u003c/code\u003e is found near the start, the input is parsed as a real multi-file diff (one tree entry per file, with \u003ccode\u003e+\u003c/code\u003e/\u003ccode\u003e-\u003c/code\u003e markers, hunk navigation, word-diff, compact mode, and per-file annotations); otherwise the input is shown as a single context-only buffer with all lines as context, supporting annotations, file-level notes, search, wrap, collapsed mode, and structured output. Any per-section parse failure falls the whole input back to raw-text mode so a malformed patch never silently drops files. Input is capped at 64 MiB.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e--stdin\u003c/code\u003e is explicit and mutually exclusive with refs, \u003ccode\u003e--staged\u003c/code\u003e, \u003ccode\u003e--only\u003c/code\u003e, \u003ccode\u003e--all-files\u003c/code\u003e, \u003ccode\u003e--include\u003c/code\u003e, \u003ccode\u003e--exclude\u003c/code\u003e, and \u003ccode\u003e--annotations\u003c/code\u003e. stdin mode requires piped or redirected input; plain terminal stdin is rejected to avoid accidentally launching an empty scratch buffer.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eUse \u003ccode\u003e--stdin-name\u003c/code\u003e to control the synthetic filename for the context-only case (it is ignored in multi-file diff mode, where the tree shows the real paths). This gives annotation output a stable key and enables filename-based syntax highlighting or markdown TOC activation:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"echo \u0026quot;plain text\u0026quot; | revdiff --stdin\nprintf '# Plan\\n\\nBody\\n' | revdiff --stdin --stdin-name plan.md\ngit show HEAD~1:README.md | revdiff --stdin --stdin-name README.md\n\n# multi-file diff parsing — tree shows real paths, per-file annotations\ngh pr diff 123 | revdiff --stdin\ngit format-patch -1 --stdout | revdiff --stdin\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003eecho\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eplain text\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e revdiff --stdin\n\u003cspan class=\"pl-c1\"\u003eprintf\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e# Plan\\n\\nBody\\n\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e revdiff --stdin --stdin-name plan.md\ngit show HEAD~1:README.md \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e revdiff --stdin --stdin-name README.md\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e multi-file diff parsing — tree shows real paths, per-file annotations\u003c/span\u003e\ngh pr diff 123 \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e revdiff --stdin\ngit format-patch -1 --stdout \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e revdiff --stdin\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eReview Description\u003c/h3\u003e\u003ca id=\"user-content-review-description\" class=\"anchor\" aria-label=\"Permalink: Review Description\" href=\"#review-description\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse \u003ccode\u003e--description\u003c/code\u003e (or \u003ccode\u003e--description-file=path.md\u003c/code\u003e) to attach prose context to a review. The text is rendered at the top of the info popup (\u003ccode\u003ei\u003c/code\u003e key), with the same markdown highlighting used for \u003ccode\u003e.md\u003c/code\u003e files in the diff view. Useful when an agent (or a script) launches revdiff on your behalf and you come back to it later — the popup tells you what the change is and why.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"revdiff HEAD~3 --description=\u0026quot;# Refactor auth middleware\n\nDrop session-token storage to meet new compliance requirements.\nSee ticket SEC-441 for context.\u0026quot;\n\n# longer descriptions: keep the markdown in a file\nrevdiff HEAD~3 --description-file=.review-description.md\"\u003e\u003cpre\u003erevdiff HEAD~3 --description=\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e# Refactor auth middleware\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003eDrop session-token storage to meet new compliance requirements.\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003eSee ticket SEC-441 for context.\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e longer descriptions: keep the markdown in a file\u003c/span\u003e\nrevdiff HEAD~3 --description-file=.review-description.md\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e--description\u003c/code\u003e and \u003ccode\u003e--description-file\u003c/code\u003e are mutually exclusive. The description section is hidden when neither is set, so the flag is purely additive — existing invocations are unchanged.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMarkdown TOC Navigation\u003c/h3\u003e\u003ca id=\"user-content-markdown-toc-navigation\" class=\"anchor\" aria-label=\"Permalink: Markdown TOC Navigation\" href=\"#markdown-toc-navigation\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen reviewing a single markdown file in context-only mode (e.g., \u003ccode\u003erevdiff --only=README.md\u003c/code\u003e or \u003ccode\u003eprintf '# title\\n' | revdiff --stdin --stdin-name plan.md\u003c/code\u003e), revdiff shows a table-of-contents pane on the left listing all markdown headers. Use \u003ccode\u003eTab\u003c/code\u003e to switch focus between the TOC and diff panes, \u003ccode\u003ej\u003c/code\u003e/\u003ccode\u003ek\u003c/code\u003e to navigate headers, and \u003ccode\u003eEnter\u003c/code\u003e to jump to a header in the diff. The TOC automatically highlights the current section as you scroll through the file.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis mode activates when all three conditions are met: single file, markdown extension (\u003ccode\u003e.md\u003c/code\u003e/\u003ccode\u003e.markdown\u003c/code\u003e), and all lines are context (no diff changes). Headers inside fenced code blocks are excluded from the TOC.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eBeyond Code Review\u003c/h3\u003e\u003ca id=\"user-content-beyond-code-review\" class=\"anchor\" aria-label=\"Permalink: Beyond Code Review\" href=\"#beyond-code-review\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003e--only\u003c/code\u003e flag enables use cases beyond VCS diffs. Any text file can be loaded for annotation — no VCS repo required.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eReviewing AI-generated drafts\u003c/strong\u003e — When an AI assistant drafts text to be posted publicly (PR comments, issue responses, release notes), write it to a temp file and review in revdiff. Annotate specific lines with changes, the assistant reads annotations and rewrites, re-open to verify. Same annotate-fix-verify loop as code review.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eReviewing documentation and specs\u003c/strong\u003e — Markdown files, API specs, config files, and plan documents can all be reviewed with inline annotations. Useful for reviewing RFCs, annotating configs before deployment, or marking up plans with questions.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"revdiff --only=docs/plans/feature.md\nrevdiff --only=/tmp/draft-comment.md\"\u003e\u003cpre\u003erevdiff --only=docs/plans/feature.md\nrevdiff --only=/tmp/draft-comment.md\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eReviewing generated output\u003c/strong\u003e — CI configs, Terraform plans, generated migrations, or command output. Load files with \u003ccode\u003e--only\u003c/code\u003e or stream ephemeral output with \u003ccode\u003e--stdin\u003c/code\u003e, annotate what needs fixing, feed annotations back to the generator.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eZed Integration\u003c/h3\u003e\u003ca id=\"user-content-zed-integration\" class=\"anchor\" aria-label=\"Permalink: Zed Integration\" href=\"#zed-integration\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eZed's \u003ca href=\"https://zed.dev/docs/tasks\" rel=\"nofollow\"\u003ecustom tasks\u003c/a\u003e can launch revdiff directly in an editor terminal tab.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSee the \u003ca href=\"https://revdiff.com/docs.html#zed-integration\" rel=\"nofollow\"\u003eZed integration guide\u003c/a\u003e for ready-to-use task definitions, keybinding setup, and platform-specific clipboard notes.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eReview History\u003c/h3\u003e\u003ca id=\"user-content-review-history\" class=\"anchor\" aria-label=\"Permalink: Review History\" href=\"#review-history\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen you quit with annotations (\u003ccode\u003eq\u003c/code\u003e), revdiff automatically saves a copy of the review session to \u003ccode\u003e~/.config/revdiff/history/\u0026lt;repo-name\u0026gt;/\u0026lt;timestamp\u0026gt;.md\u003c/code\u003e. This is a safety net — if annotations are lost (process crash, agent fails to capture stdout), the history file preserves them.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eEach history file contains:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eHeader with path, refs, and (git only) a short commit hash\u003c/li\u003e\n\u003cli\u003eFull annotation output (same format as stdout)\u003c/li\u003e\n\u003cli\u003eRaw git diff for annotated files only\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eHistory auto-save is always on and silent — errors are logged to stderr, never fail the process. No history is saved on discard quit (\u003ccode\u003eQ\u003c/code\u003e) or when there are no annotations. For \u003ccode\u003e--stdin\u003c/code\u003e mode, files are saved under \u003ccode\u003estdin/\u003c/code\u003e subdirectory; for \u003ccode\u003e--only\u003c/code\u003e without git, the parent directory name is used instead of a repo name.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe history file is also a crash-recovery save when the process is terminated by a signal — a SIGHUP from a dropped SSH or tmux client, or a SIGTERM. On a signal exit only the history file is written, never the \u003ccode\u003e-o\u003c/code\u003e output, because a signal is not the deliberate handoff that \u003ccode\u003eq\u003c/code\u003e and \u003ccode\u003eO\u003c/code\u003e perform. Recover the annotations the usual way — load the newest history file. A signal-delivered SIGTERM previously wrote the \u003ccode\u003e-o\u003c/code\u003e output; it no longer does.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOverride the history directory with \u003ccode\u003e--history-dir\u003c/code\u003e, \u003ccode\u003eREVDIFF_HISTORY_DIR\u003c/code\u003e env var, or \u003ccode\u003ehistory-dir\u003c/code\u003e in the config file.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn the Claude Code and Codex plugins, you can also tell the agent to use a past review by saying things like \"locate my latest revdiff review\" or \"use the annotations from the review I just did in another terminal\". The plugin reads the newest history file for the current repo via the helper script \u003ccode\u003eread-latest-history.sh\u003c/code\u003e and processes the annotations as if they had come from a fresh launcher call. This is useful for standalone revdiff runs outside the plugin, or when the live launcher output is unavailable (e.g., a broken custom launcher or a crashed agent).\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eKey Bindings\u003c/h3\u003e\u003ca id=\"user-content-key-bindings\" class=\"anchor\" aria-label=\"Permalink: Key Bindings\" href=\"#key-bindings\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNavigation:\u003c/strong\u003e\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eKey\u003c/th\u003e\n\u003cth\u003eAction\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ej/k\u003c/code\u003e or up/down\u003c/td\u003e\n\u003ctd\u003eNavigate files (tree) / scroll diff (diff pane); with \u003ccode\u003e--cross-file-motion\u003c/code\u003e, continues to the previous/next file at the boundary\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eh/l\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSwitch between file tree and diff pane\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eleft/right\u003c/td\u003e\n\u003ctd\u003eHorizontal scroll in diff pane (truncated lines show \u003ccode\u003e«\u003c/code\u003e / \u003ccode\u003e»\u003c/code\u003e overflow indicators at the edges)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eTab\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSwitch between file tree and diff pane\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ePgDown/PgUp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePage scroll in file tree and diff pane; with \u003ccode\u003e--cross-file-motion\u003c/code\u003e, continues to the previous/next file at the boundary\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eCtrl+d/Ctrl+u\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eHalf-page scroll in file tree and diff pane; with \u003ccode\u003e--cross-file-motion\u003c/code\u003e, continues to the previous/next file at the boundary\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eJ/K\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eScroll diff viewport (works from either pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eHome/End\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eJump to first/last item\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eEnter\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSwitch to diff pane (tree) / start annotation (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003en/p\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNext/previous changed file; next/prev header in markdown TOC mode (n = next match when search active)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eP\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOpen the file picker\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e[\u003c/code\u003e / \u003ccode\u003e]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eJump to previous/next change hunk in diff; add \u003ccode\u003e--cross-file-hunks\u003c/code\u003e to continue into the previous/next file at the boundary\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ee\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOpen focused file in \u003ccode\u003e$EDITOR\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003eThe file picker lists paths currently visible in the sidebar, so annotated-only and unreviewed-only filters remain active. Printable keys always filter full relative paths; use the arrow keys or mouse wheel to move, and press \u003ccode\u003eEnter\u003c/code\u003e or left-click to jump. \u003ccode\u003eBackspace\u003c/code\u003e edits the filter. The first \u003ccode\u003eEsc\u003c/code\u003e clears a non-empty filter and keeps the picker open; the second closes it. Because printable keys always filter, \u003ccode\u003eP\u003c/code\u003e typed inside the picker adds to the filter rather than closing it; a \u003ccode\u003ejump_file\u003c/code\u003e binding with a modifier (e.g. \u003ccode\u003emap alt+f jump_file\u003c/code\u003e) closes the picker when pressed again.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eSearch:\u003c/strong\u003e\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eKey\u003c/th\u003e\n\u003cth\u003eAction\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eStart search in diff pane\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003en\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNext search match (overrides next file when search active)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eN\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePrevious file (previous search match when searching)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e↑\u003c/code\u003e / \u003ccode\u003eCtrl+P\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRecall previous search query (in search prompt)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e↓\u003c/code\u003e / \u003ccode\u003eCtrl+N\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRecall next search query / clear (in search prompt)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eEsc\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCancel search input / clear search results\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eAnnotations:\u003c/strong\u003e\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eKey\u003c/th\u003e\n\u003cth\u003eAction\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ea\u003c/code\u003e or \u003ccode\u003eEnter\u003c/code\u003e (diff pane)\u003c/td\u003e\n\u003ctd\u003eAnnotate current diff line\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eA\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAdd file-level annotation (stored at top of diff)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e@\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle annotation list popup (navigate and jump to any annotation)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e}\u003c/code\u003e / \u003ccode\u003e{\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eJump to next/previous annotation (always crosses file boundaries; silent no-op at the first/last annotation)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ed\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDelete annotation under cursor\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eO\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eExport annotations without exiting (requires \u003ccode\u003e--output\u003c/code\u003e and/or \u003ccode\u003e--post-flush-command\u003c/code\u003e)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eCtrl+E\u003c/code\u003e (during annotation input)\u003c/td\u003e\n\u003ctd\u003eOpen \u003ccode\u003e$EDITOR\u003c/code\u003e for multi-line annotation (\u003ccode\u003eopen_editor\u003c/code\u003e — rebindable)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eEsc\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCancel annotation input\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003eWhile the annotation input is active, press \u003ccode\u003eCtrl+E\u003c/code\u003e (or whatever key is bound to \u003ccode\u003eopen_editor\u003c/code\u003e) to hand off the current text to an external editor for multi-line comments. Editor resolution: \u003ccode\u003e$EDITOR\u003c/code\u003e → \u003ccode\u003e$VISUAL\u003c/code\u003e → \u003ccode\u003evi\u003c/code\u003e. Values with arguments work (e.g. \u003ccode\u003eEDITOR=\"code --wait\"\u003c/code\u003e). On editor save and quit, the full file contents (including newlines) become the annotation. Quitting the editor with an empty file cancels the annotation and preserves any previously stored note on that line. Multi-line annotations are rendered line-by-line in the diff view, shown flattened in the annotation list popup (\u003ccode\u003e@\u003c/code\u003e), and emitted with embedded newlines in the structured output.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003ePress \u003ccode\u003ee\u003c/code\u003e in the diff pane to open the focused file in \u003ccode\u003e$EDITOR\u003c/code\u003e (\u003ccode\u003eopen_file_in_editor\u003c/code\u003e — rebindable) when revdiff has a stable source path. Editor resolution is the same \u003ccode\u003e$EDITOR\u003c/code\u003e → \u003ccode\u003e$VISUAL\u003c/code\u003e → \u003ccode\u003evi\u003c/code\u003e chain. Known editors receive either \u003ccode\u003e$EDITOR +N path\u003c/code\u003e or \u003ccode\u003e$EDITOR --goto path:N\u003c/code\u003e as appropriate; unknown editors receive only the file path. File lines are resolved on a best-effort basis. For working tree changes, a clean editor exit reloads the displayed file. For \u003ccode\u003e--staged\u003c/code\u003e or refs, a clean editor exit returns to revdiff without reloading the displayed diff. In compare mode, \u003ccode\u003ee\u003c/code\u003e opens the \u003ccode\u003e--compare-new\u003c/code\u003e side. Working tree files with line annotations cannot be opened for editing because edits can orphan those annotations. Diffs read with \u003ccode\u003e--stdin\u003c/code\u003e do not support opening files. Unsupported rows or files and editor errors show a status hint instead of launching an editor or changing the diff.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003ePress \u003ccode\u003eO\u003c/code\u003e to export the current annotations without exiting (\u003ccode\u003eflush_output\u003c/code\u003e, rebindable). Configure \u003ccode\u003e--output\u003c/code\u003e, \u003ccode\u003e--post-flush-command\u003c/code\u003e, or both. With \u003ccode\u003e--output\u003c/code\u003e, each flush atomically overwrites the file with the full current annotation set (a snapshot, not an append log). With \u003ccode\u003e--post-flush-command\u003c/code\u003e, the same snapshot is sent to the command on stdin. If neither is configured, or if there are no annotations, revdiff shows a status hint and does nothing.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe output file supports a keep-open review loop with an AI agent: annotate, flush with \u003ccode\u003eO\u003c/code\u003e, let the agent read the file and edit code, then reload with \u003ccode\u003eR\u003c/code\u003e and continue in the same session.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor a local clipboard-only workflow on macOS, set this in \u003ccode\u003e~/.config/revdiff/config\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ini notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"post-flush-command = pbcopy\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003epost-flush-command\u003c/span\u003e = pbcopy\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eEach \u003ccode\u003eO\u003c/code\u003e copies the full current annotation set without requiring \u003ccode\u003e--output\u003c/code\u003e. On Linux, use \u003ccode\u003exclip -selection clipboard\u003c/code\u003e for X11 or \u003ccode\u003ewl-copy\u003c/code\u003e for Wayland.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor a terminal clipboard over SSH or a multiplexer, use OSC 52. revdiff does not include an OSC 52 helper; create an \u003ccode\u003eosc-copy\u003c/code\u003e shell script on your \u003ccode\u003ePATH\u003c/code\u003e that reads stdin and writes the clipboard sequence to \u003ccode\u003e/dev/tty\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#!/bin/sh\ndata=$(base64 | tr -d '\\n')\nprintf '\\033]52;c;%s\\007' \u0026quot;$data\u0026quot; \u0026gt; /dev/tty\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#!\u003c/span\u003e/bin/sh\u003c/span\u003e\ndata=\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e$(\u003c/span\u003ebase64 \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e tr -d \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\\n\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003eprintf\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\\033]52;c;%s\\007\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$data\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e\u0026gt;\u003c/span\u003e /dev/tty\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAfter making the script executable, run revdiff with \u003ccode\u003e--post-flush-command=osc-copy\u003c/code\u003e or set \u003ccode\u003epost-flush-command = osc-copy\u003c/code\u003e in the config file. No output file is required; add \u003ccode\u003e--output\u003c/code\u003e only when the same flush should also write a snapshot file.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe post-flush command runs synchronously. Use a fast, non-interactive command because revdiff waits for it to finish before restoring the TUI.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003ePress \u003ccode\u003eSpace\u003c/code\u003e to mark the focused file reviewed. Press \u003ccode\u003eF\u003c/code\u003e to toggle the sidebar between all files and unreviewed files; while filtered, marking a file reviewed removes it from the list and advances to the next unfinished file. On \u003ccode\u003eR\u003c/code\u003e reload, revdiff keeps the mark only when the file's effective text diff is unchanged; rebases that only shift line numbers or surrounding context keep it, while changed or removed files lose it. Binary files and opaque placeholders are conservatively unmarked on reload because their rendered diff does not expose enough content to prove they are unchanged.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eView:\u003c/strong\u003e\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eKey\u003c/th\u003e\n\u003cth\u003eAction\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ev\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle collapsed diff mode (shows final text with change markers)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eC\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle compact diff view (small context around changes, re-fetches current file)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ew\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle word wrap (long lines wrap with \u003ccode\u003e↪\u003c/code\u003e continuation markers)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003et\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle tree/TOC pane visibility (gives diff full terminal width)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eL\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle line numbers (side-by-side old/new for diffs, single column for full-context files)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eB\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle blame gutter (author name + commit age per line)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eW\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle intra-line word-diff highlighting for paired add/remove lines\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e.\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eExpand/collapse individual hunk under cursor (collapsed mode only)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOpen theme selector with live preview\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ef\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle filter: all files / annotated only (shown when annotations exist)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eF\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle filter: all files / unreviewed only\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e?\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle help overlay showing all keybindings\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ei\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eToggle info popup — review scope (mode, VCS, ref, filters, file/status counts, aggregate \u003ccode\u003e+/-\u003c/code\u003e stats) plus the commit log for the current ref range when applicable\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eR\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eReload diff from VCS (warns if annotations exist)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eq\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eQuit, output annotations to stdout\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eQ\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDiscard all annotations and quit (confirms if annotations exist)\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eStatus Bar Icons\u003c/h3\u003e\u003ca id=\"user-content-status-bar-icons\" class=\"anchor\" aria-label=\"Permalink: Status Bar Icons\" href=\"#status-bar-icons\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe status bar shows a fixed row of mode indicators on the right side. All slots are always rendered — active modes use the status bar foreground color, inactive modes use muted gray, so the row occupies the same width regardless of what's toggled on. The help overlay (\u003ccode\u003e?\u003c/code\u003e) shows each icon beside the key that controls it.\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eIcon\u003c/th\u003e\n\u003cth\u003eToggle\u003c/th\u003e\n\u003cth\u003eMeaning\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e▼\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ev\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCollapsed diff mode\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e⊂\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eC\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCompact diff mode (small context around changes)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e◉\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ef\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFilter: annotated files only\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e↩\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ew\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eWord wrap mode\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e≋\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003e/\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSearch active\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e⊟\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003et\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eTree/TOC pane hidden (diff uses full width)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e#\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eL\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eLine numbers visible in gutter\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eb\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eB\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eBlame gutter visible\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e±\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eW\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eIntra-line word-diff highlighting\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e✓\u003c/code\u003e / \u003ccode\u003e○\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eSpace\u003c/code\u003e / \u003ccode\u003eF\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eReviewed files / unreviewed-only filter active\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e∅\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eu\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eUntracked files visible in tree\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003eOn narrow terminals, the left-hand segments are dropped before the icons: search position first, then line and hunk info, then the filename truncates. The icon row on the right stays put.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMouse Support\u003c/h3\u003e\u003ca id=\"user-content-mouse-support\" class=\"anchor\" aria-label=\"Permalink: Mouse Support\" href=\"#mouse-support\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003erevdiff enables mouse tracking by default so the scroll wheel and left-click work consistently across terminals.\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eScroll wheel\u003c/strong\u003e: scrolls whichever pane the cursor is over. In the tree/TOC pane the wheel moves the cursor one entry per notch (matches \u003ccode\u003ej\u003c/code\u003e/\u003ccode\u003ek\u003c/code\u003e). In the diff pane the wheel scrolls the viewport by three lines per notch — the diff cursor stays on its current logical line and is pinned to the visible edge if scrolling pushes it off-screen. During fast scrolls (a trackpad flick) the cursor highlight catches up after a brief pause once the burst settles, matching less/vim behavior.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eShift+scroll\u003c/strong\u003e: half-page scroll in the diff pane. In the tree/TOC pane Shift+wheel behaves the same as plain wheel (one entry per notch — no page step).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLeft-click in the tree\u003c/strong\u003e: focuses the tree and selects/loads the clicked entry (same as pressing \u003ccode\u003ej\u003c/code\u003e/\u003ccode\u003ek\u003c/code\u003e to land there). Clicking a directory row moves the cursor but does not load a file.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLeft-click in the diff\u003c/strong\u003e: focuses the diff and moves the cursor to the clicked line. Enables a \"click, then \u003ccode\u003ea\u003c/code\u003e\" annotation flow.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLeft-click in the TOC pane\u003c/strong\u003e (single-file markdown): focuses the TOC and selects the clicked header.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eScroll wheel in overlay popups\u003c/strong\u003e (info, annotations, themes, help): scrolls the popup content or moves its cursor. Shift+wheel uses a half-page step. In the theme selector, wheel previews each theme live.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLeft-click in the annotation popup\u003c/strong\u003e: jumps to the clicked annotation (same as pressing \u003ccode\u003eEnter\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLeft-click in the theme popup\u003c/strong\u003e: confirms the clicked theme (same as pressing \u003ccode\u003eEnter\u003c/code\u003e). Clicks on the filter row or blank separator are ignored.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLeft-click in the file picker\u003c/strong\u003e: jumps to the clicked file (same as pressing \u003ccode\u003eEnter\u003c/code\u003e). Clicks on the filter row or blank separator are ignored.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eScroll wheel in the file picker\u003c/strong\u003e: moves the picker cursor. Shift+wheel uses a half-page step.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eHorizontal wheel, right-click, middle-click, drag selection, and clicks on the status bar or diff header are intentionally ignored. Clicks outside an open overlay are swallowed — dismiss an overlay with \u003ccode\u003eEsc\u003c/code\u003e or its toggle key. Modal states (annotation input, search input, confirm discard, reload confirm) swallow mouse events entirely.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eText selection trade-off\u003c/strong\u003e — once mouse tracking is on, plain drag is captured by revdiff. For terminal-native text selection:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003ekitty\u003c/strong\u003e: hold \u003ccode\u003eCtrl+Shift\u003c/code\u003e while dragging\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eiTerm2\u003c/strong\u003e: hold \u003ccode\u003eOption\u003c/code\u003e while dragging\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eghostty\u003c/strong\u003e (and ghostty-based terminals such as agterm): hold \u003ccode\u003eShift\u003c/code\u003e while dragging. Ghostty also uses \u003ccode\u003eShift\u003c/code\u003e to \u003cem\u003eextend\u003c/em\u003e an existing selection, so if text is already selected the drag grows that selection instead of starting a new one - clear it first. Ghostty 1.3.0+ additionally has a \u003ccode\u003etoggle_mouse_reporting\u003c/code\u003e keybind, unbound by default, which suspends mouse capture without restarting revdiff\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003emost other terminals\u003c/strong\u003e: hold \u003ccode\u003eShift\u003c/code\u003e while dragging\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eBecause the tree pane is rendered alongside the diff on the same rows, multi-line Shift+drag will include tree content. For clean copies of diff text, use your terminal's block-select mode (Option+drag in iTerm2, Ctrl+Shift+drag in kitty) or run with \u003ccode\u003e--no-mouse\u003c/code\u003e to disable mouse capture entirely.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOpt out with \u003ccode\u003e--no-mouse\u003c/code\u003e, \u003ccode\u003eREVDIFF_NO_MOUSE=true\u003c/code\u003e, or \u003ccode\u003eno-mouse = true\u003c/code\u003e in the config file.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCustom Keybindings\u003c/h3\u003e\u003ca id=\"user-content-custom-keybindings\" class=\"anchor\" aria-label=\"Permalink: Custom Keybindings\" href=\"#custom-keybindings\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll keybindings can be customized via a keybindings file at \u003ccode\u003e~/.config/revdiff/keybindings\u003c/code\u003e. Override the path with \u003ccode\u003e--keys\u003c/code\u003e flag or \u003ccode\u003eREVDIFF_KEYS\u003c/code\u003e env var.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe file uses a simple \u003ccode\u003emap\u003c/code\u003e/\u003ccode\u003eunmap\u003c/code\u003e format (blank lines and \u003ccode\u003e#\u003c/code\u003e comments are ignored):\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"# ~/.config/revdiff/keybindings\nmap ctrl+d half_page_down\nmap ctrl+u half_page_up\nmap x quit\nunmap q\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e# ~/.config/revdiff/keybindings\nmap ctrl+d half_page_down\nmap ctrl+u half_page_up\nmap x quit\nunmap q\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003emap \u0026lt;key\u0026gt; \u0026lt;action\u0026gt;\u003c/code\u003e — binds a key to an action (additive, defaults are kept unless explicitly unmapped)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eunmap \u0026lt;key\u0026gt;\u003c/code\u003e — removes a default binding\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eGenerate a template with all current bindings:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"mkdir -p ~/.config/revdiff\nrevdiff --dump-keys \u0026gt; ~/.config/revdiff/keybindings\"\u003e\u003cpre\u003emkdir -p \u003cspan class=\"pl-k\"\u003e~\u003c/span\u003e/.config/revdiff\nrevdiff --dump-keys \u003cspan class=\"pl-k\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e~\u003c/span\u003e/.config/revdiff/keybindings\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThen edit to taste. Fixed modal keys (Enter, Esc in annotation/search input, confirm discard) are not remappable. Keymap-resolved actions like \u003ccode\u003eopen_editor\u003c/code\u003e work during annotation input and can be rebound.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePaging the diff from the file tree:\u003c/strong\u003e \u003ccode\u003eJ\u003c/code\u003e/\u003ccode\u003eK\u003c/code\u003e scroll the diff viewport from either pane, but only by a few lines, while \u003ccode\u003ePgDown\u003c/code\u003e/\u003ccode\u003ePgUp\u003c/code\u003e and \u003ccode\u003eCtrl+d\u003c/code\u003e/\u003ccode\u003eCtrl+u\u003c/code\u003e stay pane-relative and page whichever pane has focus. The \u003ccode\u003escroll_diff_page_*\u003c/code\u003e and \u003ccode\u003escroll_diff_half_page_*\u003c/code\u003e actions are the page-sized versions of \u003ccode\u003eJ\u003c/code\u003e/\u003ccode\u003eK\u003c/code\u003e — they ship with no default key, so bind them to get lazygit-style paging that always targets the diff:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"map pgdown scroll_diff_page_down\nmap pgup scroll_diff_page_up\nmap ctrl+d scroll_diff_half_page_down\nmap ctrl+u scroll_diff_half_page_up\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003emap pgdown scroll_diff_page_down\nmap pgup scroll_diff_page_up\nmap ctrl+d scroll_diff_half_page_down\nmap ctrl+u scroll_diff_half_page_up\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThree consequences worth knowing. This also replaces cursor paging while the diff pane has focus: the keys scroll the viewport and pin the cursor back into view instead of walking the cursor a page at a time. The file tree and markdown TOC lose their own page-sized traversal on those keys. And because \u003ccode\u003epage_down\u003c/code\u003e, \u003ccode\u003epage_up\u003c/code\u003e, \u003ccode\u003ehalf_page_down\u003c/code\u003e and \u003ccode\u003ehalf_page_up\u003c/code\u003e have no other default key, rebinding all four lines leaves them unbound everywhere, including the \u003ccode\u003e?\u003c/code\u003e help and \u003ccode\u003ei\u003c/code\u003e info overlays, which page through the same actions. Omit one pair of mapping lines to keep its default paging. Because they have no default binding, these actions appear in neither the \u003ccode\u003e?\u003c/code\u003e help overlay nor \u003ccode\u003e--dump-keys\u003c/code\u003e until you bind them.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eChord bindings (ctrl/alt leader):\u003c/strong\u003e bind a two-stage chord by joining the leader and second key with \u003ccode\u003e\u0026gt;\u003c/code\u003e. The leader must be a \u003ccode\u003ectrl+*\u003c/code\u003e or \u003ccode\u003ealt+*\u003c/code\u003e combo; the second stage is any single key. Only two stages are supported.\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"map ctrl+w\u0026gt;x mark_reviewed\nmap alt+t\u0026gt;n theme_select\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003emap ctrl+w\u0026gt;x mark_reviewed\nmap alt+t\u0026gt;n theme_select\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen the leader is pressed, the status bar shows \u003ccode\u003ePending: ctrl+w, esc to cancel\u003c/code\u003e; press the second key to dispatch, or \u003ccode\u003eesc\u003c/code\u003e to cancel silently. Binding a key as both a standalone action and a chord prefix drops the standalone binding (the chord wins, with a warning). Chord bindings work under non-Latin keyboard layouts — the second-stage key is translated via the same layout-resolve fallback as single-key bindings. Note: chord bindings do not fire during text input (annotation and search prompts) — the leader key is consumed by the text input widget. Use single-key \u003ccode\u003ectrl+*\u003c/code\u003e bindings for actions like \u003ccode\u003eopen_editor\u003c/code\u003e that need to work during annotation input.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003emacOS note:\u003c/strong\u003e \u003ccode\u003ealt+*\u003c/code\u003e leaders require your terminal to send Option as Meta/Alt. Most terminals default to \"Option composes special characters\" (e.g. \u003ccode\u003eOption+T\u003c/code\u003e → \u003ccode\u003e†\u003c/code\u003e), in which case Alt chords silently won't fire. To enable: iTerm2 → \u003cem\u003eProfiles → Keys → Left/Right Option key → \u003ccode\u003eEsc+\u003c/code\u003e\u003c/em\u003e; Terminal.app → \u003cem\u003eProfiles → Keyboard → Use Option as Meta key\u003c/em\u003e; Kitty → \u003ccode\u003emacos_option_as_alt yes\u003c/code\u003e; Ghostty → \u003ccode\u003emacos-option-as-alt = true\u003c/code\u003e. If you'd rather not touch terminal settings, use \u003ccode\u003ectrl+*\u003c/code\u003e leaders — those work everywhere with no configuration.\u003c/p\u003e\n\u003cdetails\u003e\n\u003csummary\u003eAvailable actions (click to expand)\u003c/summary\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNavigation:\u003c/strong\u003e \u003ccode\u003edown\u003c/code\u003e, \u003ccode\u003eup\u003c/code\u003e, \u003ccode\u003epage_down\u003c/code\u003e, \u003ccode\u003epage_up\u003c/code\u003e, \u003ccode\u003ehalf_page_down\u003c/code\u003e, \u003ccode\u003ehalf_page_up\u003c/code\u003e, \u003ccode\u003ehome\u003c/code\u003e, \u003ccode\u003eend\u003c/code\u003e, \u003ccode\u003escroll_left\u003c/code\u003e, \u003ccode\u003escroll_right\u003c/code\u003e, \u003ccode\u003escroll_center\u003c/code\u003e, \u003ccode\u003escroll_top\u003c/code\u003e, \u003ccode\u003escroll_bottom\u003c/code\u003e, \u003ccode\u003escroll_diff_down\u003c/code\u003e, \u003ccode\u003escroll_diff_up\u003c/code\u003e, \u003ccode\u003escroll_diff_page_down\u003c/code\u003e, \u003ccode\u003escroll_diff_page_up\u003c/code\u003e, \u003ccode\u003escroll_diff_half_page_down\u003c/code\u003e, \u003ccode\u003escroll_diff_half_page_up\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eFile/Hunk:\u003c/strong\u003e \u003ccode\u003enext_item\u003c/code\u003e, \u003ccode\u003eprev_item\u003c/code\u003e, \u003ccode\u003ejump_file\u003c/code\u003e, \u003ccode\u003enext_hunk\u003c/code\u003e, \u003ccode\u003eprev_hunk\u003c/code\u003e, \u003ccode\u003eopen_file_in_editor\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePane:\u003c/strong\u003e \u003ccode\u003etoggle_pane\u003c/code\u003e, \u003ccode\u003efocus_tree\u003c/code\u003e, \u003ccode\u003efocus_diff\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eSearch:\u003c/strong\u003e \u003ccode\u003esearch\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eAnnotations:\u003c/strong\u003e \u003ccode\u003econfirm\u003c/code\u003e (annotate line / select file), \u003ccode\u003eannotate_file\u003c/code\u003e, \u003ccode\u003edelete_annotation\u003c/code\u003e, \u003ccode\u003eannot_list\u003c/code\u003e, \u003ccode\u003eopen_editor\u003c/code\u003e, \u003ccode\u003enext_annotation\u003c/code\u003e, \u003ccode\u003eprev_annotation\u003c/code\u003e, \u003ccode\u003eflush_output\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eView:\u003c/strong\u003e \u003ccode\u003etoggle_collapsed\u003c/code\u003e, \u003ccode\u003etoggle_compact\u003c/code\u003e, \u003ccode\u003etoggle_wrap\u003c/code\u003e, \u003ccode\u003etoggle_tree\u003c/code\u003e, \u003ccode\u003etoggle_line_numbers\u003c/code\u003e, \u003ccode\u003etoggle_blame\u003c/code\u003e, \u003ccode\u003etoggle_word_diff\u003c/code\u003e, \u003ccode\u003etoggle_hunk\u003c/code\u003e, \u003ccode\u003etoggle_untracked\u003c/code\u003e, \u003ccode\u003emark_reviewed\u003c/code\u003e, \u003ccode\u003efilter_unreviewed\u003c/code\u003e, \u003ccode\u003etheme_select\u003c/code\u003e, \u003ccode\u003efilter\u003c/code\u003e, \u003ccode\u003einfo\u003c/code\u003e, \u003ccode\u003ereload\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eQuit:\u003c/strong\u003e \u003ccode\u003equit\u003c/code\u003e, \u003ccode\u003ediscard_quit\u003c/code\u003e, \u003ccode\u003ehelp\u003c/code\u003e, \u003ccode\u003edismiss\u003c/code\u003e\u003c/p\u003e\n\u003c/details\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVim-motion Preset\u003c/h3\u003e\u003ca id=\"user-content-vim-motion-preset\" class=\"anchor\" aria-label=\"Permalink: Vim-motion Preset\" href=\"#vim-motion-preset\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOpt-in vim-style motion layer activated via \u003ccode\u003e--vim-motion\u003c/code\u003e, \u003ccode\u003eREVDIFF_VIM_MOTION=true\u003c/code\u003e, or \u003ccode\u003evim-motion = true\u003c/code\u003e in the config file. Off by default — when off, existing single-key bindings are unchanged.\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eKeys\u003c/th\u003e\n\u003cth\u003eAction\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\u0026lt;N\u0026gt;j\u003c/code\u003e / \u003ccode\u003e\u0026lt;N\u0026gt;k\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eMove cursor N lines down/up (diff pane, 1-9999)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003egg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eJump to first line (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eG\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eJump to last line (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\u0026lt;N\u0026gt;G\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eGoto line N (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eH\u003c/code\u003e / \u003ccode\u003e\u0026lt;N\u0026gt;H\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCursor to top of screen / Nth line from top (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eM\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCursor to middle of screen (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eL\u003c/code\u003e / \u003ccode\u003e\u0026lt;N\u0026gt;L\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCursor to bottom of screen / Nth line from bottom (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ezz\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCenter viewport on cursor (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ezt\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAlign viewport top on cursor (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ezb\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAlign viewport bottom on cursor (diff pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eZZ\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eQuit (any pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eZQ\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDiscard annotations and quit (any pane)\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003eWhen the preset is on, the digits \u003ccode\u003e0\u003c/code\u003e-\u003ccode\u003e9\u003c/code\u003e and the leader keys \u003ccode\u003eg\u003c/code\u003e, \u003ccode\u003ez\u003c/code\u003e, \u003ccode\u003eZ\u003c/code\u003e are intercepted before the regular keymap, so any standalone binding on those keys is overridden while the flag is active. \u003ccode\u003e\u0026lt;N\u0026gt;j\u003c/code\u003e/\u003ccode\u003e\u0026lt;N\u0026gt;k\u003c/code\u003e/\u003ccode\u003e\u0026lt;N\u0026gt;G\u003c/code\u003e, \u003ccode\u003egg\u003c/code\u003e/\u003ccode\u003ezz\u003c/code\u003e/\u003ccode\u003ezt\u003c/code\u003e/\u003ccode\u003ezb\u003c/code\u003e, and the screen-position motions \u003ccode\u003eH\u003c/code\u003e/\u003ccode\u003eM\u003c/code\u003e/\u003ccode\u003eL\u003c/code\u003e apply to the diff pane only — in the file tree they fall through to the normal bindings. \u003ccode\u003eZZ\u003c/code\u003e and \u003ccode\u003eZQ\u003c/code\u003e work from any pane. While the preset is active \u003ccode\u003eL\u003c/code\u003e is a screen-position motion rather than the line-numbers toggle (\u003ccode\u003etoggle_line_numbers\u003c/code\u003e); remap it in the keybindings file if you need both. Press \u003ccode\u003eEsc\u003c/code\u003e to silently cancel a pending leader; an unknown second key surfaces a transient \u003ccode\u003eUnknown: \u0026lt;chord\u0026gt;\u003c/code\u003e hint in the status bar. A bare digit \u003ccode\u003e0\u003c/code\u003e is not consumed (falls through to whatever binding is mapped); counts over 9999 are clamped. Modal keys (search input, annotation input, overlay navigation) always take precedence over the interceptor, and \u003ccode\u003ectrl+*\u003c/code\u003e/\u003ccode\u003ealt+*\u003c/code\u003e chord bindings keep working orthogonally.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe help overlay (\u003ccode\u003e?\u003c/code\u003e) shows a dedicated \u003cstrong\u003eVim motion\u003c/strong\u003e section listing all eleven preset bindings when \u003ccode\u003e--vim-motion\u003c/code\u003e is on; when off, the section is hidden.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eOutput Format\u003c/h3\u003e\u003ca id=\"user-content-output-format\" class=\"anchor\" aria-label=\"Permalink: Output Format\" href=\"#output-format\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"## handler.go (file-level)\nconsider splitting this file into smaller modules\n\n## handler.go:43 (+)\nuse errors.Is() instead of direct comparison\n\n## handler.go:43-67 (+)\nrefactor this hunk to reduce nesting\n\n## store.go:18 (-)\ndon't remove this validation\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e## handler.go (file-level)\nconsider splitting this file into smaller modules\n\n## handler.go:43 (+)\nuse errors.Is() instead of direct comparison\n\n## handler.go:43-67 (+)\nrefactor this hunk to reduce nesting\n\n## store.go:18 (-)\ndon't remove this validation\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen annotation text contains the keyword \"hunk\" (case-insensitive, whole word), the output header automatically expands to include the full hunk line range (e.g., \u003ccode\u003ehandler.go:43-67 (+)\u003c/code\u003e instead of \u003ccode\u003ehandler.go:43 (+)\u003c/code\u003e). This gives AI consumers the range context without any extra steps.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eComment body lines starting with \u003ccode\u003e## \u003c/code\u003e (the record-header form) are prefixed with a single space on output so parsers that split on \u003ccode\u003e## \u003c/code\u003e record headers cannot confuse a multi-line comment for a new record.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eContributing\u003c/h2\u003e\u003ca id=\"user-content-contributing\" class=\"anchor\" aria-label=\"Permalink: Contributing\" href=\"#contributing\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSee \u003ca href=\"/umputun/revdiff/blob/master/CONTRIBUTING.md\"\u003eCONTRIBUTING.md\u003c/a\u003e for details.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLicense\u003c/h2\u003e\u003ca id=\"user-content-license\" class=\"anchor\" aria-label=\"Permalink: License\" href=\"#license\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMIT License - see \u003ca href=\"/umputun/revdiff/blob/master/LICENSE\"\u003eLICENSE\u003c/a\u003e file for details.\u003c/p\u003e\n\u003c/article\u003e","richTextTruncated":false,"renderedFileInfo":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"\u003cimg src=\"site/assets/logo.png\" alt=\"\" width=\"28\"\u003e\u0026nbsp;revdiff \u0026nbsp;\u003ca href=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml/badge.svg\" alt=\"build\"\u003e\u003c/a\u003e \u003ca href=\"https://coveralls.io/github/umputun/revdiff?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/umputun/revdiff/badge.svg?branch=master\" alt=\"Coverage Status\"\u003e\u003c/a\u003e \u003ca href=\"https://goreportcard.com/report/github.com/umputun/revdiff\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/umputun/revdiff\" alt=\"Go Report Card\"\u003e\u003c/a\u003e","fully_qualified_name":"\u003cimg src=\"site/assets/logo.png\" alt=\"\" width=\"28\"\u003e\u0026nbsp;revdiff \u0026nbsp;\u003ca href=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml/badge.svg\" alt=\"build\"\u003e\u003c/a\u003e \u003ca href=\"https://coveralls.io/github/umputun/revdiff?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/umputun/revdiff/badge.svg?branch=master\" alt=\"Coverage Status\"\u003e\u003c/a\u003e \u003ca href=\"https://goreportcard.com/report/github.com/umputun/revdiff\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/umputun/revdiff\" alt=\"Go Report Card\"\u003e\u003c/a\u003e","kind":"section_1","ident_start":2,"ident_end":583,"extent_start":0,"extent_end":67187,"ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":583}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":1001,"utf16_col":0}}},{"name":"Features","fully_qualified_name":"Features","kind":"section_2","ident_start":1066,"ident_end":1074,"extent_start":1063,"extent_end":5222,"ident_utf16":{"start":{"line_number":6,"utf16_col":3},"end":{"line_number":6,"utf16_col":11}},"extent_utf16":{"start":{"line_number":6,"utf16_col":0},"end":{"line_number":42,"utf16_col":0}}},{"name":"Requirements","fully_qualified_name":"Requirements","kind":"section_2","ident_start":5225,"ident_end":5237,"extent_start":5222,"extent_end":5544,"ident_utf16":{"start":{"line_number":42,"utf16_col":3},"end":{"line_number":42,"utf16_col":15}},"extent_utf16":{"start":{"line_number":42,"utf16_col":0},"end":{"line_number":47,"utf16_col":0}}},{"name":"Installation","fully_qualified_name":"Installation","kind":"section_2","ident_start":5547,"ident_end":5559,"extent_start":5544,"extent_end":6318,"ident_utf16":{"start":{"line_number":47,"utf16_col":3},"end":{"line_number":47,"utf16_col":15}},"extent_utf16":{"start":{"line_number":47,"utf16_col":0},"end":{"line_number":85,"utf16_col":0}}},{"name":"Claude Code Plugin","fully_qualified_name":"Claude Code Plugin","kind":"section_2","ident_start":6321,"ident_end":6339,"extent_start":6318,"extent_end":15129,"ident_utf16":{"start":{"line_number":85,"utf16_col":3},"end":{"line_number":85,"utf16_col":21}},"extent_utf16":{"start":{"line_number":85,"utf16_col":0},"end":{"line_number":211,"utf16_col":0}}},{"name":"Plan Review Plugin","fully_qualified_name":"Plan Review Plugin","kind":"section_3","ident_start":14129,"ident_end":14147,"extent_start":14125,"extent_end":15129,"ident_utf16":{"start":{"line_number":189,"utf16_col":4},"end":{"line_number":189,"utf16_col":22}},"extent_utf16":{"start":{"line_number":189,"utf16_col":0},"end":{"line_number":211,"utf16_col":0}}},{"name":"Pi Package","fully_qualified_name":"Pi Package","kind":"section_2","ident_start":15132,"ident_end":15142,"extent_start":15129,"extent_end":18451,"ident_utf16":{"start":{"line_number":211,"utf16_col":3},"end":{"line_number":211,"utf16_col":13}},"extent_utf16":{"start":{"line_number":211,"utf16_col":0},"end":{"line_number":276,"utf16_col":0}}},{"name":"Codex Plugin","fully_qualified_name":"Codex Plugin","kind":"section_2","ident_start":18454,"ident_end":18466,"extent_start":18451,"extent_end":23866,"ident_utf16":{"start":{"line_number":276,"utf16_col":3},"end":{"line_number":276,"utf16_col":15}},"extent_utf16":{"start":{"line_number":276,"utf16_col":0},"end":{"line_number":358,"utf16_col":0}}},{"name":"Integration with Other Tools","fully_qualified_name":"Integration with Other Tools","kind":"section_3","ident_start":20899,"ident_end":20927,"extent_start":20895,"extent_end":23866,"ident_utf16":{"start":{"line_number":314,"utf16_col":4},"end":{"line_number":314,"utf16_col":32}},"extent_utf16":{"start":{"line_number":314,"utf16_col":0},"end":{"line_number":358,"utf16_col":0}}},{"name":"OpenCode","fully_qualified_name":"OpenCode","kind":"section_4","ident_start":20934,"ident_end":20942,"extent_start":20929,"extent_end":23208,"ident_utf16":{"start":{"line_number":316,"utf16_col":5},"end":{"line_number":316,"utf16_col":13}},"extent_utf16":{"start":{"line_number":316,"utf16_col":0},"end":{"line_number":341,"utf16_col":0}}},{"name":"General","fully_qualified_name":"General","kind":"section_4","ident_start":23213,"ident_end":23220,"extent_start":23208,"extent_end":23866,"ident_utf16":{"start":{"line_number":341,"utf16_col":5},"end":{"line_number":341,"utf16_col":12}},"extent_utf16":{"start":{"line_number":341,"utf16_col":0},"end":{"line_number":358,"utf16_col":0}}},{"name":"Usage","fully_qualified_name":"Usage","kind":"section_2","ident_start":23869,"ident_end":23874,"extent_start":23866,"extent_end":67050,"ident_utf16":{"start":{"line_number":358,"utf16_col":3},"end":{"line_number":358,"utf16_col":8}},"extent_utf16":{"start":{"line_number":358,"utf16_col":0},"end":{"line_number":994,"utf16_col":0}}},{"name":"Options","fully_qualified_name":"Options","kind":"section_3","ident_start":24329,"ident_end":24336,"extent_start":24325,"extent_end":30303,"ident_utf16":{"start":{"line_number":372,"utf16_col":4},"end":{"line_number":372,"utf16_col":11}},"extent_utf16":{"start":{"line_number":372,"utf16_col":0},"end":{"line_number":433,"utf16_col":0}}},{"name":"Config File","fully_qualified_name":"Config File","kind":"section_3","ident_start":30307,"ident_end":30318,"extent_start":30303,"extent_end":30715,"ident_utf16":{"start":{"line_number":433,"utf16_col":4},"end":{"line_number":433,"utf16_col":15}},"extent_utf16":{"start":{"line_number":433,"utf16_col":0},"end":{"line_number":446,"utf16_col":0}}},{"name":"Themes","fully_qualified_name":"Themes","kind":"section_3","ident_start":30719,"ident_end":30725,"extent_start":30715,"extent_end":36059,"ident_utf16":{"start":{"line_number":446,"utf16_col":4},"end":{"line_number":446,"utf16_col":10}},"extent_utf16":{"start":{"line_number":446,"utf16_col":0},"end":{"line_number":553,"utf16_col":0}}},{"name":"Examples","fully_qualified_name":"Examples","kind":"section_3","ident_start":36063,"ident_end":36071,"extent_start":36059,"extent_end":37956,"ident_utf16":{"start":{"line_number":553,"utf16_col":4},"end":{"line_number":553,"utf16_col":12}},"extent_utf16":{"start":{"line_number":553,"utf16_col":0},"end":{"line_number":615,"utf16_col":0}}},{"name":"All-Files Mode","fully_qualified_name":"All-Files Mode","kind":"section_3","ident_start":37960,"ident_end":37974,"extent_start":37956,"extent_end":39244,"ident_utf16":{"start":{"line_number":615,"utf16_col":4},"end":{"line_number":615,"utf16_col":18}},"extent_utf16":{"start":{"line_number":615,"utf16_col":0},"end":{"line_number":641,"utf16_col":0}}},{"name":"Context-Only File Review","fully_qualified_name":"Context-Only File Review","kind":"section_3","ident_start":39248,"ident_end":39272,"extent_start":39244,"extent_end":39834,"ident_utf16":{"start":{"line_number":641,"utf16_col":4},"end":{"line_number":641,"utf16_col":28}},"extent_utf16":{"start":{"line_number":641,"utf16_col":0},"end":{"line_number":650,"utf16_col":0}}},{"name":"Two-File Diff","fully_qualified_name":"Two-File Diff","kind":"section_3","ident_start":39838,"ident_end":39851,"extent_start":39834,"extent_end":40496,"ident_utf16":{"start":{"line_number":650,"utf16_col":4},"end":{"line_number":650,"utf16_col":17}},"extent_utf16":{"start":{"line_number":650,"utf16_col":0},"end":{"line_number":661,"utf16_col":0}}},{"name":"Scratch-Buffer Review","fully_qualified_name":"Scratch-Buffer Review","kind":"section_3","ident_start":40500,"ident_end":40521,"extent_start":40496,"extent_end":42096,"ident_utf16":{"start":{"line_number":661,"utf16_col":4},"end":{"line_number":661,"utf16_col":25}},"extent_utf16":{"start":{"line_number":661,"utf16_col":0},"end":{"line_number":679,"utf16_col":0}}},{"name":"Review Description","fully_qualified_name":"Review Description","kind":"section_3","ident_start":42100,"ident_end":42118,"extent_start":42096,"extent_end":42966,"ident_utf16":{"start":{"line_number":679,"utf16_col":4},"end":{"line_number":679,"utf16_col":22}},"extent_utf16":{"start":{"line_number":679,"utf16_col":0},"end":{"line_number":695,"utf16_col":0}}},{"name":"Markdown TOC Navigation","fully_qualified_name":"Markdown TOC Navigation","kind":"section_3","ident_start":42970,"ident_end":42993,"extent_start":42966,"extent_end":43667,"ident_utf16":{"start":{"line_number":695,"utf16_col":4},"end":{"line_number":695,"utf16_col":27}},"extent_utf16":{"start":{"line_number":695,"utf16_col":0},"end":{"line_number":701,"utf16_col":0}}},{"name":"Beyond Code Review","fully_qualified_name":"Beyond Code Review","kind":"section_3","ident_start":43671,"ident_end":43689,"extent_start":43667,"extent_end":44730,"ident_utf16":{"start":{"line_number":701,"utf16_col":4},"end":{"line_number":701,"utf16_col":22}},"extent_utf16":{"start":{"line_number":701,"utf16_col":0},"end":{"line_number":716,"utf16_col":0}}},{"name":"Zed Integration","fully_qualified_name":"Zed Integration","kind":"section_3","ident_start":44734,"ident_end":44749,"extent_start":44730,"extent_end":45028,"ident_utf16":{"start":{"line_number":716,"utf16_col":4},"end":{"line_number":716,"utf16_col":19}},"extent_utf16":{"start":{"line_number":716,"utf16_col":0},"end":{"line_number":722,"utf16_col":0}}},{"name":"Review History","fully_qualified_name":"Review History","kind":"section_3","ident_start":45032,"ident_end":45046,"extent_start":45028,"extent_end":46979,"ident_utf16":{"start":{"line_number":722,"utf16_col":4},"end":{"line_number":722,"utf16_col":18}},"extent_utf16":{"start":{"line_number":722,"utf16_col":0},"end":{"line_number":739,"utf16_col":0}}},{"name":"Key Bindings","fully_qualified_name":"Key Bindings","kind":"section_3","ident_start":46983,"ident_end":46995,"extent_start":46979,"extent_end":54979,"ident_utf16":{"start":{"line_number":739,"utf16_col":4},"end":{"line_number":739,"utf16_col":16}},"extent_utf16":{"start":{"line_number":739,"utf16_col":0},"end":{"line_number":836,"utf16_col":0}}},{"name":"Status Bar Icons","fully_qualified_name":"Status Bar Icons","kind":"section_3","ident_start":54983,"ident_end":54999,"extent_start":54979,"extent_end":56121,"ident_utf16":{"start":{"line_number":836,"utf16_col":4},"end":{"line_number":836,"utf16_col":20}},"extent_utf16":{"start":{"line_number":836,"utf16_col":0},"end":{"line_number":856,"utf16_col":0}}},{"name":"Mouse Support","fully_qualified_name":"Mouse Support","kind":"section_3","ident_start":56125,"ident_end":56138,"extent_start":56121,"extent_end":59459,"ident_utf16":{"start":{"line_number":856,"utf16_col":4},"end":{"line_number":856,"utf16_col":17}},"extent_utf16":{"start":{"line_number":856,"utf16_col":0},"end":{"line_number":884,"utf16_col":0}}},{"name":"Custom Keybindings","fully_qualified_name":"Custom Keybindings","kind":"section_3","ident_start":59463,"ident_end":59481,"extent_start":59459,"extent_end":64219,"ident_utf16":{"start":{"line_number":884,"utf16_col":4},"end":{"line_number":884,"utf16_col":22}},"extent_utf16":{"start":{"line_number":884,"utf16_col":0},"end":{"line_number":951,"utf16_col":0}}},{"name":"Vim-motion Preset","fully_qualified_name":"Vim-motion Preset","kind":"section_3","ident_start":64223,"ident_end":64240,"extent_start":64219,"extent_end":66271,"ident_utf16":{"start":{"line_number":951,"utf16_col":4},"end":{"line_number":951,"utf16_col":21}},"extent_utf16":{"start":{"line_number":951,"utf16_col":0},"end":{"line_number":974,"utf16_col":0}}},{"name":"Output Format","fully_qualified_name":"Output Format","kind":"section_3","ident_start":66275,"ident_end":66288,"extent_start":66271,"extent_end":67050,"ident_utf16":{"start":{"line_number":974,"utf16_col":4},"end":{"line_number":974,"utf16_col":17}},"extent_utf16":{"start":{"line_number":974,"utf16_col":0},"end":{"line_number":994,"utf16_col":0}}},{"name":"Contributing","fully_qualified_name":"Contributing","kind":"section_2","ident_start":67053,"ident_end":67065,"extent_start":67050,"extent_end":67120,"ident_utf16":{"start":{"line_number":994,"utf16_col":3},"end":{"line_number":994,"utf16_col":15}},"extent_utf16":{"start":{"line_number":994,"utf16_col":0},"end":{"line_number":998,"utf16_col":0}}},{"name":"License","fully_qualified_name":"License","kind":"section_2","ident_start":67123,"ident_end":67130,"extent_start":67120,"extent_end":67187,"ident_utf16":{"start":{"line_number":998,"utf16_col":3},"end":{"line_number":998,"utf16_col":10}},"extent_utf16":{"start":{"line_number":998,"utf16_col":0},"end":{"line_number":1001,"utf16_col":0}}}]}},"codeViewLayoutRoute":{"repo":{"id":1198207465,"defaultBranch":"master","name":"revdiff","ownerLogin":"umputun","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2026-04-01T07:59:06.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/535880?v=4","public":true,"private":false,"isOrgOwned":false,"isArchived":false},"currentUser":null,"uploadToken":"mCSuBOGEVzcBI48XgvPHtIDJV3E4PllnzTjC8673oxcRldCL-7Lm4ZwoohwnhdzpRcm_BMTNMwaOn_Q8kJr9fQ","allShortcutsEnabled":false,"treeExpanded":true,"path":"README.md","symbolsExpanded":false,"refInfo":{"name":"master","listCacheKey":"v0:1791429287.0","canEdit":false,"currentOid":"5200a9fe1635e53b8fbc5fe21b2e9edb407bfb9a"},"helpUrl":"https://docs.github.com","githubDevUrl":null},"codeViewFileTreeLayoutRoute":{"fileTree":{"":{"items":[{"name":".agents","path":".agents","contentType":"directory"},{"name":".claude-plugin","path":".claude-plugin","contentType":"directory"},{"name":".claude","path":".claude","contentType":"directory"},{"name":".github","path":".github","contentType":"directory"},{"name":".revmux","path":".revmux","contentType":"directory"},{"name":".zed","path":".zed","contentType":"directory"},{"name":"app","path":"app","contentType":"directory"},{"name":"completions","path":"completions","contentType":"directory"},{"name":"docs","path":"docs","contentType":"directory"},{"name":"plugins","path":"plugins","contentType":"directory"},{"name":"site","path":"site","contentType":"directory"},{"name":"themes","path":"themes","contentType":"directory"},{"name":"vendor","path":"vendor","contentType":"directory"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".golangci.yml","path":".golangci.yml","contentType":"file"},{"name":".goreleaser.yml","path":".goreleaser.yml","contentType":"file"},{"name":"CHANGELOG.md","path":"CHANGELOG.md","contentType":"file"},{"name":"CLAUDE.md","path":"CLAUDE.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"Makefile","path":"Makefile","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"flake.lock","path":"flake.lock","contentType":"file"},{"name":"flake.nix","path":"flake.nix","contentType":"file"},{"name":"go.mod","path":"go.mod","contentType":"file"},{"name":"go.sum","path":"go.sum","contentType":"file"},{"name":"package.json","path":"package.json","contentType":"file"}],"totalCount":27}},"fileTreeProcessingTime":10.530912,"foldersToFetch":[]},"codeViewBlobLayoutRoute":{"codeLineWrapEnabled":false,"refInfo":{"name":"master","listCacheKey":"v0:1791429287.0","canEdit":false,"refType":"branch","currentOid":"5200a9fe1635e53b8fbc5fe21b2e9edb407bfb9a","canEditOnDefaultBranch":false,"fileExistsOnDefault":true},"path":"README.md","blob":{"copilotSWEAgentEnabled":false,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/umputun/revdiff/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"README.md","displayUrl":"https://github.com/umputun/revdiff/blob/master/README.md?raw=true","headerInfo":{"blobSize":"65.6 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"5acf443","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fumputun%2Frevdiff%2Fblob%2Fmaster%2FREADME.md","isCSV":false,"isRichtext":true,"lineInfo":{"truncatedLoc":"1001","truncatedSloc":"722"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"isIssueTemplate":false,"isDiscussionTemplate":false,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/umputun/revdiff/blob/master/README.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/umputun/revdiff/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/umputun/revdiff/raw/refs/heads/master/README.md","renderImageOrRaw":false,"shortPath":null,"symbolsEnabled":true,"tabSize":4,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null},"copilotInfo":null,"copilotAccessAllowed":false,"copilotSpacesEnabled":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true},"codeViewBlobLayoutRoute.StyledBlob":{"rawLines":["# \u003cimg src=\"site/assets/logo.png\" alt=\"\" width=\"28\"\u003e\u0026nbsp;revdiff \u0026nbsp;\u003ca href=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/umputun/revdiff/actions/workflows/ci.yml/badge.svg\" alt=\"build\"\u003e\u003c/a\u003e \u003ca href=\"https://coveralls.io/github/umputun/revdiff?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/umputun/revdiff/badge.svg?branch=master\" alt=\"Coverage Status\"\u003e\u003c/a\u003e \u003ca href=\"https://goreportcard.com/report/github.com/umputun/revdiff\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/umputun/revdiff\" alt=\"Go Report Card\"\u003e\u003c/a\u003e","","TUI for reviewing diffs, files, and documents with inline annotations. Outputs structured annotations to stdout on quit, making it easy to pipe results into AI agents, scripts, or other tools.","","Built for a specific use case: reviewing code changes, plans, and documents without leaving a terminal-based AI coding session (e.g., Claude Code). Just enough UI to navigate diffs and files, annotate specific lines, and return the results to the calling process - no more, no less.","","## Features","","- Structured annotation output to stdout - pipe into AI agents, scripts, or other tools","- Full-file diff view with syntax highlighting","- Intra-line word-diff: highlights the specific changed words within paired add/remove lines using a brighter background overlay, off by default — enable with `--word-diff` or toggle with `W`","- Collapsed diff mode: shows final text with change markers, toggle with `v`","- Word wrap mode: wraps long lines at viewport boundary with `↪` continuation markers, toggle with `w`; optional `--wrap-indent N` for hanging-indent continuations (handy for markdown lists)","- Page scroll overlap: `--page-overlap N` carries the bottom N lines of the screen to the top of the next one on PgUp/PgDn, so the seam between screens keeps context; the carryover is approximate on wrapped or annotated lines, which occupy several rows but are a single cursor stop","- Horizontal scroll overflow indicators: truncated diff lines show `«` / `»` markers at the edges to signal hidden content off-screen","- Vertical scrollbar thumb: a thicker `┃` segment on pane right borders indicates the visible portion of long diffs, file trees, and markdown TOCs; thumb size and position track scroll progress automatically","- Line numbers: side-by-side old/new line number gutter for diffs, single column for full-context files, toggle with `L`","- Rename-aware diffs (git): a renamed file shows its origin in the diff-pane header as `old → new` and renders only the real line changes instead of a full delete-and-add","- Mercurial support: auto-detects hg repos, translates git-style refs (HEAD, HEAD~N) to Mercurial revsets","- Jujutsu support: auto-detects jj repos (including colocated git+jj), translates git-style refs to jj revsets (`HEAD` → `@-`, `HEAD~N` → `@` plus N+1 dashes); `--all-files` supported","- Blame gutter: shows author name and commit age per line, toggle with `B`","- Annotate any line in the diff (added, removed, or context) plus file-level notes","- Single-file auto-detection: when a diff contains exactly one file, hides the tree pane and gives full terminal width to the diff view","- Two-pane TUI: file tree (left) + colorized diff viewport (right)","- Vim-style `/` search within diff with `n`/`N` match navigation","- Hunk navigation to jump between change groups","- Annotation list popup (`@`): browse all annotations across files, jump to any annotation","- Filter file tree to show only annotated files","- Status line with filename, diff stats, hunk position, line number, and mode indicators","- Help overlay (`?`) showing all keybindings organized by section","- Info popup (`i`) showing launch scope (mode, VCS, ref, filters, file/status counts, aggregate `+/-` line stats), the optional `--description` prose, and the commit log subject + body for every commit in the current ref range (git/hg/jj) — useful for restoring narrative context when reviewing PR-style diffs","- Markdown TOC navigation: single-file markdown files in context-only mode show a table-of-contents pane with header navigation and active section tracking","- All-files mode: browse and annotate all tracked files with `--all-files` (git `ls-files` or jj `file list`), filter with `--include` and `--exclude`","- No-VCS file review: `--only` files outside a VCS repo (or not in any diff) are shown as context-only with full annotation support","- Scratch-buffer review: annotate arbitrary piped or redirected text with `--stdin`, optionally naming it with `--stdin-name`. When the piped content sniffs as a git unified diff, revdiff parses it as a real multi-file diff (review `gh pr diff` or `git format-patch -1 --stdout` output directly); otherwise the input is shown as a single context-only buffer.","- Pi package: launch revdiff from pi, capture annotations, and send them to the agent immediately for the normal review loop","- Review history: auto-saves annotations and diffs to `~/.config/revdiff/history/` on quit as a safety net","- Fully customizable colors via environment variables, CLI flags, or config file","- Custom keybindings: remap any key via config file, export defaults with `--dump-keys`","","![revdiff screenshot](site/assets/screenshot.png)","","## Requirements","","- `git`, `hg`, or `jj` (used to generate diffs; optional when using `--only` or `--stdin`)","- Jujutsu must be 0.27 or newer. Versions 0.23 through 0.26 have no `jj file annotate -T`, so the blame gutter does not work. Versions before 0.23 also reject the commit-log template behind the commit-info popup.","","## Installation","","**Homebrew (macOS/Linux):**","","```bash","brew install umputun/apps/revdiff","```","","**Arch Linux (AUR):**","","```bash","paru -S revdiff","```","","**Debian/Ubuntu (.deb):**","","```bash","# download the latest .deb for your architecture from GitHub Releases","sudo dpkg -i revdiff_*.deb","```","","**RPM-based (Fedora, RHEL, etc.):**","","```bash","# download the latest .rpm for your architecture from GitHub Releases","sudo rpm -i revdiff_*.rpm","```","","**Go:**","","```bash","go install github.com/umputun/revdiff/app/revdiff@latest","```","","Installs the `revdiff` binary into `GOBIN` (defaults to `$(go env GOPATH)/bin`). Add that directory to your `PATH`.","","**Binary releases:** download from [GitHub Releases](https://github.com/umputun/revdiff/releases) (deb, rpm, archives for linux/darwin amd64/arm64).","","## Claude Code Plugin","","revdiff ships with a Claude Code plugin for interactive code review directly from a Claude session. The plugin launches revdiff as a terminal overlay, captures annotations, and feeds them back to Claude for processing.","","The plugin requires one of the following terminals since Claude Code itself cannot display interactive TUI applications - the overlay runs revdiff in a separate terminal layer on top of the current session:","","| Terminal | Overlay method | Detection |","|----------|---------------|-----------|","| **agterm** | `agtermctl session overlay open … --block` (full-pane overlay, blocks until quit) | `$AGTERM_SESSION_ID` env var |","| **tmux** | `display-popup` (blocks until quit) | `$TMUX` env var |","| **Zellij** | `zellij run --floating` | `$ZELLIJ` env var |","| **herdr** | `herdr tab create` + `herdr pane run` (new tab), or a zoomed `herdr pane split` with `REVDIFF_HERDR_PANE=1` | `$HERDR_ENV` env var |","| **kitty** | `kitty @ launch --type=overlay` | `$KITTY_LISTEN_ON` env var |","| **wezterm** | `wezterm cli split-pane` | `$WEZTERM_PANE` env var |","| **Kaku** | `kaku cli split-pane` (same API as wezterm) | `$WEZTERM_PANE` env var |","| **cmux** | `cmux new-split` + `cmux send` | `$CMUX_SURFACE_ID`, `__CFBundleIdentifier=com.cmuxterm.app`, or `GHOSTTY_RESOURCES_DIR` / `GHOSTTY_BIN_DIR` containing `cmux.app` |","| **ghostty** | AppleScript split + zoom (macOS only) | `$TERM_PROGRAM` + AppleScript probe |","| **iTerm2** | `osascript` split pane (macOS only) | `$ITERM_SESSION_ID` env var |","| **Emacs vterm** | New frame via `emacsclient` | `$INSIDE_EMACS` env var |","","Priority: agterm → tmux → Zellij → herdr → kitty → wezterm/Kaku → cmux → ghostty → iTerm2 → Emacs vterm (first detected wins). If none are available, the plugin exits with an error.","","\u003e **Note:** cmux is detected before ghostty when `$CMUX_SURFACE_ID` is set, `__CFBundleIdentifier=com.cmuxterm.app`, or `GHOSTTY_RESOURCES_DIR` / `GHOSTTY_BIN_DIR` contains `cmux.app`. The cmux block uses the cmux CLI (`new-split` + `send --surface`) instead of Ghostty's AppleScript API.","","\u003e **Note:** iTerm2 uses a split pane (vertical or horizontal, auto-detected from terminal dimensions) rather than a full-screen overlay. The iTerm2 AppleScript API does not expose a zoom command, so the split view shares screen space with the invoking session.","","\u003e **Note:** Ghostty and iTerm2 launchers use `osascript` (Apple Events), which is blocked by Claude Code's sandbox. If you use these terminals with sandbox enabled, add the launcher to `excludedCommands` in your Claude Code `settings.json`:","\u003e","\u003e ```json","\u003e {","\u003e   \"sandbox\": {","\u003e     \"excludedCommands\": [\"*/launch-revdiff.sh*\"]","\u003e   }","\u003e }","\u003e ```","\u003e","\u003e Terminals that use CLI tools instead of AppleScript (agterm, tmux, Zellij, herdr, kitty, wezterm, Kaku, cmux) are not affected.","","\u003e **Disconnect-resilient tmux window mode:** set `REVDIFF_TMUX_WINDOW=1` in the launcher's environment to open revdiff in a persistent, server-owned tmux window instead of a client-owned `display-popup`. A dropped SSH or tmux client tears down a popup and kills the review, but a server-owned window survives the disconnect — reattach and the live review is still there. This is a launcher environment variable, not a revdiff flag.","","\u003e **Pane-scoped overlay (herdr):** Set `REVDIFF_HERDR_PANE=1` in the launcher's environment to open revdiff in a zoomed split of the agent's own herdr pane instead of a new fullscreen tab, so the agent pane stays one keypress away. It needs a herdr whose CLI carries `pane split`, `pane get` and `pane close`; an unsupported CLI or a refused split falls back to the tab overlay; a split that succeeds but returns no usable pane id fails closed with a warning rather than opening a second surface, and may leave a stray pane to close by hand. This is a launcher environment variable, not a revdiff flag.","","\u003e **Pane-scoped overlay (agterm):** set `REVDIFF_AGTERM_PANE=1` in the launcher's environment to open revdiff in the agent's own split pane instead of over the whole session, leaving the sibling pane live and visible. It applies only when that session is split — the session-wide overlay stands otherwise, and the launcher retries session-wide if agterm refuses the pane. The review gets pane width rather than session width, which is why it is opt-in. This is a launcher environment variable, not a revdiff flag.","","**Install:**","","```bash","# add marketplace and install","/plugin marketplace add umputun/revdiff","/plugin install revdiff@revdiff","```","","**Use with `/revdiff` command:**","","```","/revdiff                  -- smart detection: uncommitted, last commit, or branch diff","/revdiff HEAD~1 HEAD      -- review last commit","/revdiff main             -- review current branch against main","/revdiff --staged         -- review staged changes only","/revdiff HEAD~3 HEAD      -- review last 3 commits","```","","**Use with free text** (no slash command needed):","","```","\"review diff\"                     -- smart detection, same as /revdiff","\"review diff HEAD~1 HEAD\"         -- last commit","\"review diff against main\"        -- branch diff","\"review changes from last 2 days\" -- Claude resolves the ref automatically","\"revdiff for staged changes\"      -- staged only","```","","When no ref is provided, the plugin auto-detects the VCS (git, hg, or jj) and inspects the current repo state to pick what to review:","- On main/master with uncommitted changes — reviews uncommitted changes","- On main/master with clean tree — reviews the last commit","- On a feature branch with clean tree — reviews branch diff against main","- On a feature branch with uncommitted changes — asks whether to review uncommitted only or the full branch diff","- Outside a VCS repo — falls back to asking the user what to review","","The plugin includes built-in reference documentation and can answer questions about revdiff usage, available themes, keybindings, and configuration options. It can also create or modify the local config file (`~/.config/revdiff/config`) on request:","","```","\"what chroma themes does revdiff support?\"","\"switch revdiff to dracula theme\"","\"what are the revdiff keybindings?\"","\"set tree width to 3 in revdiff config\"","```","","The plugin supports the full review loop: annotate → plan → fix → re-review until no more annotations remain. The bundled launcher treats exit code `10` as success-with-annotations and processes stdout normally.","","**Ask instead of instruct:** an annotation containing `??` anywhere in its text is treated as a question rather than a directive, so the agent explains that code instead of changing it. Openers `explain`, `remind`, `describe`, `what is`, `what are`, `how does`, `how do` and `clarify` do the same. `??` is the language-neutral form and works whatever you write in.","","```","## renderer.go:142 (+)","why a pointer here??","","## store.go:88 (-)","explain what this lock protects","```","","The answer comes back as a markdown document reopened in revdiff, with a TOC sidebar, so you can annotate the explanation itself to ask follow-ups. That loop repeats until you quit without annotating. Any code-change annotations from the same batch are held and applied afterwards. The Codex plugin behaves the same way; the Pi package classifies questions too but answers them in chat.","","**Custom launchers:** the Claude diff-review skill and the cross-runtime planning plugin resolve launchers through a two-layer chain (user → bundled). Claude uses `${CLAUDE_PLUGIN_DATA}/scripts/\u003clauncher\u003e`; the Codex planning hook uses `${PLUGIN_DATA}/scripts/launch-plan-review.sh`. There is no project-level executable override by design because these hooks auto-fire in any opened repository. See `.claude-plugin/skills/revdiff/references/install.md` for diff review and [plugins/revdiff-planning/README.md](plugins/revdiff-planning/README.md) for plan review.","","### Plan Review Plugin","","A separate `revdiff-planning` plugin automatically opens revdiff when Claude or Codex completes a plan, letting you annotate it before implementation. If you add annotations, the agent revises the full plan and presents it again — looping until you're satisfied. Exit code `10` means annotations were captured, not launcher failure.","","Claude Code:","","```bash","/plugin marketplace add umputun/revdiff","/plugin install revdiff-planning@revdiff","```","","Codex:","","```bash","codex plugin marketplace add umputun/revdiff","codex plugin add revdiff-planning@revdiff","```","","Start a new Codex session and trust the hook through `/hooks`. Codex automatic review is opt-in and only fires for complete `\u003cproposed_plan\u003e` blocks in Plan mode; `/revdiff-plan` remains the manual fallback.","","This plugin is independent from the main `revdiff` plugin. In Claude Code it hooks `ExitPlanMode`, and so does `planning` from `cc-thingz`; Claude Code runs both hooks, so enabling both can review the same plan twice.","","## Pi Package","","revdiff also ships as a [pi](https://github.com/badlogic/pi-mono) package. The `/revdiff` command routes requests through the revdiff skill, which resolves refs, files, and natural-language targets before launching the existing `revdiff` binary through the `revdiff_review` tool. If no annotations were captured, the agent stops the review loop unless you explicitly ask for another review.","","**Install:**","","```bash","pi install https://github.com/umputun/revdiff","```","","**Command inside pi:**","","```text","/revdiff [args]","```","","Useful args:","","```text","/revdiff                         -- detect uncommitted, staged, or branch changes, then open revdiff","/revdiff HEAD~1 HEAD             -- review last commit","/revdiff main                    -- review against main","/revdiff --staged                -- review staged changes","/revdiff --untracked             -- include untracked files in working-tree review","/revdiff --all-files             -- browse all tracked files","/revdiff --all-files --exclude vendor","/revdiff --only README.md        -- review a single file in context-only mode","/revdiff HEAD~3 --description=\"why this refactor matters\"","/revdiff HEAD~3 --description-file=/tmp/revdiff-desc.md","/revdiff main --annotations=/tmp/revdiff-review.md","```","","Natural-language targets are supported because `/revdiff` routes through the skill:","","```text","/revdiff prev commit","/revdiff last tag","/revdiff 2 weeks ago","```","","You can also call the skill explicitly with `/skill:revdiff \u003crequest\u003e`.","","**Agent workflow:**","","- `/revdiff` is a Pi command alias for `/skill:revdiff`; the skill resolves the request and calls `revdiff_review`.","- `revdiff_review` suspends pi, hands the terminal to revdiff, then returns captured annotations to the agent.","- The agent classifies annotations into explanation requests and code-change directives.","- Explanation requests are answered first in normal chat, without opening another revdiff session for the explanation.","- Any no-annotation `revdiff_review` result stops the loop. The agent must not relaunch revdiff unless you explicitly ask for another review.","- For explanation-only annotations, the agent asks whether to continue the original review or finish.","- Before editing repository files, the agent lists planned code/file changes, applies the changes, then reruns `revdiff_review` with the same args until no annotations are captured.","","**Notes:**","","- Requires the `revdiff` binary on `PATH`","- Set `REVDIFF_BIN=/absolute/path/to/revdiff` if pi can't find the binary","- Direct terminal handoff is the only Pi launch mode","- Exit code `10` means annotations were captured, not failure","- Use `--untracked` when agent-created files should be reviewed before they are staged","- Use `--description` or `--description-file` after analysis/refactor work so the info popup carries review context","- Use `--annotations=\u003ctempfile\u003e` to preload in-session review notes","- Successful `revdiff_review` results include captured annotation text; history is only for explicit latest-history requests or missing-output fallback","- For \"use my latest revdiff annotations\", the agent should read the newest file under `$REVDIFF_HISTORY_DIR` or `~/.config/revdiff/history/` instead of relaunching revdiff","- In the repo, the pi-specific resources live under `plugins/pi/` to keep harness integrations clearly separated","","## Codex Plugin","","revdiff ships with a [Codex CLI](https://github.com/openai/codex) plugin for interactive diff review and plan annotation directly from a Codex session. The plugin provides two skills:","","- `/revdiff` — same diff review workflow as the Claude Code plugin (detect ref, launch overlay, capture annotations, feedback loop)","- `/revdiff-plan` — extracts the last Codex assistant message from session rollout files, opens it in revdiff for annotation, and feeds feedback back","","The plugin uses the same terminal overlay mechanism (tmux, Zellij, herdr, kitty, wezterm, etc.) as the Claude Code plugin.","","**Install the diff-review skills and automatic plan-review plugin:**","","```bash","codex plugin marketplace add umputun/revdiff","codex plugin add revdiff@revdiff","codex plugin add revdiff-planning@revdiff","```","","If you previously copied the skills manually, remove `~/.codex/skills/revdiff` and `~/.codex/skills/revdiff-plan` after installing the plugin so the plugin copy is the only one in use.","","Start a new session and trust the plugin hook through `/hooks`. The `Stop` hook runs only in Plan mode and first checks `last_assistant_message`; whenever that field has no complete `\u003cproposed_plan\u003e`, it reads the exact event transcript and selects the last assistant message for the matching `session_id` and `turn_id`, without depending on a provider-specific phase. A readable clarification turn is ignored. Missing or mismatched event data, dependencies, and launcher failures warn and fail open.","","When annotations are present, the hook asks Codex to return the complete revised plan with a snapshot marker on the first line inside `\u003cproposed_plan\u003e`. The next round opens a rolling compare (`\u003cnew\u003e \u003cold\u003e`); reviewed snapshots are replaced, and a clean review removes the final snapshot.","","The `revdiff` plugin installs both interactive skills. The separate `revdiff-planning` plugin adds automatic Plan-mode review.","","**Requirements:**","","- `revdiff` binary on `PATH`","- `jq` (required only for manual `/revdiff-plan` session extraction)","- One of the supported terminal multiplexers for overlay mode","","**Notes:**","","- Codex treats exit code `10` as success-with-annotations and keeps captured output","- Automatic review uses the opt-in `revdiff-planning` plugin; `/revdiff-plan` remains a manual fallback","- Scripts are portable copies from the Claude Code plugin, not symlinks","- Codex plugin source lives under `plugins/codex/` in the repository","","### Integration with Other Tools","","#### OpenCode","","revdiff integrates with [OpenCode](https://opencode.ai). V1 provides a tool, slash command, and plan-review plugin. V2 provides a CLI plugin for `/revdiff` and automatic plan review, using the shared launcher in the client's terminal environment.","","**Install (automatically detects OpenCode v1 or v2):**","","```bash","cd plugins/opencode \u0026\u0026 bash setup.sh","```","","The v2 CLI plugin is discovered automatically under `plugins/revdiff/`. It runs reviews locally and returns annotations to the session captured at launch. Automatic plan review handles live completion events only, deduplicated between local clients using an atomic marker per event ID. Markers older than one day are removed on the next claim. Clients must share the same state directory and local checkout; the winner may be in a window the user is not looking at. Restart OpenCode after installing.","","The installer uses `opencode --version` from `PATH`; use `bash setup.sh --opencode /path/to/opencode /path/to/config` to select another v2 installation. The v2 integration supports OpenCode v2.0.0+ and has no runtime npm dependencies. Its config directory follows `OPENCODE_CONFIG_DIR`, then XDG defaults. V1 installs only to `~/.config/opencode`. Upgrade removes the obsolete v1 plan plugin, Markdown command and exact JSON registration; JSONC is left untouched with a notice. V1 code remains unchanged, and rollback leaves the inert v2 directory in place. See [plugins/opencode/README.md](plugins/opencode/README.md) for prerequisites, ownership rules and migration details.","","**Commands inside OpenCode:**","","V2 also supports `/revdiff` from the home screen. A clean review leaves it unchanged; annotations create a feedback session using the configured default agent and selected model, falling back to the configured model on older v2 clients.","","```text","/revdiff                         -- review git diff with revdiff TUI","/revdiff HEAD~3..HEAD             -- review last 3 commits","```","","The v2 plan-review plugin automatically launches revdiff after a completed plan-agent response in the displayed root session. Annotations and a line-numbered snapshot of the reviewed plan are returned to that session for revision, so the agent does not need the deleted temporary file. V1 uses the plan-mode idle hook.","","#### General","","The structured stdout output works with any tool that can read text. By default revdiff exits `0` even when annotations are produced; pass `--exit-code-on-annotations` to return `10` for successful annotation output:","","```bash","# capture annotations for processing","rc=0","annotations=$(revdiff --exit-code-on-annotations main) || rc=$?","case \"$rc\" in","  0) [ -n \"$annotations\" ] \u0026\u0026 echo \"$annotations\" | your-tool ;;","  10) echo \"$annotations\" | your-tool ;;","  *) exit \"$rc\" ;;","esac","```","","Exit status: `0` = no annotations, discarded annotations, or default mode; `10` = annotations were produced with `--exit-code-on-annotations`; `1` = real errors.","","## Usage","","```","revdiff [OPTIONS] [base] [against]","```","","Positional arguments support several forms:","- `revdiff` — uncommitted changes","- `revdiff HEAD~3` — diff a single ref against the working tree","- `revdiff HEAD~1 HEAD` — review exactly the last commit","- `revdiff main feature` — diff between two refs","- `revdiff main..feature` — same as above, using git's dot-dot syntax","- `revdiff main...feature` — changes since `feature` diverged from `main`","","### Options","","| Option | Description | Default |","|--------|-------------|---------|","| `base` | Git ref to diff against | uncommitted changes |","| `against` | Second git ref for two-ref diff | |","| `--staged` | Show staged changes, env: `REVDIFF_STAGED` | `false` |","| `--untracked` | Show untracked files in the tree, env: `REVDIFF_UNTRACKED` | `false` |","| `--tree-width` | File tree panel width in units (1-10), env: `REVDIFF_TREE_WIDTH` | `2` |","| `--tab-width` | Number of spaces per tab character, env: `REVDIFF_TAB_WIDTH` | `4` |","| `--no-colors` | Disable all colors including syntax highlighting, env: `REVDIFF_NO_COLORS` | `false` |","| `--no-status-bar` | Hide the status bar, env: `REVDIFF_NO_STATUS_BAR` | `false` |","| `--wrap` | Enable line wrapping in diff view, env: `REVDIFF_WRAP` | `false` |","| `--wrap-indent` | Indent wrap continuation rows by N columns so they hang under the first row's content (helps when reviewing markdown lists where unindented continuation can be misread as a new bullet), env: `REVDIFF_WRAP_INDENT` | `0` |","| `--page-overlap` | Keep N lines from the previous screen when paging the diff, env: `REVDIFF_PAGE_OVERLAP` | `0` |","| `--collapsed` | Start in collapsed diff mode, env: `REVDIFF_COLLAPSED` | `false` |","| `--compact` | Start in compact diff mode (small context around changes), env: `REVDIFF_COMPACT` | `false` |","| `--compact-context` | Number of context lines around changes when in compact mode, env: `REVDIFF_COMPACT_CONTEXT` | `5` |","| `--cross-file-hunks` | Allow `[` and `]` to continue into adjacent files, env: `REVDIFF_CROSS_FILE_HUNKS` | `false` |","| `--cross-file-motion` | Allow cursor motion (`j`/`k`, `PgDown`/`PgUp`, `Ctrl+d`/`Ctrl+u`) to continue into adjacent files at a boundary, env: `REVDIFF_CROSS_FILE_MOTION` | `false` |","| `--start-at-change` | Position the cursor on the first changed line, env: `REVDIFF_START_AT_CHANGE` | `false` |","| `--line-numbers` | Show line numbers in diff gutter, env: `REVDIFF_LINE_NUMBERS` | `false` |","| `--blame` | Show blame gutter, env: `REVDIFF_BLAME` | `false` |","| `--word-diff` | Highlight intra-line word-level changes in paired add/remove lines, env: `REVDIFF_WORD_DIFF` | `false` |","| `--filter-unreviewed` | Show only files not marked reviewed, env: `REVDIFF_FILTER_UNREVIEWED` | `false` |","| `--annotation-marker` | Prefix shown before annotation lines, env: `REVDIFF_ANNOTATION_MARKER` | `💬` |","| `--exit-code-on-annotations` | Exit 10 when annotations are produced, env: `REVDIFF_EXIT_CODE_ON_ANNOTATIONS`, config: `exit-code-on-annotations` | `false` |","| `--no-confirm-discard` | Skip confirmation when discarding annotations with Q, env: `REVDIFF_NO_CONFIRM_DISCARD` | `false` |","| `--no-confirm-reload` | Skip confirmation when dropping annotations on reload with R, env: `REVDIFF_NO_CONFIRM_RELOAD` | `false` |","| `--no-mouse` | Disable mouse support (scroll wheel, click), env: `REVDIFF_NO_MOUSE` | `false` |","| `--no-tree` | Hide the file tree pane, env: `REVDIFF_NO_TREE` | `false` |","| `--vim-motion` | Enable vim-style motion preset (counts, `gg`, `G`, `H`/`M`/`L`, `zz`/`zt`/`zb`, `ZZ`/`ZQ`), env: `REVDIFF_VIM_MOTION` | `false` |","| `--chroma-style` | Chroma color theme for syntax highlighting, env: `REVDIFF_CHROMA_STYLE` | `catppuccin-macchiato` |","| `--theme` | Load color theme from `~/.config/revdiff/themes/`; use `auto` to choose by terminal background, env: `REVDIFF_THEME` | |","| `--auto-theme-dark` | Theme used by `--theme auto` on dark terminal backgrounds, env: `REVDIFF_AUTO_THEME_DARK` | `revdiff` |","| `--auto-theme-light` | Theme used by `--theme auto` on light terminal backgrounds, env: `REVDIFF_AUTO_THEME_LIGHT` | `catppuccin-latte` |","| `--dump-theme` | Print currently resolved colors as theme file to stdout and exit | |","| `--list-themes` | Print available theme names to stdout and exit | |","| `--init-themes` | Write bundled theme files to themes dir and exit | |","| `--init-all-themes` | Write all gallery themes (bundled + community) to themes dir and exit | |","| `--install-theme` | Install theme(s) from gallery or local file path and exit (repeatable) | |","| `-A`, `--all-files` | Browse all tracked files, not just diffs (git or jj) | `false` |","| `--compare-old` | Compare mode: old file path (use with `--compare-new`; uses `git diff --no-index`, no VCS repo needed) | |","| `--compare-new` | Compare mode: new file path (use with `--compare-old`) | |","| `--stdin` | Review stdin as a scratch buffer (piped or redirected input only) | `false` |","| `--stdin-name` | Synthetic file name for stdin content; enables extension-based highlighting/TOC | `scratch-buffer` |","| `--description` | Prose context shown in the info popup (markdown; for multi-line text, use a multi-line quoted shell string or `--description-file`) | |","| `--description-file` | Read the info-popup description from this file (markdown) | |","| `-I`, `--include` | Include only files matching prefix, may be repeated, env: `REVDIFF_INCLUDE` (comma-separated) | |","| `-X`, `--exclude` | Exclude files matching prefix, may be repeated, env: `REVDIFF_EXCLUDE` (comma-separated) | |","| `-F`, `--only` | Show only matching files by exact path or suffix, may be repeated (e.g. `--only=model.go`) | |","| `-o`, `--output` | Write annotations to file instead of stdout, env: `REVDIFF_OUTPUT` | |","| `--post-flush-command` | Run command after a successful `O` flush, env: `REVDIFF_POST_FLUSH_COMMAND`, config: `post-flush-command` | |","| `--annotations` | Preload annotations from a markdown file in `-o` format | |","| `--history-dir` | Directory for review history auto-saves, env: `REVDIFF_HISTORY_DIR` | `~/.config/revdiff/history/` |","| `--config` | Path to config file, env: `REVDIFF_CONFIG` | `~/.config/revdiff/config` |","| `--keys` | Path to keybindings file, env: `REVDIFF_KEYS` | `~/.config/revdiff/keybindings` |","| `--dump-keys` | Print effective keybindings to stdout and exit | |","| `--dump-config` | Print default config to stdout and exit | |","| `-V`, `--version` | Show version info | |","","### Config File","","All options can be set in a config file at `~/.config/revdiff/config` (INI format). CLI flags and environment variables override config file values. For annotation exit status, use `exit-code-on-annotations = true`.","","Generate a default config file:","","```bash","mkdir -p ~/.config/revdiff","revdiff --dump-config \u003e ~/.config/revdiff/config","```","","Then uncomment and edit the values you want to change.","","### Themes","","revdiff ships with eight bundled color themes: **basic**, **catppuccin-latte**, **catppuccin-mocha**, **dracula**, **gruvbox**, **nord**, **revdiff**, and **solarized-dark**. Themes are stored in `~/.config/revdiff/themes/` and are automatically created on first run.","","Press `T` inside revdiff to open the interactive theme selector with live preview — browse themes, see colors applied instantly, and persist your choice to the config file on confirm.","","```bash","# apply a theme","revdiff --theme dracula","","# choose a theme from the terminal background color","revdiff --theme auto","","# list available themes","revdiff --list-themes","","# re-create bundled theme files (overwrites bundled, keeps custom themes)","revdiff --init-themes","","# install a specific theme from the gallery","revdiff --install-theme catppuccin-latte","","# install all gallery themes (bundled + community)","revdiff --init-all-themes","","# export current colors as a custom theme","revdiff --dump-theme \u003e ~/.config/revdiff/themes/my-custom","```","","**Creating custom themes** — two approaches:","","1. **From current colors:** customize individual colors in your config file or via `--color-*` flags, then dump the resolved result as a theme: `revdiff --dump-theme \u003e ~/.config/revdiff/themes/my-custom`","2. **From scratch:** copy a bundled theme and edit it directly — each file defines all 23 color keys plus `chroma-style` in INI format:","","```ini","# name: my-custom","# description: custom color scheme","chroma-style = dracula","color-accent = #bd93f9","color-border = #6272a4","...all 23 color keys...","```","","Set a default theme in the config file:","","```ini","theme = dracula","```","","Or via environment variable: `REVDIFF_THEME=dracula`.","","Set `theme = auto` to query the terminal background and choose a matching theme. By default, auto mode uses `revdiff` for dark backgrounds and `catppuccin-latte` for light backgrounds:","","```ini","theme = auto","auto-theme-dark = revdiff","auto-theme-light = catppuccin-latte","```","","**Contributing themes** — community themes live in the `themes/gallery/` directory. See [themes/README.md](themes/README.md) for the contribution guide, format requirements, and validation instructions.","","**Precedence:** When `--theme` is set, it takes over completely — all 23 color fields and chroma-style are overwritten by the theme, ignoring any `--color-*` flags or env vars. Without `--theme`: built-in defaults → config file → env vars → CLI flags. `--theme` + `--no-colors` prints a warning and applies the theme.","","\u003cdetails\u003e","\u003csummary\u003eColor customization flags (click to expand)\u003c/summary\u003e","","All color options accept hex values (`#rrggbb`) and have corresponding `REVDIFF_COLOR_*` env vars.","","| Option | Description | Default |","|--------|-------------|---------|","| `--color-accent` | Active pane borders and directory names | `#D5895F` |","| `--color-border` | Inactive pane borders | `#585858` |","| `--color-normal` | File entries and context lines | `#d0d0d0` |","| `--color-muted` | Divider lines and status bar | `#585858` |","| `--color-selected-fg` | Selected file text | `#ffffaf` |","| `--color-selected-bg` | Selected file background | `#D5895F` |","| `--color-annotation` | Annotation text and markers | `#ffd700` |","| `--color-cursor-fg` | Cursor indicator color | `#bbbb44` |","| `--color-cursor-bg` | Cursor indicator background | terminal default |","| `--color-add-fg` | Added line text | `#87d787` |","| `--color-add-bg` | Added line background | `#123800` |","| `--color-remove-fg` | Removed line text | `#ff8787` |","| `--color-remove-bg` | Removed line background | `#4D1100` |","| `--color-word-add-bg` | Intra-line word-diff add background | auto-derived from add-bg |","| `--color-word-remove-bg` | Intra-line word-diff remove background | auto-derived from remove-bg |","| `--color-modify-fg` | Modified line text (collapsed mode) | `#f5c542` |","| `--color-modify-bg` | Modified line background (collapsed mode) | `#3D2E00` |","| `--color-tree-bg` | File tree pane background | terminal default |","| `--color-diff-bg` | Diff pane background | terminal default |","| `--color-status-fg` | Status bar foreground | `#202020` |","| `--color-status-bg` | Status bar background | `#C5794F` |","| `--color-search-fg` | Search match text | `#1a1a1a` |","| `--color-search-bg` | Search match background | `#4a4a00` |","","\u003c/details\u003e","","\u003cdetails\u003e","\u003csummary\u003eAvailable chroma styles (click to expand)\u003c/summary\u003e","","**Dark themes:** `aura-theme-dark`, `aura-theme-dark-soft`, `base16-snazzy`, `catppuccin-frappe`, `catppuccin-macchiato` (default), `catppuccin-mocha`, `doom-one`, `doom-one2`, `dracula`, `evergarden`, `fruity`, `github-dark`, `gruvbox`, `hrdark`, `monokai`, `modus-vivendi`, `native`, `nord`, `nordic`, `onedark`, `paraiso-dark`, `rose-pine`, `rose-pine-moon`, `rrt`, `solarized-dark`, `solarized-dark256`, `tokyonight-moon`, `tokyonight-night`, `tokyonight-storm`, `vim`, `vulcan`, `witchhazel`, `xcode-dark`","","**Light themes:** `autumn`, `borland`, `catppuccin-latte`, `colorful`, `emacs`, `friendly`, `github`, `gruvbox-light`, `igor`, `lovelace`, `manni`, `modus-operandi`, `monokailight`, `murphy`, `paraiso-light`, `pastie`, `perldoc`, `pygments`, `rainbow_dash`, `rose-pine-dawn`, `solarized-light`, `tango`, `tokyonight-day`, `trac`, `vs`, `xcode`","","**Other:** `RPGLE`, `abap`, `algol`, `algol_nu`, `arduino`, `ashen`, `average`, `bw`, `hr_high_contrast`, `onesenterprise`, `swapoff`","","\u003c/details\u003e","","### Examples","","```bash","# review uncommitted changes","revdiff","","# review changes against a branch","revdiff main","","# review staged changes","revdiff --staged","","# review last commit","revdiff HEAD~1 HEAD","","# diff between two refs","revdiff main feature","","# same with git dot-dot syntax","revdiff main..feature","","# review only specific files","revdiff --only=model.go --only=README.md","","# browse all git-tracked files in a project","revdiff --all-files","","# browse all files, excluding vendor and mocks directories","revdiff --all-files --exclude vendor --exclude mocks","","# include only src/ files","revdiff --include src","","# include src/ but exclude src/vendor/","revdiff --include src --exclude src/vendor","","# exclude paths in normal diff mode","revdiff main --exclude vendor","","# review a file outside a VCS repo (context-only, no diff markers)","revdiff --only=/tmp/plan.md","","# review a file that has no VCS changes (context-only view with annotations)","revdiff --only=docs/notes.txt","","# diff two arbitrary files (no VCS repo needed)","revdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md","","# review arbitrary piped text as a scratch buffer","printf '# Plan\\n\\nShip it\\n' | revdiff --stdin --stdin-name plan.md","","# capture annotations from generated output","some-command | revdiff --stdin --output /tmp/annotations.txt","","# round-trip: capture, edit externally, reload","revdiff -o review.md HEAD~1","$EDITOR review.md","revdiff --annotations=review.md HEAD~1","```","","`--annotations` reads the same markdown format that `-o` writes (see [Output Format](#output-format) below), so any file revdiff produces can be loaded back. You can also hand-author or generate that file from any other source — each record is `## path/to/file.go:LINE (+)` followed by the comment body — then step through the comments inline against the actual diff, edit or delete them in the TUI, and quit with `q` to write the final set to stdout (or to `-o`).","","### All-Files Mode","","Use `--all-files` (or `-A`) to browse all tracked files in a project, not just files with changes. This turns revdiff into a general-purpose code annotation tool. All files are shown in context-only mode (no `+`/`-` markers) with full annotation and syntax highlighting support.","","`--all-files` requires a git or jj repository (uses `git ls-files` or `jj file list` for file discovery) and is mutually exclusive with refs, `--staged`, and `--only`. Not supported in hg repos.","","Combine with `--include` (or `-I`) to narrow to specific paths and `--exclude` (or `-X`) to filter out unwanted paths:","","```bash","revdiff --all-files --include src","revdiff --all-files --include src --exclude src/vendor","revdiff --all-files --exclude vendor --exclude mocks","```","","`--include` and `--exclude` both use prefix matching: `--include src` keeps only `src/`, `src/foo.go`, etc. `--exclude vendor` skips `vendor/`, `vendor/foo.go`, etc. Both work in `--all-files` and normal diff modes and are composable: include narrows first, then exclude removes from the included set.","","Both options can be persisted in the config file:","","```ini","include = src","exclude = vendor","exclude = mocks","```","","Or via environment variables (comma-separated): `REVDIFF_INCLUDE=src`, `REVDIFF_EXCLUDE=vendor,mocks`.","","### Context-Only File Review","","When `--only` specifies a file that has no VCS changes (or when no VCS repo exists at all), revdiff shows the file in context-only mode: all lines are displayed without `+`/`-` gutter markers, with full annotation and syntax highlighting support. This enables reviewing arbitrary files without requiring VCS context.","","Two scenarios trigger this mode:","","1. **Inside a repo (git/hg/jj)** - `--only` files not in the diff are read from disk and shown alongside any changed files","2. **Outside a VCS repo** - `--only` is required; files are read directly from disk","","### Two-File Diff","","Use `--compare-old=\u003cpath\u003e` together with `--compare-new=\u003cpath\u003e` to diff two arbitrary files on disk using `git diff --no-index`. No VCS repository is required — this works anywhere `git` is installed.","","```bash","revdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md","revdiff --compare-old=a.txt --compare-new=b.txt","```","","`--compare-old` and `--compare-new` must be used together and are mutually exclusive with refs, `--staged`, `--only`, `--all-files`, `--stdin`, `--include`, `--exclude`, and `--annotations`. All standard diff features work: word-diff, compact mode, syntax highlighting, scrollbar, and inline annotations.","","### Scratch-Buffer Review","","Use `--stdin` to review arbitrary piped or redirected text. revdiff sniffs the input for a git unified-diff signature: when a line beginning with `diff --git a/` is found near the start, the input is parsed as a real multi-file diff (one tree entry per file, with `+`/`-` markers, hunk navigation, word-diff, compact mode, and per-file annotations); otherwise the input is shown as a single context-only buffer with all lines as context, supporting annotations, file-level notes, search, wrap, collapsed mode, and structured output. Any per-section parse failure falls the whole input back to raw-text mode so a malformed patch never silently drops files. Input is capped at 64 MiB.","","`--stdin` is explicit and mutually exclusive with refs, `--staged`, `--only`, `--all-files`, `--include`, `--exclude`, and `--annotations`. stdin mode requires piped or redirected input; plain terminal stdin is rejected to avoid accidentally launching an empty scratch buffer.","","Use `--stdin-name` to control the synthetic filename for the context-only case (it is ignored in multi-file diff mode, where the tree shows the real paths). This gives annotation output a stable key and enables filename-based syntax highlighting or markdown TOC activation:","","```bash","echo \"plain text\" | revdiff --stdin","printf '# Plan\\n\\nBody\\n' | revdiff --stdin --stdin-name plan.md","git show HEAD~1:README.md | revdiff --stdin --stdin-name README.md","","# multi-file diff parsing — tree shows real paths, per-file annotations","gh pr diff 123 | revdiff --stdin","git format-patch -1 --stdout | revdiff --stdin","```","","### Review Description","","Use `--description` (or `--description-file=path.md`) to attach prose context to a review. The text is rendered at the top of the info popup (`i` key), with the same markdown highlighting used for `.md` files in the diff view. Useful when an agent (or a script) launches revdiff on your behalf and you come back to it later — the popup tells you what the change is and why.","","```bash","revdiff HEAD~3 --description=\"# Refactor auth middleware","","Drop session-token storage to meet new compliance requirements.","See ticket SEC-441 for context.\"","","# longer descriptions: keep the markdown in a file","revdiff HEAD~3 --description-file=.review-description.md","```","","`--description` and `--description-file` are mutually exclusive. The description section is hidden when neither is set, so the flag is purely additive — existing invocations are unchanged.","","### Markdown TOC Navigation","","When reviewing a single markdown file in context-only mode (e.g., `revdiff --only=README.md` or `printf '# title\\n' | revdiff --stdin --stdin-name plan.md`), revdiff shows a table-of-contents pane on the left listing all markdown headers. Use `Tab` to switch focus between the TOC and diff panes, `j`/`k` to navigate headers, and `Enter` to jump to a header in the diff. The TOC automatically highlights the current section as you scroll through the file.","","This mode activates when all three conditions are met: single file, markdown extension (`.md`/`.markdown`), and all lines are context (no diff changes). Headers inside fenced code blocks are excluded from the TOC.","","### Beyond Code Review","","The `--only` flag enables use cases beyond VCS diffs. Any text file can be loaded for annotation — no VCS repo required.","","**Reviewing AI-generated drafts** — When an AI assistant drafts text to be posted publicly (PR comments, issue responses, release notes), write it to a temp file and review in revdiff. Annotate specific lines with changes, the assistant reads annotations and rewrites, re-open to verify. Same annotate-fix-verify loop as code review.","","**Reviewing documentation and specs** — Markdown files, API specs, config files, and plan documents can all be reviewed with inline annotations. Useful for reviewing RFCs, annotating configs before deployment, or marking up plans with questions.","","```bash","revdiff --only=docs/plans/feature.md","revdiff --only=/tmp/draft-comment.md","```","","**Reviewing generated output** — CI configs, Terraform plans, generated migrations, or command output. Load files with `--only` or stream ephemeral output with `--stdin`, annotate what needs fixing, feed annotations back to the generator.","","### Zed Integration","","Zed's [custom tasks](https://zed.dev/docs/tasks) can launch revdiff directly in an editor terminal tab.","","See the [Zed integration guide](https://revdiff.com/docs.html#zed-integration) for ready-to-use task definitions, keybinding setup, and platform-specific clipboard notes.","","### Review History","","When you quit with annotations (`q`), revdiff automatically saves a copy of the review session to `~/.config/revdiff/history/\u003crepo-name\u003e/\u003ctimestamp\u003e.md`. This is a safety net — if annotations are lost (process crash, agent fails to capture stdout), the history file preserves them.","","Each history file contains:","- Header with path, refs, and (git only) a short commit hash","- Full annotation output (same format as stdout)","- Raw git diff for annotated files only","","History auto-save is always on and silent — errors are logged to stderr, never fail the process. No history is saved on discard quit (`Q`) or when there are no annotations. For `--stdin` mode, files are saved under `stdin/` subdirectory; for `--only` without git, the parent directory name is used instead of a repo name.","","The history file is also a crash-recovery save when the process is terminated by a signal — a SIGHUP from a dropped SSH or tmux client, or a SIGTERM. On a signal exit only the history file is written, never the `-o` output, because a signal is not the deliberate handoff that `q` and `O` perform. Recover the annotations the usual way — load the newest history file. A signal-delivered SIGTERM previously wrote the `-o` output; it no longer does.","","Override the history directory with `--history-dir`, `REVDIFF_HISTORY_DIR` env var, or `history-dir` in the config file.","","In the Claude Code and Codex plugins, you can also tell the agent to use a past review by saying things like \"locate my latest revdiff review\" or \"use the annotations from the review I just did in another terminal\". The plugin reads the newest history file for the current repo via the helper script `read-latest-history.sh` and processes the annotations as if they had come from a fresh launcher call. This is useful for standalone revdiff runs outside the plugin, or when the live launcher output is unavailable (e.g., a broken custom launcher or a crashed agent).","","### Key Bindings","","**Navigation:**","","| Key | Action |","|-----|--------|","| `j/k` or up/down | Navigate files (tree) / scroll diff (diff pane); with `--cross-file-motion`, continues to the previous/next file at the boundary |","| `h/l` | Switch between file tree and diff pane |","| left/right | Horizontal scroll in diff pane (truncated lines show `«` / `»` overflow indicators at the edges) |","| `Tab` | Switch between file tree and diff pane |","| `PgDown/PgUp` | Page scroll in file tree and diff pane; with `--cross-file-motion`, continues to the previous/next file at the boundary |","| `Ctrl+d/Ctrl+u` | Half-page scroll in file tree and diff pane; with `--cross-file-motion`, continues to the previous/next file at the boundary |","| `J/K` | Scroll diff viewport (works from either pane) |","| `Home/End` | Jump to first/last item |","| `Enter` | Switch to diff pane (tree) / start annotation (diff pane) |","| `n/p` | Next/previous changed file; next/prev header in markdown TOC mode (n = next match when search active) |","| `P` | Open the file picker |","| `[` / `]` | Jump to previous/next change hunk in diff; add `--cross-file-hunks` to continue into the previous/next file at the boundary |","| `e` | Open focused file in `$EDITOR` |","","The file picker lists paths currently visible in the sidebar, so annotated-only and unreviewed-only filters remain active. Printable keys always filter full relative paths; use the arrow keys or mouse wheel to move, and press `Enter` or left-click to jump. `Backspace` edits the filter. The first `Esc` clears a non-empty filter and keeps the picker open; the second closes it. Because printable keys always filter, `P` typed inside the picker adds to the filter rather than closing it; a `jump_file` binding with a modifier (e.g. `map alt+f jump_file`) closes the picker when pressed again.","","**Search:**","","| Key | Action |","|-----|--------|","| `/` | Start search in diff pane |","| `n` | Next search match (overrides next file when search active) |","| `N` | Previous file (previous search match when searching) |","| `↑` / `Ctrl+P` | Recall previous search query (in search prompt) |","| `↓` / `Ctrl+N` | Recall next search query / clear (in search prompt) |","| `Esc` | Cancel search input / clear search results |","","**Annotations:**","","| Key | Action |","|-----|--------|","| `a` or `Enter` (diff pane) | Annotate current diff line |","| `A` | Add file-level annotation (stored at top of diff) |","| `@` | Toggle annotation list popup (navigate and jump to any annotation) |","| `}` / `{` | Jump to next/previous annotation (always crosses file boundaries; silent no-op at the first/last annotation) |","| `d` | Delete annotation under cursor |","| `O` | Export annotations without exiting (requires `--output` and/or `--post-flush-command`) |","| `Ctrl+E` (during annotation input) | Open `$EDITOR` for multi-line annotation (`open_editor` — rebindable) |","| `Esc` | Cancel annotation input |","","While the annotation input is active, press `Ctrl+E` (or whatever key is bound to `open_editor`) to hand off the current text to an external editor for multi-line comments. Editor resolution: `$EDITOR` → `$VISUAL` → `vi`. Values with arguments work (e.g. `EDITOR=\"code --wait\"`). On editor save and quit, the full file contents (including newlines) become the annotation. Quitting the editor with an empty file cancels the annotation and preserves any previously stored note on that line. Multi-line annotations are rendered line-by-line in the diff view, shown flattened in the annotation list popup (`@`), and emitted with embedded newlines in the structured output.","","Press `e` in the diff pane to open the focused file in `$EDITOR` (`open_file_in_editor` — rebindable) when revdiff has a stable source path. Editor resolution is the same `$EDITOR` → `$VISUAL` → `vi` chain. Known editors receive either `$EDITOR +N path` or `$EDITOR --goto path:N` as appropriate; unknown editors receive only the file path. File lines are resolved on a best-effort basis. For working tree changes, a clean editor exit reloads the displayed file. For `--staged` or refs, a clean editor exit returns to revdiff without reloading the displayed diff. In compare mode, `e` opens the `--compare-new` side. Working tree files with line annotations cannot be opened for editing because edits can orphan those annotations. Diffs read with `--stdin` do not support opening files. Unsupported rows or files and editor errors show a status hint instead of launching an editor or changing the diff.","","Press `O` to export the current annotations without exiting (`flush_output`, rebindable). Configure `--output`, `--post-flush-command`, or both. With `--output`, each flush atomically overwrites the file with the full current annotation set (a snapshot, not an append log). With `--post-flush-command`, the same snapshot is sent to the command on stdin. If neither is configured, or if there are no annotations, revdiff shows a status hint and does nothing.","","The output file supports a keep-open review loop with an AI agent: annotate, flush with `O`, let the agent read the file and edit code, then reload with `R` and continue in the same session.","","For a local clipboard-only workflow on macOS, set this in `~/.config/revdiff/config`:","","```ini","post-flush-command = pbcopy","```","","Each `O` copies the full current annotation set without requiring `--output`. On Linux, use `xclip -selection clipboard` for X11 or `wl-copy` for Wayland.","","For a terminal clipboard over SSH or a multiplexer, use OSC 52. revdiff does not include an OSC 52 helper; create an `osc-copy` shell script on your `PATH` that reads stdin and writes the clipboard sequence to `/dev/tty`:","","```sh","#!/bin/sh","data=$(base64 | tr -d '\\n')","printf '\\033]52;c;%s\\007' \"$data\" \u003e /dev/tty","```","","After making the script executable, run revdiff with `--post-flush-command=osc-copy` or set `post-flush-command = osc-copy` in the config file. No output file is required; add `--output` only when the same flush should also write a snapshot file.","","The post-flush command runs synchronously. Use a fast, non-interactive command because revdiff waits for it to finish before restoring the TUI.","","Press `Space` to mark the focused file reviewed. Press `F` to toggle the sidebar between all files and unreviewed files; while filtered, marking a file reviewed removes it from the list and advances to the next unfinished file. On `R` reload, revdiff keeps the mark only when the file's effective text diff is unchanged; rebases that only shift line numbers or surrounding context keep it, while changed or removed files lose it. Binary files and opaque placeholders are conservatively unmarked on reload because their rendered diff does not expose enough content to prove they are unchanged.","","**View:**","","| Key | Action |","|-----|--------|","| `v` | Toggle collapsed diff mode (shows final text with change markers) |","| `C` | Toggle compact diff view (small context around changes, re-fetches current file) |","| `w` | Toggle word wrap (long lines wrap with `↪` continuation markers) |","| `t` | Toggle tree/TOC pane visibility (gives diff full terminal width) |","| `L` | Toggle line numbers (side-by-side old/new for diffs, single column for full-context files) |","| `B` | Toggle blame gutter (author name + commit age per line) |","| `W` | Toggle intra-line word-diff highlighting for paired add/remove lines |","| `.` | Expand/collapse individual hunk under cursor (collapsed mode only) |","| `T` | Open theme selector with live preview |","| `f` | Toggle filter: all files / annotated only (shown when annotations exist) |","| `F` | Toggle filter: all files / unreviewed only |","| `?` | Toggle help overlay showing all keybindings |","| `i` | Toggle info popup — review scope (mode, VCS, ref, filters, file/status counts, aggregate `+/-` stats) plus the commit log for the current ref range when applicable |","| `R` | Reload diff from VCS (warns if annotations exist) |","| `q` | Quit, output annotations to stdout |","| `Q` | Discard all annotations and quit (confirms if annotations exist) |","","### Status Bar Icons","","The status bar shows a fixed row of mode indicators on the right side. All slots are always rendered — active modes use the status bar foreground color, inactive modes use muted gray, so the row occupies the same width regardless of what's toggled on. The help overlay (`?`) shows each icon beside the key that controls it.","","| Icon | Toggle | Meaning |","|------|--------|---------|","| `▼` | `v` | Collapsed diff mode |","| `⊂` | `C` | Compact diff mode (small context around changes) |","| `◉` | `f` | Filter: annotated files only |","| `↩` | `w` | Word wrap mode |","| `≋` | `/` | Search active |","| `⊟` | `t` | Tree/TOC pane hidden (diff uses full width) |","| `#` | `L` | Line numbers visible in gutter |","| `b` | `B` | Blame gutter visible |","| `±` | `W` | Intra-line word-diff highlighting |","| `✓` / `○` | `Space` / `F` | Reviewed files / unreviewed-only filter active |","| `∅` | `u` | Untracked files visible in tree |","","On narrow terminals, the left-hand segments are dropped before the icons: search position first, then line and hunk info, then the filename truncates. The icon row on the right stays put.","","### Mouse Support","","revdiff enables mouse tracking by default so the scroll wheel and left-click work consistently across terminals.","","- **Scroll wheel**: scrolls whichever pane the cursor is over. In the tree/TOC pane the wheel moves the cursor one entry per notch (matches `j`/`k`). In the diff pane the wheel scrolls the viewport by three lines per notch — the diff cursor stays on its current logical line and is pinned to the visible edge if scrolling pushes it off-screen. During fast scrolls (a trackpad flick) the cursor highlight catches up after a brief pause once the burst settles, matching less/vim behavior.","- **Shift+scroll**: half-page scroll in the diff pane. In the tree/TOC pane Shift+wheel behaves the same as plain wheel (one entry per notch — no page step).","- **Left-click in the tree**: focuses the tree and selects/loads the clicked entry (same as pressing `j`/`k` to land there). Clicking a directory row moves the cursor but does not load a file.","- **Left-click in the diff**: focuses the diff and moves the cursor to the clicked line. Enables a \"click, then `a`\" annotation flow.","- **Left-click in the TOC pane** (single-file markdown): focuses the TOC and selects the clicked header.","- **Scroll wheel in overlay popups** (info, annotations, themes, help): scrolls the popup content or moves its cursor. Shift+wheel uses a half-page step. In the theme selector, wheel previews each theme live.","- **Left-click in the annotation popup**: jumps to the clicked annotation (same as pressing `Enter`).","- **Left-click in the theme popup**: confirms the clicked theme (same as pressing `Enter`). Clicks on the filter row or blank separator are ignored.","- **Left-click in the file picker**: jumps to the clicked file (same as pressing `Enter`). Clicks on the filter row or blank separator are ignored.","- **Scroll wheel in the file picker**: moves the picker cursor. Shift+wheel uses a half-page step.","","Horizontal wheel, right-click, middle-click, drag selection, and clicks on the status bar or diff header are intentionally ignored. Clicks outside an open overlay are swallowed — dismiss an overlay with `Esc` or its toggle key. Modal states (annotation input, search input, confirm discard, reload confirm) swallow mouse events entirely.","","**Text selection trade-off** — once mouse tracking is on, plain drag is captured by revdiff. For terminal-native text selection:","","- **kitty**: hold `Ctrl+Shift` while dragging","- **iTerm2**: hold `Option` while dragging","- **ghostty** (and ghostty-based terminals such as agterm): hold `Shift` while dragging. Ghostty also uses `Shift` to *extend* an existing selection, so if text is already selected the drag grows that selection instead of starting a new one - clear it first. Ghostty 1.3.0+ additionally has a `toggle_mouse_reporting` keybind, unbound by default, which suspends mouse capture without restarting revdiff","- **most other terminals**: hold `Shift` while dragging","","Because the tree pane is rendered alongside the diff on the same rows, multi-line Shift+drag will include tree content. For clean copies of diff text, use your terminal's block-select mode (Option+drag in iTerm2, Ctrl+Shift+drag in kitty) or run with `--no-mouse` to disable mouse capture entirely.","","Opt out with `--no-mouse`, `REVDIFF_NO_MOUSE=true`, or `no-mouse = true` in the config file.","","### Custom Keybindings","","All keybindings can be customized via a keybindings file at `~/.config/revdiff/keybindings`. Override the path with `--keys` flag or `REVDIFF_KEYS` env var.","","The file uses a simple `map`/`unmap` format (blank lines and `#` comments are ignored):","","```","# ~/.config/revdiff/keybindings","map ctrl+d half_page_down","map ctrl+u half_page_up","map x quit","unmap q","```","","- `map \u003ckey\u003e \u003caction\u003e` — binds a key to an action (additive, defaults are kept unless explicitly unmapped)","- `unmap \u003ckey\u003e` — removes a default binding","","Generate a template with all current bindings:","","```bash","mkdir -p ~/.config/revdiff","revdiff --dump-keys \u003e ~/.config/revdiff/keybindings","```","","Then edit to taste. Fixed modal keys (Enter, Esc in annotation/search input, confirm discard) are not remappable. Keymap-resolved actions like `open_editor` work during annotation input and can be rebound.","","**Paging the diff from the file tree:** `J`/`K` scroll the diff viewport from either pane, but only by a few lines, while `PgDown`/`PgUp` and `Ctrl+d`/`Ctrl+u` stay pane-relative and page whichever pane has focus. The `scroll_diff_page_*` and `scroll_diff_half_page_*` actions are the page-sized versions of `J`/`K` — they ship with no default key, so bind them to get lazygit-style paging that always targets the diff:","","```","map pgdown scroll_diff_page_down","map pgup scroll_diff_page_up","map ctrl+d scroll_diff_half_page_down","map ctrl+u scroll_diff_half_page_up","```","","Three consequences worth knowing. This also replaces cursor paging while the diff pane has focus: the keys scroll the viewport and pin the cursor back into view instead of walking the cursor a page at a time. The file tree and markdown TOC lose their own page-sized traversal on those keys. And because `page_down`, `page_up`, `half_page_down` and `half_page_up` have no other default key, rebinding all four lines leaves them unbound everywhere, including the `?` help and `i` info overlays, which page through the same actions. Omit one pair of mapping lines to keep its default paging. Because they have no default binding, these actions appear in neither the `?` help overlay nor `--dump-keys` until you bind them.","","**Chord bindings (ctrl/alt leader):** bind a two-stage chord by joining the leader and second key with `\u003e`. The leader must be a `ctrl+*` or `alt+*` combo; the second stage is any single key. Only two stages are supported.","","```","map ctrl+w\u003ex mark_reviewed","map alt+t\u003en theme_select","```","","When the leader is pressed, the status bar shows `Pending: ctrl+w, esc to cancel`; press the second key to dispatch, or `esc` to cancel silently. Binding a key as both a standalone action and a chord prefix drops the standalone binding (the chord wins, with a warning). Chord bindings work under non-Latin keyboard layouts — the second-stage key is translated via the same layout-resolve fallback as single-key bindings. Note: chord bindings do not fire during text input (annotation and search prompts) — the leader key is consumed by the text input widget. Use single-key `ctrl+*` bindings for actions like `open_editor` that need to work during annotation input.","","**macOS note:** `alt+*` leaders require your terminal to send Option as Meta/Alt. Most terminals default to \"Option composes special characters\" (e.g. `Option+T` → `†`), in which case Alt chords silently won't fire. To enable: iTerm2 → *Profiles → Keys → Left/Right Option key → `Esc+`*; Terminal.app → *Profiles → Keyboard → Use Option as Meta key*; Kitty → `macos_option_as_alt yes`; Ghostty → `macos-option-as-alt = true`. If you'd rather not touch terminal settings, use `ctrl+*` leaders — those work everywhere with no configuration.","","\u003cdetails\u003e","\u003csummary\u003eAvailable actions (click to expand)\u003c/summary\u003e","","**Navigation:** `down`, `up`, `page_down`, `page_up`, `half_page_down`, `half_page_up`, `home`, `end`, `scroll_left`, `scroll_right`, `scroll_center`, `scroll_top`, `scroll_bottom`, `scroll_diff_down`, `scroll_diff_up`, `scroll_diff_page_down`, `scroll_diff_page_up`, `scroll_diff_half_page_down`, `scroll_diff_half_page_up`","","**File/Hunk:** `next_item`, `prev_item`, `jump_file`, `next_hunk`, `prev_hunk`, `open_file_in_editor`","","**Pane:** `toggle_pane`, `focus_tree`, `focus_diff`","","**Search:** `search`","","**Annotations:** `confirm` (annotate line / select file), `annotate_file`, `delete_annotation`, `annot_list`, `open_editor`, `next_annotation`, `prev_annotation`, `flush_output`","","**View:** `toggle_collapsed`, `toggle_compact`, `toggle_wrap`, `toggle_tree`, `toggle_line_numbers`, `toggle_blame`, `toggle_word_diff`, `toggle_hunk`, `toggle_untracked`, `mark_reviewed`, `filter_unreviewed`, `theme_select`, `filter`, `info`, `reload`","","**Quit:** `quit`, `discard_quit`, `help`, `dismiss`","","\u003c/details\u003e","","### Vim-motion Preset","","Opt-in vim-style motion layer activated via `--vim-motion`, `REVDIFF_VIM_MOTION=true`, or `vim-motion = true` in the config file. Off by default — when off, existing single-key bindings are unchanged.","","| Keys | Action |","|------|--------|","| `\u003cN\u003ej` / `\u003cN\u003ek` | Move cursor N lines down/up (diff pane, 1-9999) |","| `gg` | Jump to first line (diff pane) |","| `G` | Jump to last line (diff pane) |","| `\u003cN\u003eG` | Goto line N (diff pane) |","| `H` / `\u003cN\u003eH` | Cursor to top of screen / Nth line from top (diff pane) |","| `M` | Cursor to middle of screen (diff pane) |","| `L` / `\u003cN\u003eL` | Cursor to bottom of screen / Nth line from bottom (diff pane) |","| `zz` | Center viewport on cursor (diff pane) |","| `zt` | Align viewport top on cursor (diff pane) |","| `zb` | Align viewport bottom on cursor (diff pane) |","| `ZZ` | Quit (any pane) |","| `ZQ` | Discard annotations and quit (any pane) |","","When the preset is on, the digits `0`-`9` and the leader keys `g`, `z`, `Z` are intercepted before the regular keymap, so any standalone binding on those keys is overridden while the flag is active. `\u003cN\u003ej`/`\u003cN\u003ek`/`\u003cN\u003eG`, `gg`/`zz`/`zt`/`zb`, and the screen-position motions `H`/`M`/`L` apply to the diff pane only — in the file tree they fall through to the normal bindings. `ZZ` and `ZQ` work from any pane. While the preset is active `L` is a screen-position motion rather than the line-numbers toggle (`toggle_line_numbers`); remap it in the keybindings file if you need both. Press `Esc` to silently cancel a pending leader; an unknown second key surfaces a transient `Unknown: \u003cchord\u003e` hint in the status bar. A bare digit `0` is not consumed (falls through to whatever binding is mapped); counts over 9999 are clamped. Modal keys (search input, annotation input, overlay navigation) always take precedence over the interceptor, and `ctrl+*`/`alt+*` chord bindings keep working orthogonally.","","The help overlay (`?`) shows a dedicated **Vim motion** section listing all eleven preset bindings when `--vim-motion` is on; when off, the section is hidden.","","### Output Format","","```","## handler.go (file-level)","consider splitting this file into smaller modules","","## handler.go:43 (+)","use errors.Is() instead of direct comparison","","## handler.go:43-67 (+)","refactor this hunk to reduce nesting","","## store.go:18 (-)","don't remove this validation","```","","When annotation text contains the keyword \"hunk\" (case-insensitive, whole word), the output header automatically expands to include the full hunk line range (e.g., `handler.go:43-67 (+)` instead of `handler.go:43 (+)`). This gives AI consumers the range context without any extra steps.","","Comment body lines starting with `## ` (the record-header form) are prefixed with a single space on output so parsers that split on `## ` record headers cannot confuse a multi-line comment for a new record.","","## Contributing","","See [CONTRIBUTING.md](CONTRIBUTING.md) for details.","","## License","","MIT License - see [LICENSE](LICENSE) file for details."],"stylingDirectives":[[[0,583,"pl-mh"],[2,583,"pl-en"],[3,6,"pl-ent"],[7,10,"pl-e"],[11,12,"pl-s"],[12,32,"pl-s"],[32,33,"pl-s"],[34,37,"pl-e"],[38,39,"pl-s"],[39,40,"pl-s"],[41,46,"pl-e"],[47,48,"pl-s"],[48,50,"pl-s"],[50,51,"pl-s"],[52,58,"pl-c1"],[53,57,"pl-k"],[66,72,"pl-c1"],[67,71,"pl-k"],[73,74,"pl-ent"],[75,79,"pl-e"],[80,81,"pl-s"],[81,140,"pl-s"],[140,141,"pl-s"],[143,146,"pl-ent"],[147,150,"pl-e"],[151,152,"pl-s"],[152,221,"pl-s"],[221,222,"pl-s"],[223,226,"pl-e"],[227,228,"pl-s"],[228,233,"pl-s"],[233,234,"pl-s"],[237,238,"pl-ent"],[241,242,"pl-ent"],[243,247,"pl-e"],[248,249,"pl-s"],[249,306,"pl-s"],[306,307,"pl-s"],[309,312,"pl-ent"],[313,316,"pl-e"],[317,318,"pl-s"],[318,391,"pl-s"],[391,392,"pl-s"],[393,396,"pl-e"],[397,398,"pl-s"],[398,413,"pl-s"],[413,414,"pl-s"],[417,418,"pl-ent"],[421,422,"pl-ent"],[423,427,"pl-e"],[428,429,"pl-s"],[429,487,"pl-s"],[487,488,"pl-s"],[490,493,"pl-ent"],[494,497,"pl-e"],[498,499,"pl-s"],[499,556,"pl-s"],[556,557,"pl-s"],[558,561,"pl-e"],[562,563,"pl-s"],[563,577,"pl-s"],[577,578,"pl-s"],[581,582,"pl-ent"]],[],[],[],[],[],[[0,11,"pl-mh"],[3,11,"pl-en"]],[],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[159,160,"pl-s"],[160,171,"pl-c1"],[171,172,"pl-s"],[188,189,"pl-s"],[189,190,"pl-c1"],[190,191,"pl-s"]],[[0,1,"pl-v"],[73,74,"pl-s"],[74,75,"pl-c1"],[75,76,"pl-s"]],[[0,1,"pl-v"],[61,62,"pl-s"],[62,63,"pl-c1"],[63,64,"pl-s"],[99,100,"pl-s"],[100,101,"pl-c1"],[101,102,"pl-s"],[113,114,"pl-s"],[114,129,"pl-c1"],[129,130,"pl-s"]],[[0,1,"pl-v"],[23,24,"pl-s"],[24,40,"pl-c1"],[40,41,"pl-s"]],[[0,1,"pl-v"],[67,68,"pl-s"],[68,69,"pl-c1"],[69,70,"pl-s"],[73,74,"pl-s"],[74,75,"pl-c1"],[75,76,"pl-s"]],[[0,1,"pl-v"],[38,39,"pl-s"],[39,40,"pl-c1"],[40,41,"pl-s"]],[[0,1,"pl-v"],[117,118,"pl-s"],[118,119,"pl-c1"],[119,120,"pl-s"]],[[0,1,"pl-v"],[87,88,"pl-s"],[88,97,"pl-c1"],[97,98,"pl-s"]],[[0,1,"pl-v"],[81,82,"pl-s"]],[[0,1,"pl-v"],[112,113,"pl-s"],[113,117,"pl-c1"],[117,118,"pl-s"],[121,122,"pl-s"],[122,124,"pl-c1"],[124,125,"pl-s"],[127,128,"pl-s"],[128,134,"pl-c1"],[134,135,"pl-s"],[138,139,"pl-s"],[139,140,"pl-c1"],[140,141,"pl-s"],[160,161,"pl-s"],[161,172,"pl-c1"],[172,173,"pl-s"]],[[0,1,"pl-v"],[71,72,"pl-s"],[72,73,"pl-c1"],[73,74,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[12,13,"pl-s"],[13,14,"pl-c1"],[14,15,"pl-s"],[40,41,"pl-s"],[41,42,"pl-c1"],[42,43,"pl-s"],[44,45,"pl-s"],[45,46,"pl-c1"],[46,47,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[25,26,"pl-s"],[26,27,"pl-c1"],[27,28,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[16,17,"pl-s"],[17,18,"pl-c1"],[18,19,"pl-s"]],[[0,1,"pl-v"],[14,15,"pl-s"],[15,16,"pl-c1"],[16,17,"pl-s"],[96,97,"pl-s"],[97,100,"pl-c1"],[100,101,"pl-s"],[128,129,"pl-s"],[129,142,"pl-c1"],[142,143,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[61,62,"pl-s"],[62,73,"pl-c1"],[73,74,"pl-s"],[80,81,"pl-s"],[81,89,"pl-c1"],[89,90,"pl-s"],[97,98,"pl-s"],[98,107,"pl-c1"],[107,108,"pl-s"],[123,124,"pl-s"],[124,133,"pl-c1"],[133,134,"pl-s"],[139,140,"pl-s"],[140,149,"pl-c1"],[149,150,"pl-s"]],[[0,1,"pl-v"],[22,23,"pl-s"],[23,29,"pl-c1"],[29,30,"pl-s"]],[[0,1,"pl-v"],[74,75,"pl-s"],[75,82,"pl-c1"],[82,83,"pl-s"],[111,112,"pl-s"],[112,124,"pl-c1"],[124,125,"pl-s"],[232,233,"pl-s"],[233,243,"pl-c1"],[243,244,"pl-s"],[248,249,"pl-s"],[249,277,"pl-c1"],[277,278,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[54,55,"pl-s"],[55,81,"pl-c1"],[81,82,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[74,75,"pl-s"],[75,86,"pl-c1"],[86,87,"pl-s"]],[],[[0,2,"pl-s"],[20,21,"pl-s"],[21,22,"pl-s"],[22,48,"pl-corl"],[48,49,"pl-s"]],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[9,10,"pl-s"],[10,12,"pl-c1"],[12,13,"pl-s"],[18,19,"pl-s"],[19,21,"pl-c1"],[21,22,"pl-s"],[68,69,"pl-s"],[69,75,"pl-c1"],[75,76,"pl-s"],[80,81,"pl-s"],[81,88,"pl-c1"],[88,89,"pl-s"]],[[0,1,"pl-v"],[68,69,"pl-s"],[69,88,"pl-c1"],[88,89,"pl-s"]],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[0,2,"pl-s"],[25,27,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[19,21,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[23,25,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,69,"pl-c"],[0,1,"pl-c"]],[[21,22,"pl-k"]],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[33,35,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,69,"pl-c"],[0,1,"pl-c"]],[[20,21,"pl-k"]],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[5,7,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,3,"pl-s"]],[],[[13,14,"pl-s"],[14,21,"pl-c1"],[21,22,"pl-s"],[35,36,"pl-s"],[36,41,"pl-c1"],[41,42,"pl-s"],[56,57,"pl-s"],[57,77,"pl-c1"],[77,78,"pl-s"],[108,109,"pl-s"],[109,113,"pl-c1"],[113,114,"pl-s"]],[],[[0,2,"pl-s"],[18,20,"pl-s"],[35,36,"pl-s"],[51,52,"pl-s"],[52,53,"pl-s"],[53,96,"pl-corl"],[96,97,"pl-s"]],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[],[],[],[],[[0,1,"pl-ml"],[11,12,"pl-ml"],[28,29,"pl-ml"],[40,41,"pl-ml"]],[[0,1,"pl-ml"],[11,12,"pl-ml"],[27,28,"pl-ml"],[39,40,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[10,12,"pl-s"],[13,14,"pl-ml"],[15,16,"pl-s"],[16,56,"pl-c1"],[56,57,"pl-s"],[97,98,"pl-ml"],[99,100,"pl-s"],[100,118,"pl-c1"],[118,119,"pl-s"],[128,129,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[8,10,"pl-s"],[11,12,"pl-ml"],[13,14,"pl-s"],[14,27,"pl-c1"],[27,28,"pl-s"],[49,50,"pl-ml"],[51,52,"pl-s"],[52,57,"pl-c1"],[57,58,"pl-s"],[67,68,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[10,12,"pl-s"],[13,14,"pl-ml"],[15,16,"pl-s"],[16,37,"pl-c1"],[37,38,"pl-s"],[39,40,"pl-ml"],[41,42,"pl-s"],[42,49,"pl-c1"],[49,50,"pl-s"],[59,60,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[9,11,"pl-s"],[12,13,"pl-ml"],[14,15,"pl-s"],[15,31,"pl-c1"],[31,32,"pl-s"],[35,36,"pl-s"],[36,50,"pl-c1"],[50,51,"pl-s"],[75,76,"pl-s"],[76,92,"pl-c1"],[92,93,"pl-s"],[99,100,"pl-s"],[100,120,"pl-c1"],[120,121,"pl-s"],[122,123,"pl-ml"],[124,125,"pl-s"],[125,135,"pl-c1"],[135,136,"pl-s"],[145,146,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[9,11,"pl-s"],[12,13,"pl-ml"],[14,15,"pl-s"],[15,44,"pl-c1"],[44,45,"pl-s"],[46,47,"pl-ml"],[48,49,"pl-s"],[49,65,"pl-c1"],[65,66,"pl-s"],[75,76,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[11,13,"pl-s"],[14,15,"pl-ml"],[16,17,"pl-s"],[17,39,"pl-c1"],[39,40,"pl-s"],[41,42,"pl-ml"],[43,44,"pl-s"],[44,57,"pl-c1"],[57,58,"pl-s"],[67,68,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[8,10,"pl-s"],[11,12,"pl-ml"],[13,14,"pl-s"],[14,33,"pl-c1"],[33,34,"pl-s"],[57,58,"pl-ml"],[59,60,"pl-s"],[60,73,"pl-c1"],[73,74,"pl-s"],[83,84,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[8,10,"pl-s"],[11,12,"pl-ml"],[13,14,"pl-s"],[14,28,"pl-c1"],[28,29,"pl-s"],[32,33,"pl-s"],[33,42,"pl-c1"],[42,43,"pl-s"],[44,45,"pl-ml"],[46,47,"pl-s"],[47,63,"pl-c1"],[63,64,"pl-s"],[66,67,"pl-s"],[67,104,"pl-c1"],[104,105,"pl-s"],[110,111,"pl-s"],[111,132,"pl-c1"],[132,133,"pl-s"],[136,137,"pl-s"],[137,152,"pl-c1"],[152,153,"pl-s"],[165,166,"pl-s"],[166,174,"pl-c1"],[174,175,"pl-s"],[176,177,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[11,13,"pl-s"],[14,15,"pl-ml"],[54,55,"pl-ml"],[56,57,"pl-s"],[57,70,"pl-c1"],[70,71,"pl-s"],[92,93,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[10,12,"pl-s"],[13,14,"pl-ml"],[15,16,"pl-s"],[16,25,"pl-c1"],[25,26,"pl-s"],[51,52,"pl-ml"],[53,54,"pl-s"],[54,71,"pl-c1"],[71,72,"pl-s"],[81,82,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[15,17,"pl-s"],[18,19,"pl-ml"],[34,35,"pl-s"],[35,46,"pl-c1"],[46,47,"pl-s"],[48,49,"pl-ml"],[50,51,"pl-s"],[51,64,"pl-c1"],[64,65,"pl-s"],[74,75,"pl-ml"]],[],[],[],[[0,288,"pl-ent"],[0,2,"pl-ent"],[2,4,"pl-s"],[9,11,"pl-s"],[49,50,"pl-s"],[50,66,"pl-c1"],[66,67,"pl-s"],[76,77,"pl-s"],[77,114,"pl-c1"],[114,115,"pl-s"],[120,121,"pl-s"],[121,142,"pl-c1"],[142,143,"pl-s"],[146,147,"pl-s"],[147,162,"pl-c1"],[162,163,"pl-s"],[173,174,"pl-s"],[174,182,"pl-c1"],[182,183,"pl-s"],[219,220,"pl-s"],[220,229,"pl-c1"],[229,230,"pl-s"],[233,234,"pl-s"],[234,248,"pl-c1"],[248,249,"pl-s"]],[[0,0,"pl-ent"]],[[0,260,"pl-ent"],[0,2,"pl-ent"],[2,4,"pl-s"],[9,11,"pl-s"]],[[0,0,"pl-ent"]],[[0,240,"pl-ent"],[0,2,"pl-ent"],[2,4,"pl-s"],[9,11,"pl-s"],[45,46,"pl-s"],[46,55,"pl-c1"],[55,56,"pl-s"],[185,186,"pl-s"],[186,202,"pl-c1"],[202,203,"pl-s"],[224,225,"pl-s"],[225,238,"pl-c1"],[238,239,"pl-s"]],[[0,1,"pl-ent"],[0,1,"pl-ent"]],[[0,9,"pl-ent"],[0,2,"pl-ent"],[2,5,"pl-s"],[5,9,"pl-en"]],[[0,3,"pl-ent"],[0,3,"pl-ii"]],[[0,16,"pl-ent"],[0,16,"pl-ii"]],[[0,50,"pl-ent"],[0,50,"pl-ii"]],[[0,5,"pl-ent"],[0,5,"pl-ii"]],[[0,3,"pl-ent"],[0,3,"pl-ii"]],[[0,5,"pl-ent"],[0,5,"pl-ii"]],[[0,1,"pl-ent"],[0,1,"pl-ii"]],[[0,129,"pl-ent"],[0,129,"pl-ii"]],[[0,0,"pl-ent"]],[[0,431,"pl-ent"],[0,431,"pl-ii"]],[[0,0,"pl-ent"]],[[0,602,"pl-ent"],[0,602,"pl-ii"]],[[0,0,"pl-ent"]],[[0,513,"pl-ent"],[0,513,"pl-ii"]],[[0,0,"pl-ent"]],[[0,12,"pl-ent"],[0,12,"pl-ii"]],[[0,0,"pl-ent"]],[[0,7,"pl-ent"],[0,7,"pl-ii"]],[[0,29,"pl-ent"],[0,29,"pl-ii"]],[[0,39,"pl-ent"],[0,39,"pl-ii"]],[[0,31,"pl-ent"],[0,31,"pl-ii"]],[[0,3,"pl-ent"],[0,3,"pl-s"]],[[0,0,"pl-ent"]],[[0,2,"pl-s"],[11,12,"pl-s"],[12,20,"pl-c1"],[20,21,"pl-s"],[30,32,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,86,"pl-c1"]],[[0,47,"pl-c1"]],[[0,63,"pl-c1"]],[[0,55,"pl-c1"]],[[0,50,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,2,"pl-s"],[20,22,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,70,"pl-c1"]],[[0,48,"pl-c1"]],[[0,48,"pl-c1"]],[[0,74,"pl-c1"]],[[0,48,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[],[[209,210,"pl-s"],[210,234,"pl-c1"],[234,235,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,42,"pl-c1"]],[[0,33,"pl-c1"]],[[0,35,"pl-c1"]],[[0,39,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[148,149,"pl-s"],[149,151,"pl-c1"],[151,152,"pl-s"]],[],[[0,2,"pl-s"],[26,28,"pl-s"],[54,55,"pl-s"],[55,57,"pl-c1"],[57,58,"pl-s"],[194,195,"pl-s"],[195,202,"pl-c1"],[202,203,"pl-s"],[205,206,"pl-s"],[206,212,"pl-c1"],[212,213,"pl-s"],[215,216,"pl-s"],[216,224,"pl-c1"],[224,225,"pl-s"],[227,228,"pl-s"],[228,235,"pl-c1"],[235,236,"pl-s"],[238,239,"pl-s"],[239,247,"pl-c1"],[247,248,"pl-s"],[250,251,"pl-s"],[251,259,"pl-c1"],[259,260,"pl-s"],[262,263,"pl-s"],[263,269,"pl-c1"],[269,270,"pl-s"],[275,276,"pl-s"],[276,283,"pl-c1"],[283,284,"pl-s"],[298,299,"pl-s"],[299,301,"pl-c1"],[301,302,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,22,"pl-c1"]],[[0,20,"pl-c1"]],[[0,0,"pl-c1"]],[[0,18,"pl-c1"]],[[0,31,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[],[],[[0,2,"pl-s"],[19,21,"pl-s"],[163,164,"pl-s"],[164,204,"pl-c1"],[204,205,"pl-s"],[236,237,"pl-s"],[237,281,"pl-c1"],[281,282,"pl-s"],[400,401,"pl-s"],[401,452,"pl-c1"],[452,453,"pl-s"],[474,475,"pl-s"],[509,510,"pl-s"],[510,511,"pl-s"],[511,545,"pl-corl"],[545,546,"pl-s"]],[],[[0,22,"pl-mh"],[4,22,"pl-en"]],[],[[11,12,"pl-s"],[12,28,"pl-c1"],[28,29,"pl-s"],[273,274,"pl-s"],[274,276,"pl-c1"],[276,277,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[[0,3,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[[0,3,"pl-s"]],[],[[53,54,"pl-s"],[54,60,"pl-c1"],[60,61,"pl-s"],[124,125,"pl-s"],[125,140,"pl-c1"],[140,141,"pl-s"],[163,164,"pl-s"],[164,177,"pl-c1"],[177,178,"pl-s"]],[],[[41,42,"pl-s"],[42,49,"pl-c1"],[49,50,"pl-s"],[83,84,"pl-s"],[84,96,"pl-c1"],[96,97,"pl-s"],[111,112,"pl-s"],[112,120,"pl-c1"],[120,121,"pl-s"],[127,128,"pl-s"],[128,137,"pl-c1"],[137,138,"pl-s"]],[],[[0,13,"pl-mh"],[3,13,"pl-en"]],[],[[24,25,"pl-s"],[27,28,"pl-s"],[28,29,"pl-s"],[29,64,"pl-corl"],[64,65,"pl-s"],[79,80,"pl-s"],[80,88,"pl-c1"],[88,89,"pl-s"],[228,229,"pl-s"],[229,236,"pl-c1"],[236,237,"pl-s"],[257,258,"pl-s"],[258,272,"pl-c1"],[272,273,"pl-s"]],[],[[0,2,"pl-s"],[10,12,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[20,22,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"],[7,7,"pl-c1"]],[[0,15,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"],[7,7,"pl-c1"]],[[0,100,"pl-c1"]],[[0,54,"pl-c1"]],[[0,55,"pl-c1"]],[[0,57,"pl-c1"]],[[0,82,"pl-c1"]],[[0,60,"pl-c1"]],[[0,37,"pl-c1"]],[[0,77,"pl-c1"]],[[0,57,"pl-c1"]],[[0,55,"pl-c1"]],[[0,50,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[47,48,"pl-s"],[48,56,"pl-c1"],[56,57,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"],[7,7,"pl-c1"]],[[0,20,"pl-c1"]],[[0,17,"pl-c1"]],[[0,20,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[44,45,"pl-s"],[45,69,"pl-c1"],[69,70,"pl-s"]],[],[[0,2,"pl-s"],[17,19,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"],[39,40,"pl-s"],[40,54,"pl-c1"],[54,55,"pl-s"],[98,99,"pl-s"],[99,113,"pl-c1"],[113,114,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[20,21,"pl-s"],[21,35,"pl-c1"],[35,36,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[111,112,"pl-s"],[112,126,"pl-c1"],[126,127,"pl-s"]],[],[[0,2,"pl-s"],[8,10,"pl-s"]],[],[[0,1,"pl-v"],[15,16,"pl-s"],[16,23,"pl-c1"],[23,24,"pl-s"],[35,36,"pl-s"],[36,40,"pl-c1"],[40,41,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,44,"pl-c1"],[44,45,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[12,13,"pl-s"],[13,15,"pl-c1"],[15,16,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,18,"pl-c1"],[18,19,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,20,"pl-c1"],[20,21,"pl-s"],[25,26,"pl-s"],[26,44,"pl-c1"],[44,45,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,31,"pl-c1"],[31,32,"pl-s"]],[[0,1,"pl-v"],[13,14,"pl-s"],[14,28,"pl-c1"],[28,29,"pl-s"]],[[0,1,"pl-v"],[87,88,"pl-s"],[88,108,"pl-c1"],[108,109,"pl-s"],[113,114,"pl-s"],[114,140,"pl-c1"],[140,141,"pl-s"]],[[0,1,"pl-v"],[52,53,"pl-s"],[53,64,"pl-c1"],[64,65,"pl-s"]],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[21,22,"pl-s"],[31,32,"pl-s"],[32,33,"pl-s"],[33,64,"pl-corl"],[64,65,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"]],[],[],[],[[0,2,"pl-s"],[66,68,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[],[[0,3,"pl-s"]],[],[[53,54,"pl-s"],[54,77,"pl-c1"],[77,78,"pl-s"],[83,84,"pl-s"],[84,112,"pl-c1"],[112,113,"pl-s"]],[],[[54,55,"pl-s"],[55,61,"pl-c1"],[61,62,"pl-s"],[68,69,"pl-s"],[69,73,"pl-c1"],[73,74,"pl-s"],[120,121,"pl-s"],[121,143,"pl-c1"],[143,144,"pl-s"],[182,183,"pl-s"],[183,198,"pl-c1"],[198,199,"pl-s"],[293,294,"pl-s"],[294,304,"pl-c1"],[304,305,"pl-s"],[310,311,"pl-s"],[311,318,"pl-c1"],[318,319,"pl-s"]],[],[[134,135,"pl-s"],[135,150,"pl-c1"],[150,151,"pl-s"],[193,194,"pl-s"],[194,205,"pl-c1"],[205,206,"pl-s"]],[],[[4,5,"pl-s"],[5,12,"pl-c1"],[12,13,"pl-s"],[68,69,"pl-s"],[69,85,"pl-c1"],[85,86,"pl-s"]],[],[[0,2,"pl-s"],[15,17,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[22,23,"pl-s"],[23,27,"pl-c1"],[27,28,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[33,34,"pl-s"],[34,47,"pl-c1"],[47,48,"pl-s"]],[[0,1,"pl-v"]],[],[[0,2,"pl-s"],[8,10,"pl-s"]],[],[[0,1,"pl-v"],[25,26,"pl-s"],[26,28,"pl-c1"],[28,29,"pl-s"]],[[0,1,"pl-v"],[35,36,"pl-s"],[36,52,"pl-c1"],[52,53,"pl-s"],[62,63,"pl-s"],[63,76,"pl-c1"],[76,77,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[34,35,"pl-s"],[35,49,"pl-c1"],[49,50,"pl-s"]],[],[[0,32,"pl-mh"],[4,32,"pl-en"]],[],[[0,13,"pl-mh"],[5,13,"pl-en"]],[],[[24,25,"pl-s"],[33,34,"pl-s"],[34,35,"pl-s"],[35,54,"pl-corl"],[54,55,"pl-s"],[145,146,"pl-s"],[146,154,"pl-c1"],[154,155,"pl-s"]],[],[[0,2,"pl-s"],[52,54,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,2,"pl-c1"],[20,22,"pl-k"]],[[0,3,"pl-s"]],[],[[52,53,"pl-s"],[53,69,"pl-c1"],[69,70,"pl-s"]],[],[[19,20,"pl-s"],[20,38,"pl-c1"],[38,39,"pl-s"],[45,46,"pl-s"],[46,50,"pl-c1"],[50,51,"pl-s"],[57,58,"pl-s"],[58,116,"pl-c1"],[116,117,"pl-s"],[264,265,"pl-s"],[265,284,"pl-c1"],[284,285,"pl-s"],[326,327,"pl-s"],[327,345,"pl-c1"],[345,346,"pl-s"],[562,563,"pl-s"],[589,590,"pl-s"],[590,591,"pl-s"],[591,617,"pl-corl"],[617,618,"pl-s"]],[],[[0,2,"pl-s"],[27,29,"pl-s"]],[],[[17,18,"pl-s"],[18,26,"pl-c1"],[26,27,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"],[7,7,"pl-c1"]],[[0,68,"pl-c1"]],[[0,58,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[],[],[[0,12,"pl-mh"],[5,12,"pl-en"]],[],[[94,95,"pl-s"],[95,96,"pl-c1"],[96,97,"pl-s"],[139,140,"pl-s"],[140,166,"pl-c1"],[166,167,"pl-s"],[178,179,"pl-s"],[179,181,"pl-c1"],[181,182,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,36,"pl-c"],[0,1,"pl-c"]],[],[[12,54,"pl-s"],[12,14,"pl-pds"],[53,54,"pl-pds"],[55,57,"pl-k"],[61,63,"pl-smi"]],[[0,4,"pl-k"],[5,10,"pl-s"],[5,6,"pl-pds"],[6,9,"pl-smi"],[9,10,"pl-pds"],[11,13,"pl-k"]],[[7,9,"pl-k"],[10,24,"pl-s"],[10,11,"pl-pds"],[11,23,"pl-smi"],[23,24,"pl-pds"],[27,29,"pl-k"],[30,34,"pl-c1"],[35,49,"pl-s"],[35,36,"pl-pds"],[36,48,"pl-smi"],[48,49,"pl-pds"],[50,51,"pl-k"]],[[6,10,"pl-c1"],[11,25,"pl-s"],[11,12,"pl-pds"],[12,24,"pl-smi"],[24,25,"pl-pds"],[26,27,"pl-k"]],[[2,3,"pl-k"],[5,9,"pl-c1"],[10,15,"pl-s"],[10,11,"pl-pds"],[11,14,"pl-smi"],[14,15,"pl-pds"]],[[0,4,"pl-k"]],[[0,3,"pl-s"]],[],[[13,14,"pl-s"],[14,15,"pl-c1"],[15,16,"pl-s"],[75,76,"pl-s"],[76,78,"pl-c1"],[78,79,"pl-s"],[113,114,"pl-s"],[114,140,"pl-c1"],[140,141,"pl-s"],[143,144,"pl-s"],[144,145,"pl-c1"],[145,146,"pl-s"]],[],[[0,8,"pl-mh"],[3,8,"pl-en"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,34,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,24,"pl-c1"],[24,25,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,25,"pl-c1"],[25,26,"pl-s"],[43,44,"pl-s"],[44,51,"pl-c1"],[51,52,"pl-s"],[67,68,"pl-s"],[68,72,"pl-c1"],[72,73,"pl-s"]],[],[[0,11,"pl-mh"],[4,11,"pl-en"]],[],[[0,1,"pl-ml"],[9,10,"pl-ml"],[23,24,"pl-ml"],[33,34,"pl-ml"]],[[0,1,"pl-ml"],[9,10,"pl-ml"],[23,24,"pl-ml"],[33,34,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,7,"pl-c1"],[7,8,"pl-s"],[9,10,"pl-ml"],[35,36,"pl-ml"],[57,58,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[46,47,"pl-ml"],[48,49,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"],[13,14,"pl-ml"],[41,42,"pl-s"],[42,56,"pl-c1"],[56,57,"pl-s"],[58,59,"pl-ml"],[60,61,"pl-s"],[61,66,"pl-c1"],[66,67,"pl-s"],[68,69,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[16,17,"pl-ml"],[57,58,"pl-s"],[58,75,"pl-c1"],[75,76,"pl-s"],[77,78,"pl-ml"],[79,80,"pl-s"],[80,85,"pl-c1"],[85,86,"pl-s"],[87,88,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"],[17,18,"pl-ml"],[63,64,"pl-s"],[64,82,"pl-c1"],[82,83,"pl-s"],[84,85,"pl-ml"],[86,87,"pl-s"],[87,88,"pl-c1"],[88,89,"pl-s"],[90,91,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[16,17,"pl-ml"],[59,60,"pl-s"],[60,77,"pl-c1"],[77,78,"pl-s"],[79,80,"pl-ml"],[81,82,"pl-s"],[82,83,"pl-c1"],[83,84,"pl-s"],[85,86,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[16,17,"pl-ml"],[73,74,"pl-s"],[74,91,"pl-c1"],[91,92,"pl-s"],[93,94,"pl-ml"],[95,96,"pl-s"],[96,101,"pl-c1"],[101,102,"pl-s"],[103,104,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[48,49,"pl-s"],[49,70,"pl-c1"],[70,71,"pl-s"],[72,73,"pl-ml"],[74,75,"pl-s"],[75,80,"pl-c1"],[80,81,"pl-s"],[82,83,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,9,"pl-c1"],[9,10,"pl-s"],[11,12,"pl-ml"],[53,54,"pl-s"],[54,66,"pl-c1"],[66,67,"pl-s"],[68,69,"pl-ml"],[70,71,"pl-s"],[71,76,"pl-c1"],[76,77,"pl-s"],[78,79,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[211,212,"pl-s"],[212,231,"pl-c1"],[231,232,"pl-s"],[233,234,"pl-ml"],[235,236,"pl-s"],[236,237,"pl-c1"],[237,238,"pl-s"],[239,240,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[86,87,"pl-s"],[87,107,"pl-c1"],[107,108,"pl-s"],[109,110,"pl-ml"],[111,112,"pl-s"],[112,113,"pl-c1"],[113,114,"pl-s"],[115,116,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[16,17,"pl-ml"],[53,54,"pl-s"],[54,71,"pl-c1"],[71,72,"pl-s"],[73,74,"pl-ml"],[75,76,"pl-s"],[76,81,"pl-c1"],[81,82,"pl-s"],[83,84,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"],[14,15,"pl-ml"],[80,81,"pl-s"],[81,96,"pl-c1"],[96,97,"pl-s"],[98,99,"pl-ml"],[100,101,"pl-s"],[101,106,"pl-c1"],[106,107,"pl-s"],[108,109,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[90,91,"pl-s"],[91,114,"pl-c1"],[114,115,"pl-s"],[116,117,"pl-ml"],[118,119,"pl-s"],[119,120,"pl-c1"],[120,121,"pl-s"],[122,123,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"],[23,24,"pl-ml"],[31,32,"pl-s"],[32,33,"pl-c1"],[33,34,"pl-s"],[39,40,"pl-s"],[40,41,"pl-c1"],[41,42,"pl-s"],[81,82,"pl-s"],[82,106,"pl-c1"],[106,107,"pl-s"],[108,109,"pl-ml"],[110,111,"pl-s"],[111,116,"pl-c1"],[116,117,"pl-s"],[118,119,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[47,48,"pl-s"],[48,49,"pl-c1"],[49,50,"pl-s"],[51,52,"pl-s"],[52,53,"pl-c1"],[53,54,"pl-s"],[56,57,"pl-s"],[57,63,"pl-c1"],[63,64,"pl-s"],[65,66,"pl-s"],[66,70,"pl-c1"],[70,71,"pl-s"],[73,74,"pl-s"],[74,80,"pl-c1"],[80,81,"pl-s"],[82,83,"pl-s"],[83,89,"pl-c1"],[89,90,"pl-s"],[144,145,"pl-s"],[145,170,"pl-c1"],[170,171,"pl-s"],[172,173,"pl-ml"],[174,175,"pl-s"],[175,180,"pl-c1"],[180,181,"pl-s"],[182,183,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[76,77,"pl-s"],[77,100,"pl-c1"],[100,101,"pl-s"],[102,103,"pl-ml"],[104,105,"pl-s"],[105,110,"pl-c1"],[110,111,"pl-s"],[112,113,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[60,61,"pl-s"],[61,81,"pl-c1"],[81,82,"pl-s"],[83,84,"pl-ml"],[85,86,"pl-s"],[86,91,"pl-c1"],[91,92,"pl-s"],[93,94,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[38,39,"pl-s"],[39,52,"pl-c1"],[52,53,"pl-s"],[54,55,"pl-ml"],[56,57,"pl-s"],[57,62,"pl-c1"],[62,63,"pl-s"],[64,65,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[16,17,"pl-ml"],[91,92,"pl-s"],[92,109,"pl-c1"],[109,110,"pl-s"],[111,112,"pl-ml"],[113,114,"pl-s"],[114,119,"pl-c1"],[119,120,"pl-s"],[121,122,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[68,69,"pl-s"],[69,94,"pl-c1"],[94,95,"pl-s"],[96,97,"pl-ml"],[98,99,"pl-s"],[99,104,"pl-c1"],[104,105,"pl-s"],[106,107,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[69,70,"pl-s"],[70,95,"pl-c1"],[95,96,"pl-s"],[97,98,"pl-ml"],[99,100,"pl-s"],[100,102,"pl-c1"],[102,103,"pl-s"],[104,105,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,29,"pl-c1"],[29,30,"pl-s"],[31,32,"pl-ml"],[77,78,"pl-s"],[78,110,"pl-c1"],[110,111,"pl-s"],[121,122,"pl-s"],[122,146,"pl-c1"],[146,147,"pl-s"],[148,149,"pl-ml"],[150,151,"pl-s"],[151,156,"pl-c1"],[156,157,"pl-s"],[158,159,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[25,26,"pl-ml"],[86,87,"pl-s"],[87,113,"pl-c1"],[113,114,"pl-s"],[115,116,"pl-ml"],[117,118,"pl-s"],[118,123,"pl-c1"],[123,124,"pl-s"],[125,126,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[93,94,"pl-s"],[94,119,"pl-c1"],[119,120,"pl-s"],[121,122,"pl-ml"],[123,124,"pl-s"],[124,129,"pl-c1"],[129,130,"pl-s"],[131,132,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,13,"pl-c1"],[13,14,"pl-s"],[15,16,"pl-ml"],[67,68,"pl-s"],[68,84,"pl-c1"],[84,85,"pl-s"],[86,87,"pl-ml"],[88,89,"pl-s"],[89,94,"pl-c1"],[94,95,"pl-s"],[96,97,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"],[14,15,"pl-ml"],[46,47,"pl-s"],[47,62,"pl-c1"],[62,63,"pl-s"],[64,65,"pl-ml"],[66,67,"pl-s"],[67,72,"pl-c1"],[72,73,"pl-s"],[74,75,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"],[17,18,"pl-ml"],[59,60,"pl-s"],[60,62,"pl-c1"],[62,63,"pl-s"],[65,66,"pl-s"],[66,67,"pl-c1"],[67,68,"pl-s"],[70,71,"pl-s"],[71,72,"pl-c1"],[72,73,"pl-s"],[74,75,"pl-s"],[75,76,"pl-c1"],[76,77,"pl-s"],[78,79,"pl-s"],[79,80,"pl-c1"],[80,81,"pl-s"],[83,84,"pl-s"],[84,86,"pl-c1"],[86,87,"pl-s"],[88,89,"pl-s"],[89,91,"pl-c1"],[91,92,"pl-s"],[93,94,"pl-s"],[94,96,"pl-c1"],[96,97,"pl-s"],[99,100,"pl-s"],[100,102,"pl-c1"],[102,103,"pl-s"],[104,105,"pl-s"],[105,107,"pl-c1"],[107,108,"pl-s"],[116,117,"pl-s"],[117,135,"pl-c1"],[135,136,"pl-s"],[137,138,"pl-ml"],[139,140,"pl-s"],[140,145,"pl-c1"],[145,146,"pl-s"],[147,148,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[70,71,"pl-s"],[71,91,"pl-c1"],[91,92,"pl-s"],[93,94,"pl-ml"],[95,96,"pl-s"],[96,116,"pl-c1"],[116,117,"pl-s"],[118,119,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[36,37,"pl-s"],[37,62,"pl-c1"],[62,63,"pl-s"],[69,70,"pl-s"],[70,74,"pl-c1"],[74,75,"pl-s"],[115,116,"pl-s"],[116,129,"pl-c1"],[129,130,"pl-s"],[131,132,"pl-ml"],[133,134,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[38,39,"pl-s"],[39,51,"pl-c1"],[51,52,"pl-s"],[88,89,"pl-s"],[89,112,"pl-c1"],[112,113,"pl-s"],[114,115,"pl-ml"],[116,117,"pl-s"],[117,124,"pl-c1"],[124,125,"pl-s"],[126,127,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"],[23,24,"pl-ml"],[39,40,"pl-s"],[40,52,"pl-c1"],[52,53,"pl-s"],[90,91,"pl-s"],[91,115,"pl-c1"],[115,116,"pl-s"],[117,118,"pl-ml"],[119,120,"pl-s"],[120,136,"pl-c1"],[136,137,"pl-s"],[138,139,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"],[17,18,"pl-ml"],[84,85,"pl-ml"],[86,87,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[67,68,"pl-ml"],[69,70,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[69,70,"pl-ml"],[71,72,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[94,95,"pl-ml"],[96,97,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[93,94,"pl-ml"],[95,96,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[8,9,"pl-s"],[9,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[77,78,"pl-ml"],[79,80,"pl-s"],[80,85,"pl-c1"],[85,86,"pl-s"],[87,88,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[58,59,"pl-s"],[59,72,"pl-c1"],[72,73,"pl-s"],[80,81,"pl-s"],[81,100,"pl-c1"],[100,101,"pl-s"],[123,124,"pl-ml"],[125,126,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[58,59,"pl-s"],[59,72,"pl-c1"],[72,73,"pl-s"],[75,76,"pl-ml"],[77,78,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[80,81,"pl-ml"],[82,83,"pl-s"],[83,88,"pl-c1"],[88,89,"pl-s"],[90,91,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"],[17,18,"pl-ml"],[99,100,"pl-ml"],[101,102,"pl-s"],[102,116,"pl-c1"],[116,117,"pl-s"],[118,119,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[130,131,"pl-s"],[131,149,"pl-c1"],[149,150,"pl-s"],[152,153,"pl-ml"],[154,155,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"],[23,24,"pl-ml"],[83,84,"pl-ml"],[85,86,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[8,9,"pl-s"],[9,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[80,81,"pl-s"],[81,96,"pl-c1"],[96,97,"pl-s"],[116,117,"pl-ml"],[118,119,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[8,9,"pl-s"],[9,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[75,76,"pl-s"],[76,91,"pl-c1"],[91,92,"pl-s"],[111,112,"pl-ml"],[113,114,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[8,9,"pl-s"],[9,15,"pl-c1"],[15,16,"pl-s"],[17,18,"pl-ml"],[91,92,"pl-s"],[92,107,"pl-c1"],[107,108,"pl-s"],[110,111,"pl-ml"],[112,113,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[8,9,"pl-s"],[9,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[71,72,"pl-s"],[72,86,"pl-c1"],[86,87,"pl-s"],[88,89,"pl-ml"],[90,91,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[25,26,"pl-ml"],[58,59,"pl-s"],[59,60,"pl-c1"],[60,61,"pl-s"],[74,75,"pl-s"],[75,101,"pl-c1"],[101,102,"pl-s"],[112,113,"pl-s"],[113,131,"pl-c1"],[131,132,"pl-s"],[133,134,"pl-ml"],[135,136,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[64,65,"pl-s"],[65,67,"pl-c1"],[67,68,"pl-s"],[76,77,"pl-ml"],[78,79,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[66,67,"pl-s"],[67,86,"pl-c1"],[86,87,"pl-s"],[88,89,"pl-ml"],[90,91,"pl-s"],[91,117,"pl-c1"],[117,118,"pl-s"],[119,120,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"],[13,14,"pl-ml"],[41,42,"pl-s"],[42,56,"pl-c1"],[56,57,"pl-s"],[58,59,"pl-ml"],[60,61,"pl-s"],[61,85,"pl-c1"],[85,86,"pl-s"],[87,88,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,9,"pl-c1"],[9,10,"pl-s"],[11,12,"pl-ml"],[44,45,"pl-s"],[45,57,"pl-c1"],[57,58,"pl-s"],[59,60,"pl-ml"],[61,62,"pl-s"],[62,91,"pl-c1"],[91,92,"pl-s"],[93,94,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[16,17,"pl-ml"],[65,66,"pl-ml"],[67,68,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[60,61,"pl-ml"],[62,63,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[8,9,"pl-s"],[9,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[40,41,"pl-ml"],[42,43,"pl-ml"]],[],[[0,15,"pl-mh"],[4,15,"pl-en"]],[],[[43,44,"pl-s"],[44,68,"pl-c1"],[68,69,"pl-s"],[181,182,"pl-s"],[182,213,"pl-c1"],[213,214,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[9,10,"pl-k"]],[[22,23,"pl-k"],[24,25,"pl-k"]],[[0,3,"pl-s"]],[],[],[],[[0,10,"pl-mh"],[4,10,"pl-en"]],[],[[47,49,"pl-s"],[54,56,"pl-s"],[58,60,"pl-s"],[76,78,"pl-s"],[80,82,"pl-s"],[98,100,"pl-s"],[102,104,"pl-s"],[111,113,"pl-s"],[115,117,"pl-s"],[124,126,"pl-s"],[128,130,"pl-s"],[134,136,"pl-s"],[138,140,"pl-s"],[147,149,"pl-s"],[155,157,"pl-s"],[171,173,"pl-s"],[196,197,"pl-s"],[197,222,"pl-c1"],[222,223,"pl-s"]],[],[[6,7,"pl-s"],[7,8,"pl-c1"],[8,9,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,15,"pl-c"],[0,1,"pl-c"]],[],[],[[0,51,"pl-c"],[0,1,"pl-c"]],[],[],[[0,23,"pl-c"],[0,1,"pl-c"]],[],[],[[0,73,"pl-c"],[0,1,"pl-c"]],[],[],[[0,43,"pl-c"],[0,1,"pl-c"]],[],[],[[0,50,"pl-c"],[0,1,"pl-c"]],[],[],[[0,41,"pl-c"],[0,1,"pl-c"]],[[21,22,"pl-k"],[23,24,"pl-k"]],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[24,26,"pl-s"]],[],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[25,27,"pl-s"],[83,84,"pl-s"],[84,93,"pl-c1"],[93,94,"pl-s"],[144,145,"pl-s"],[145,202,"pl-c1"],[202,203,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[18,20,"pl-s"],[106,107,"pl-s"],[107,119,"pl-c1"],[119,120,"pl-s"]],[],[[0,3,"pl-s"],[3,6,"pl-en"]],[[0,17,"pl-c"],[0,1,"pl-c"]],[[0,34,"pl-c"],[0,1,"pl-c"]],[[0,12,"pl-k"]],[[0,12,"pl-k"],[15,22,"pl-c"],[15,16,"pl-c"]],[[0,12,"pl-k"],[15,22,"pl-c"],[15,16,"pl-c"]],[],[[0,3,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,6,"pl-en"]],[[0,5,"pl-k"]],[[0,3,"pl-s"]],[],[[29,30,"pl-s"],[30,51,"pl-c1"],[51,52,"pl-s"]],[],[[4,5,"pl-s"],[5,17,"pl-c1"],[17,18,"pl-s"],[108,109,"pl-s"],[109,116,"pl-c1"],[116,117,"pl-s"],[143,144,"pl-s"],[144,160,"pl-c1"],[160,161,"pl-s"]],[],[[0,3,"pl-s"],[3,6,"pl-en"]],[[0,5,"pl-k"]],[[0,15,"pl-k"]],[[0,16,"pl-k"]],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[21,23,"pl-s"],[55,56,"pl-s"],[56,71,"pl-c1"],[71,72,"pl-s"],[88,89,"pl-s"],[105,106,"pl-s"],[106,107,"pl-s"],[107,123,"pl-corl"],[123,124,"pl-s"]],[],[[0,2,"pl-s"],[13,15,"pl-s"],[21,22,"pl-s"],[22,29,"pl-c1"],[29,30,"pl-s"],[146,147,"pl-s"],[147,156,"pl-c1"],[156,157,"pl-s"],[185,186,"pl-s"],[186,193,"pl-c1"],[193,194,"pl-s"],[252,253,"pl-s"],[253,260,"pl-c1"],[260,261,"pl-s"],[264,265,"pl-s"],[265,276,"pl-c1"],[276,277,"pl-s"]],[],[[1,8,"pl-ent"]],[[1,8,"pl-ent"],[54,61,"pl-ent"]],[],[[37,38,"pl-s"],[38,45,"pl-c1"],[45,46,"pl-s"],[71,72,"pl-s"],[72,87,"pl-c1"],[87,88,"pl-s"]],[],[[0,1,"pl-ml"],[9,10,"pl-ml"],[23,24,"pl-ml"],[33,34,"pl-ml"]],[[0,1,"pl-ml"],[9,10,"pl-ml"],[23,24,"pl-ml"],[33,34,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[61,62,"pl-ml"],[63,64,"pl-s"],[64,71,"pl-c1"],[71,72,"pl-s"],[73,74,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[43,44,"pl-ml"],[45,46,"pl-s"],[46,53,"pl-c1"],[53,54,"pl-s"],[55,56,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[52,53,"pl-ml"],[54,55,"pl-s"],[55,62,"pl-c1"],[62,63,"pl-s"],[64,65,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[49,50,"pl-ml"],[51,52,"pl-s"],[52,59,"pl-c1"],[59,60,"pl-s"],[61,62,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[45,46,"pl-ml"],[47,48,"pl-s"],[48,55,"pl-c1"],[55,56,"pl-s"],[57,58,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[51,52,"pl-ml"],[53,54,"pl-s"],[54,61,"pl-c1"],[61,62,"pl-s"],[63,64,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"],[23,24,"pl-ml"],[53,54,"pl-ml"],[55,56,"pl-s"],[56,63,"pl-c1"],[63,64,"pl-s"],[65,66,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[47,48,"pl-ml"],[49,50,"pl-s"],[50,57,"pl-c1"],[57,58,"pl-s"],[59,60,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[52,53,"pl-ml"],[71,72,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[37,38,"pl-ml"],[39,40,"pl-s"],[40,47,"pl-c1"],[47,48,"pl-s"],[49,50,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[43,44,"pl-ml"],[45,46,"pl-s"],[46,53,"pl-c1"],[53,54,"pl-s"],[55,56,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[42,43,"pl-ml"],[44,45,"pl-s"],[45,52,"pl-c1"],[52,53,"pl-s"],[54,55,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[48,49,"pl-ml"],[50,51,"pl-s"],[51,58,"pl-c1"],[58,59,"pl-s"],[60,61,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[62,63,"pl-ml"],[89,90,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,25,"pl-c1"],[25,26,"pl-s"],[27,28,"pl-ml"],[68,69,"pl-ml"],[98,99,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[60,61,"pl-ml"],[62,63,"pl-s"],[63,70,"pl-c1"],[70,71,"pl-s"],[72,73,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[66,67,"pl-ml"],[68,69,"pl-s"],[69,76,"pl-c1"],[76,77,"pl-s"],[78,79,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[48,49,"pl-ml"],[67,68,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[43,44,"pl-ml"],[62,63,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[46,47,"pl-ml"],[48,49,"pl-s"],[49,56,"pl-c1"],[56,57,"pl-s"],[58,59,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[46,47,"pl-ml"],[48,49,"pl-s"],[49,56,"pl-c1"],[56,57,"pl-s"],[58,59,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[42,43,"pl-ml"],[44,45,"pl-s"],[45,52,"pl-c1"],[52,53,"pl-s"],[54,55,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[48,49,"pl-ml"],[50,51,"pl-s"],[51,58,"pl-c1"],[58,59,"pl-s"],[60,61,"pl-ml"]],[],[[2,9,"pl-ent"]],[],[[1,8,"pl-ent"]],[[1,8,"pl-ent"],[52,59,"pl-ent"]],[],[[0,2,"pl-s"],[14,16,"pl-s"],[17,18,"pl-s"],[18,33,"pl-c1"],[33,34,"pl-s"],[36,37,"pl-s"],[37,57,"pl-c1"],[57,58,"pl-s"],[60,61,"pl-s"],[61,74,"pl-c1"],[74,75,"pl-s"],[77,78,"pl-s"],[78,95,"pl-c1"],[95,96,"pl-s"],[98,99,"pl-s"],[99,119,"pl-c1"],[119,120,"pl-s"],[132,133,"pl-s"],[133,149,"pl-c1"],[149,150,"pl-s"],[152,153,"pl-s"],[153,161,"pl-c1"],[161,162,"pl-s"],[164,165,"pl-s"],[165,174,"pl-c1"],[174,175,"pl-s"],[177,178,"pl-s"],[178,185,"pl-c1"],[185,186,"pl-s"],[188,189,"pl-s"],[189,199,"pl-c1"],[199,200,"pl-s"],[202,203,"pl-s"],[203,209,"pl-c1"],[209,210,"pl-s"],[212,213,"pl-s"],[213,224,"pl-c1"],[224,225,"pl-s"],[227,228,"pl-s"],[228,235,"pl-c1"],[235,236,"pl-s"],[238,239,"pl-s"],[239,245,"pl-c1"],[245,246,"pl-s"],[248,249,"pl-s"],[249,256,"pl-c1"],[256,257,"pl-s"],[259,260,"pl-s"],[260,273,"pl-c1"],[273,274,"pl-s"],[276,277,"pl-s"],[277,283,"pl-c1"],[283,284,"pl-s"],[286,287,"pl-s"],[287,291,"pl-c1"],[291,292,"pl-s"],[294,295,"pl-s"],[295,301,"pl-c1"],[301,302,"pl-s"],[304,305,"pl-s"],[305,312,"pl-c1"],[312,313,"pl-s"],[315,316,"pl-s"],[316,328,"pl-c1"],[328,329,"pl-s"],[331,332,"pl-s"],[332,341,"pl-c1"],[341,342,"pl-s"],[344,345,"pl-s"],[345,359,"pl-c1"],[359,360,"pl-s"],[362,363,"pl-s"],[363,366,"pl-c1"],[366,367,"pl-s"],[369,370,"pl-s"],[370,384,"pl-c1"],[384,385,"pl-s"],[387,388,"pl-s"],[388,405,"pl-c1"],[405,406,"pl-s"],[408,409,"pl-s"],[409,424,"pl-c1"],[424,425,"pl-s"],[427,428,"pl-s"],[428,444,"pl-c1"],[444,445,"pl-s"],[447,448,"pl-s"],[448,464,"pl-c1"],[464,465,"pl-s"],[467,468,"pl-s"],[468,471,"pl-c1"],[471,472,"pl-s"],[474,475,"pl-s"],[475,481,"pl-c1"],[481,482,"pl-s"],[484,485,"pl-s"],[485,495,"pl-c1"],[495,496,"pl-s"],[498,499,"pl-s"],[499,509,"pl-c1"],[509,510,"pl-s"]],[],[[0,2,"pl-s"],[15,17,"pl-s"],[18,19,"pl-s"],[19,25,"pl-c1"],[25,26,"pl-s"],[28,29,"pl-s"],[29,36,"pl-c1"],[36,37,"pl-s"],[39,40,"pl-s"],[40,56,"pl-c1"],[56,57,"pl-s"],[59,60,"pl-s"],[60,68,"pl-c1"],[68,69,"pl-s"],[71,72,"pl-s"],[72,77,"pl-c1"],[77,78,"pl-s"],[80,81,"pl-s"],[81,89,"pl-c1"],[89,90,"pl-s"],[92,93,"pl-s"],[93,99,"pl-c1"],[99,100,"pl-s"],[102,103,"pl-s"],[103,116,"pl-c1"],[116,117,"pl-s"],[119,120,"pl-s"],[120,124,"pl-c1"],[124,125,"pl-s"],[127,128,"pl-s"],[128,136,"pl-c1"],[136,137,"pl-s"],[139,140,"pl-s"],[140,145,"pl-c1"],[145,146,"pl-s"],[148,149,"pl-s"],[149,163,"pl-c1"],[163,164,"pl-s"],[166,167,"pl-s"],[167,179,"pl-c1"],[179,180,"pl-s"],[182,183,"pl-s"],[183,189,"pl-c1"],[189,190,"pl-s"],[192,193,"pl-s"],[193,206,"pl-c1"],[206,207,"pl-s"],[209,210,"pl-s"],[210,216,"pl-c1"],[216,217,"pl-s"],[219,220,"pl-s"],[220,227,"pl-c1"],[227,228,"pl-s"],[230,231,"pl-s"],[231,239,"pl-c1"],[239,240,"pl-s"],[242,243,"pl-s"],[243,255,"pl-c1"],[255,256,"pl-s"],[258,259,"pl-s"],[259,273,"pl-c1"],[273,274,"pl-s"],[276,277,"pl-s"],[277,292,"pl-c1"],[292,293,"pl-s"],[295,296,"pl-s"],[296,301,"pl-c1"],[301,302,"pl-s"],[304,305,"pl-s"],[305,319,"pl-c1"],[319,320,"pl-s"],[322,323,"pl-s"],[323,327,"pl-c1"],[327,328,"pl-s"],[330,331,"pl-s"],[331,333,"pl-c1"],[333,334,"pl-s"],[336,337,"pl-s"],[337,342,"pl-c1"],[342,343,"pl-s"]],[],[[0,2,"pl-s"],[8,10,"pl-s"],[11,12,"pl-s"],[12,17,"pl-c1"],[17,18,"pl-s"],[20,21,"pl-s"],[21,25,"pl-c1"],[25,26,"pl-s"],[28,29,"pl-s"],[29,34,"pl-c1"],[34,35,"pl-s"],[37,38,"pl-s"],[38,46,"pl-c1"],[46,47,"pl-s"],[49,50,"pl-s"],[50,57,"pl-c1"],[57,58,"pl-s"],[60,61,"pl-s"],[61,66,"pl-c1"],[66,67,"pl-s"],[69,70,"pl-s"],[70,77,"pl-c1"],[77,78,"pl-s"],[80,81,"pl-s"],[81,83,"pl-c1"],[83,84,"pl-s"],[86,87,"pl-s"],[87,103,"pl-c1"],[103,104,"pl-s"],[106,107,"pl-s"],[107,121,"pl-c1"],[121,122,"pl-s"],[124,125,"pl-s"],[125,132,"pl-c1"],[132,133,"pl-s"]],[],[[2,9,"pl-ent"]],[],[[0,12,"pl-mh"],[4,12,"pl-en"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,28,"pl-c"],[0,1,"pl-c"]],[],[],[[0,33,"pl-c"],[0,1,"pl-c"]],[],[],[[0,23,"pl-c"],[0,1,"pl-c"]],[],[],[[0,20,"pl-c"],[0,1,"pl-c"]],[],[],[[0,23,"pl-c"],[0,1,"pl-c"]],[],[],[[0,30,"pl-c"],[0,1,"pl-c"]],[],[],[[0,28,"pl-c"],[0,1,"pl-c"]],[],[],[[0,43,"pl-c"],[0,1,"pl-c"]],[],[],[[0,58,"pl-c"],[0,1,"pl-c"]],[],[],[[0,25,"pl-c"],[0,1,"pl-c"]],[],[],[[0,38,"pl-c"],[0,1,"pl-c"]],[],[],[[0,35,"pl-c"],[0,1,"pl-c"]],[],[],[[0,66,"pl-c"],[0,1,"pl-c"]],[],[],[[0,76,"pl-c"],[0,1,"pl-c"]],[],[],[[0,47,"pl-c"],[0,1,"pl-c"]],[],[],[[0,49,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-c1"],[7,28,"pl-s"],[7,8,"pl-pds"],[27,28,"pl-pds"],[29,30,"pl-k"]],[],[[0,43,"pl-c"],[0,1,"pl-c"]],[[13,14,"pl-k"]],[],[[0,46,"pl-c"],[0,1,"pl-c"]],[],[[0,7,"pl-smi"]],[],[[0,3,"pl-s"]],[],[[0,1,"pl-s"],[1,14,"pl-c1"],[14,15,"pl-s"],[52,53,"pl-s"],[53,55,"pl-c1"],[55,56,"pl-s"],[69,70,"pl-s"],[83,84,"pl-s"],[84,85,"pl-s"],[85,99,"pl-corl"],[99,100,"pl-s"],[244,245,"pl-s"],[245,272,"pl-c1"],[272,273,"pl-s"],[414,415,"pl-s"],[415,416,"pl-c1"],[416,417,"pl-s"],[458,459,"pl-s"],[459,461,"pl-c1"],[461,462,"pl-s"]],[],[[0,18,"pl-mh"],[4,18,"pl-en"]],[],[[4,5,"pl-s"],[5,16,"pl-c1"],[16,17,"pl-s"],[22,23,"pl-s"],[23,25,"pl-c1"],[25,26,"pl-s"],[208,209,"pl-s"],[209,210,"pl-c1"],[210,211,"pl-s"],[212,213,"pl-s"],[213,214,"pl-c1"],[214,215,"pl-s"]],[],[[0,1,"pl-s"],[1,12,"pl-c1"],[12,13,"pl-s"],[52,53,"pl-s"],[53,65,"pl-c1"],[65,66,"pl-s"],[70,71,"pl-s"],[71,83,"pl-c1"],[83,84,"pl-s"],[142,143,"pl-s"],[143,151,"pl-c1"],[151,152,"pl-s"],[158,159,"pl-s"],[159,165,"pl-c1"],[165,166,"pl-s"]],[],[[13,14,"pl-s"],[14,23,"pl-c1"],[23,24,"pl-s"],[29,30,"pl-s"],[30,32,"pl-c1"],[32,33,"pl-s"],[67,68,"pl-s"],[68,77,"pl-c1"],[77,78,"pl-s"],[83,84,"pl-s"],[84,86,"pl-c1"],[86,87,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[],[[0,3,"pl-s"]],[],[[0,1,"pl-s"],[1,10,"pl-c1"],[10,11,"pl-s"],[16,17,"pl-s"],[17,26,"pl-c1"],[26,27,"pl-s"],[54,55,"pl-s"],[55,68,"pl-c1"],[68,69,"pl-s"],[81,82,"pl-s"],[82,86,"pl-c1"],[86,87,"pl-s"],[89,90,"pl-s"],[90,100,"pl-c1"],[100,101,"pl-s"],[108,109,"pl-s"],[109,125,"pl-c1"],[125,126,"pl-s"],[133,134,"pl-s"],[134,141,"pl-c1"],[141,142,"pl-s"],[144,145,"pl-s"],[145,158,"pl-c1"],[158,159,"pl-s"],[179,180,"pl-s"],[180,191,"pl-c1"],[191,192,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,6,"pl-en"]],[[0,7,"pl-k"]],[[0,7,"pl-k"]],[[0,7,"pl-k"]],[[0,3,"pl-s"]],[],[[48,49,"pl-s"],[49,68,"pl-c1"],[68,69,"pl-s"],[71,72,"pl-s"],[72,100,"pl-c1"],[100,101,"pl-s"]],[],[[0,28,"pl-mh"],[4,28,"pl-en"]],[],[[5,6,"pl-s"],[6,12,"pl-c1"],[12,13,"pl-s"],[169,170,"pl-s"],[170,171,"pl-c1"],[171,172,"pl-s"],[173,174,"pl-s"],[174,175,"pl-c1"],[175,176,"pl-s"]],[],[],[],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[30,32,"pl-s"],[35,36,"pl-s"],[36,42,"pl-c1"],[42,43,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[23,25,"pl-s"],[28,29,"pl-s"],[29,35,"pl-c1"],[35,36,"pl-s"]],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[],[[4,5,"pl-s"],[5,25,"pl-c1"],[25,26,"pl-s"],[41,42,"pl-s"],[42,62,"pl-c1"],[62,63,"pl-s"],[106,107,"pl-s"],[107,126,"pl-c1"],[126,127,"pl-s"],[181,182,"pl-s"],[182,185,"pl-c1"],[185,186,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[[0,3,"pl-s"]],[],[[0,1,"pl-s"],[1,14,"pl-c1"],[14,15,"pl-s"],[20,21,"pl-s"],[21,34,"pl-c1"],[34,35,"pl-s"],[96,97,"pl-s"],[97,105,"pl-c1"],[105,106,"pl-s"],[108,109,"pl-s"],[109,115,"pl-c1"],[115,116,"pl-s"],[118,119,"pl-s"],[119,130,"pl-c1"],[130,131,"pl-s"],[133,134,"pl-s"],[134,141,"pl-c1"],[141,142,"pl-s"],[144,145,"pl-s"],[145,154,"pl-c1"],[154,155,"pl-s"],[157,158,"pl-s"],[158,167,"pl-c1"],[167,168,"pl-s"],[174,175,"pl-s"],[175,188,"pl-c1"],[188,189,"pl-s"]],[],[[0,25,"pl-mh"],[4,25,"pl-en"]],[],[[4,5,"pl-s"],[5,12,"pl-c1"],[12,13,"pl-s"],[146,147,"pl-s"],[147,160,"pl-c1"],[160,161,"pl-s"],[264,265,"pl-s"],[265,266,"pl-c1"],[266,267,"pl-s"],[268,269,"pl-s"],[269,270,"pl-c1"],[270,271,"pl-s"]],[],[[0,1,"pl-s"],[1,8,"pl-c1"],[8,9,"pl-s"],[56,57,"pl-s"],[57,65,"pl-c1"],[65,66,"pl-s"],[68,69,"pl-s"],[69,75,"pl-c1"],[75,76,"pl-s"],[78,79,"pl-s"],[79,90,"pl-c1"],[90,91,"pl-s"],[93,94,"pl-s"],[94,103,"pl-c1"],[103,104,"pl-s"],[106,107,"pl-s"],[107,116,"pl-c1"],[116,117,"pl-s"],[123,124,"pl-s"],[124,137,"pl-c1"],[137,138,"pl-s"]],[],[[4,5,"pl-s"],[5,17,"pl-c1"],[17,18,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,4,"pl-c1"],[5,17,"pl-s"],[5,6,"pl-pds"],[16,17,"pl-pds"],[18,19,"pl-k"]],[[0,6,"pl-c1"],[7,25,"pl-s"],[7,8,"pl-pds"],[24,25,"pl-pds"],[26,27,"pl-k"]],[[26,27,"pl-k"]],[],[[0,71,"pl-c"],[0,1,"pl-c"]],[[15,16,"pl-k"]],[[29,30,"pl-k"]],[[0,3,"pl-s"]],[],[[0,22,"pl-mh"],[4,22,"pl-en"]],[],[[4,5,"pl-s"],[5,18,"pl-c1"],[18,19,"pl-s"],[24,25,"pl-s"],[25,51,"pl-c1"],[51,52,"pl-s"],[142,143,"pl-s"],[143,144,"pl-c1"],[144,145,"pl-s"],[197,198,"pl-s"],[198,201,"pl-c1"],[201,202,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[29,56,"pl-s"],[29,30,"pl-pds"]],[[0,0,"pl-s"]],[[0,63,"pl-s"]],[[0,32,"pl-s"],[31,32,"pl-pds"]],[],[[0,50,"pl-c"],[0,1,"pl-c"]],[],[[0,3,"pl-s"]],[],[[0,1,"pl-s"],[1,14,"pl-c1"],[14,15,"pl-s"],[20,21,"pl-s"],[21,39,"pl-c1"],[39,40,"pl-s"]],[],[[0,27,"pl-mh"],[4,27,"pl-en"]],[],[[66,67,"pl-s"],[67,91,"pl-c1"],[91,92,"pl-s"],[96,97,"pl-s"],[97,154,"pl-c1"],[154,155,"pl-s"],[243,244,"pl-s"],[244,247,"pl-c1"],[247,248,"pl-s"],[297,298,"pl-s"],[298,299,"pl-c1"],[299,300,"pl-s"],[301,302,"pl-s"],[302,303,"pl-c1"],[303,304,"pl-s"],[330,331,"pl-s"],[331,336,"pl-c1"],[336,337,"pl-s"]],[],[[88,89,"pl-s"],[89,92,"pl-c1"],[92,93,"pl-s"],[94,95,"pl-s"],[95,104,"pl-c1"],[104,105,"pl-s"]],[],[[0,22,"pl-mh"],[4,22,"pl-en"]],[],[[4,5,"pl-s"],[5,11,"pl-c1"],[11,12,"pl-s"]],[],[[0,2,"pl-s"],[31,33,"pl-s"]],[],[[0,2,"pl-s"],[35,37,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[28,30,"pl-s"],[119,120,"pl-s"],[120,126,"pl-c1"],[126,127,"pl-s"],[160,161,"pl-s"],[161,168,"pl-c1"],[168,169,"pl-s"]],[],[[0,19,"pl-mh"],[4,19,"pl-en"]],[],[[6,7,"pl-s"],[19,20,"pl-s"],[20,21,"pl-s"],[21,47,"pl-corl"],[47,48,"pl-s"]],[],[[8,9,"pl-s"],[30,31,"pl-s"],[31,32,"pl-s"],[32,77,"pl-corl"],[77,78,"pl-s"]],[],[[0,18,"pl-mh"],[4,18,"pl-en"]],[],[[32,33,"pl-s"],[33,34,"pl-c1"],[34,35,"pl-s"],[98,99,"pl-s"],[99,151,"pl-c1"],[151,152,"pl-s"]],[],[],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[],[[134,135,"pl-s"],[135,136,"pl-c1"],[136,137,"pl-s"],[177,178,"pl-s"],[178,185,"pl-c1"],[185,186,"pl-s"],[215,216,"pl-s"],[216,222,"pl-c1"],[222,223,"pl-s"],[242,243,"pl-s"],[243,249,"pl-c1"],[249,250,"pl-s"]],[],[[211,212,"pl-s"],[212,214,"pl-c1"],[214,215,"pl-s"],[276,277,"pl-s"],[277,278,"pl-c1"],[278,279,"pl-s"],[284,285,"pl-s"],[285,286,"pl-c1"],[286,287,"pl-s"],[415,416,"pl-s"],[416,418,"pl-c1"],[418,419,"pl-s"]],[],[[36,37,"pl-s"],[37,50,"pl-c1"],[50,51,"pl-s"],[53,54,"pl-s"],[54,73,"pl-c1"],[73,74,"pl-s"],[87,88,"pl-s"],[88,99,"pl-c1"],[99,100,"pl-s"]],[],[[300,301,"pl-s"],[301,323,"pl-c1"],[323,324,"pl-s"]],[],[[0,16,"pl-mh"],[4,16,"pl-en"]],[],[[0,2,"pl-s"],[13,15,"pl-s"]],[],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[19,20,"pl-ml"],[75,76,"pl-s"],[76,95,"pl-c1"],[95,96,"pl-s"],[150,151,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[8,9,"pl-ml"],[49,50,"pl-ml"]],[[0,1,"pl-ml"],[13,14,"pl-ml"],[68,69,"pl-s"],[69,70,"pl-c1"],[70,71,"pl-s"],[74,75,"pl-s"],[75,76,"pl-c1"],[76,77,"pl-s"],[112,113,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[8,9,"pl-ml"],[49,50,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[16,17,"pl-ml"],[63,64,"pl-s"],[64,83,"pl-c1"],[83,84,"pl-s"],[138,139,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[70,71,"pl-s"],[71,90,"pl-c1"],[90,91,"pl-s"],[145,146,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[8,9,"pl-ml"],[56,57,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"],[13,14,"pl-ml"],[39,40,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,8,"pl-c1"],[8,9,"pl-s"],[10,11,"pl-ml"],[70,71,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[8,9,"pl-ml"],[112,113,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[29,30,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[61,62,"pl-s"],[62,80,"pl-c1"],[80,81,"pl-s"],[138,139,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[29,30,"pl-s"],[30,37,"pl-c1"],[37,38,"pl-s"],[39,40,"pl-ml"]],[],[[226,227,"pl-s"],[227,232,"pl-c1"],[232,233,"pl-s"],[257,258,"pl-s"],[258,267,"pl-c1"],[267,268,"pl-s"],[297,298,"pl-s"],[298,301,"pl-c1"],[301,302,"pl-s"],[416,417,"pl-s"],[417,418,"pl-c1"],[418,419,"pl-s"],[489,490,"pl-s"],[490,499,"pl-c1"],[499,500,"pl-s"],[531,532,"pl-s"],[532,551,"pl-c1"],[551,552,"pl-s"]],[],[[0,2,"pl-s"],[9,11,"pl-s"]],[],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[34,35,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[67,68,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[61,62,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[8,9,"pl-s"],[9,15,"pl-c1"],[15,16,"pl-s"],[17,18,"pl-ml"],[67,68,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[8,9,"pl-s"],[9,15,"pl-c1"],[15,16,"pl-s"],[17,18,"pl-ml"],[71,72,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[8,9,"pl-ml"],[53,54,"pl-ml"]],[],[[0,2,"pl-s"],[14,16,"pl-s"]],[],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[9,10,"pl-s"],[10,15,"pl-c1"],[15,16,"pl-s"],[29,30,"pl-ml"],[58,59,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[58,59,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[75,76,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[123,124,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[39,40,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[53,54,"pl-s"],[54,62,"pl-c1"],[62,63,"pl-s"],[71,72,"pl-s"],[72,92,"pl-c1"],[92,93,"pl-s"],[95,96,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,9,"pl-c1"],[9,10,"pl-s"],[37,38,"pl-ml"],[44,45,"pl-s"],[45,52,"pl-c1"],[52,53,"pl-s"],[81,82,"pl-s"],[82,93,"pl-c1"],[93,94,"pl-s"],[109,110,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[8,9,"pl-ml"],[34,35,"pl-ml"]],[],[[44,45,"pl-s"],[45,51,"pl-c1"],[51,52,"pl-s"],[82,83,"pl-s"],[83,94,"pl-c1"],[94,95,"pl-s"],[192,193,"pl-s"],[193,200,"pl-c1"],[200,201,"pl-s"],[204,205,"pl-s"],[205,212,"pl-c1"],[212,213,"pl-s"],[216,217,"pl-s"],[217,219,"pl-c1"],[219,220,"pl-s"],[255,256,"pl-s"],[256,276,"pl-c1"],[276,277,"pl-s"],[602,603,"pl-s"],[603,604,"pl-c1"],[604,605,"pl-s"]],[],[[6,7,"pl-s"],[7,8,"pl-c1"],[8,9,"pl-s"],[55,56,"pl-s"],[56,63,"pl-c1"],[63,64,"pl-s"],[66,67,"pl-s"],[67,86,"pl-c1"],[86,87,"pl-s"],[171,172,"pl-s"],[172,179,"pl-c1"],[179,180,"pl-s"],[183,184,"pl-s"],[184,191,"pl-c1"],[191,192,"pl-s"],[195,196,"pl-s"],[196,198,"pl-c1"],[198,199,"pl-s"],[236,237,"pl-s"],[237,252,"pl-c1"],[252,253,"pl-s"],[257,258,"pl-s"],[258,279,"pl-c1"],[279,280,"pl-s"],[467,468,"pl-s"],[468,476,"pl-c1"],[476,477,"pl-s"],[581,582,"pl-s"],[582,583,"pl-c1"],[583,584,"pl-s"],[595,596,"pl-s"],[596,609,"pl-c1"],[609,610,"pl-s"],[747,748,"pl-s"],[748,755,"pl-c1"],[755,756,"pl-s"]],[],[[6,7,"pl-s"],[7,8,"pl-c1"],[8,9,"pl-s"],[61,62,"pl-s"],[62,74,"pl-c1"],[74,75,"pl-s"],[100,101,"pl-s"],[101,109,"pl-c1"],[109,110,"pl-s"],[112,113,"pl-s"],[113,133,"pl-c1"],[133,134,"pl-s"],[150,151,"pl-s"],[151,159,"pl-c1"],[159,160,"pl-s"],[279,280,"pl-s"],[280,300,"pl-c1"],[300,301,"pl-s"]],[],[[88,89,"pl-s"],[89,90,"pl-c1"],[90,91,"pl-s"],[153,154,"pl-s"],[154,155,"pl-c1"],[155,156,"pl-s"]],[],[[58,59,"pl-s"],[59,83,"pl-c1"],[83,84,"pl-s"]],[],[[0,3,"pl-s"],[3,6,"pl-en"]],[[0,18,"pl-k"]],[[0,3,"pl-s"]],[],[[5,6,"pl-s"],[6,7,"pl-c1"],[7,8,"pl-s"],[66,67,"pl-s"],[67,75,"pl-c1"],[75,76,"pl-s"],[92,93,"pl-s"],[93,119,"pl-c1"],[119,120,"pl-s"],[132,133,"pl-s"],[133,140,"pl-c1"],[140,141,"pl-s"]],[],[[117,118,"pl-s"],[118,126,"pl-c1"],[126,127,"pl-s"],[149,150,"pl-s"],[150,154,"pl-c1"],[154,155,"pl-s"],[210,211,"pl-s"],[211,219,"pl-c1"],[219,220,"pl-s"]],[],[[0,3,"pl-s"],[3,5,"pl-en"]],[[0,9,"pl-c"],[0,2,"pl-c"]],[[5,27,"pl-s"],[5,7,"pl-pds"],[14,15,"pl-k"],[22,26,"pl-s"],[22,23,"pl-pds"],[25,26,"pl-pds"],[26,27,"pl-pds"]],[[0,6,"pl-c1"],[7,25,"pl-s"],[7,8,"pl-pds"],[24,25,"pl-pds"],[26,33,"pl-s"],[26,27,"pl-pds"],[27,32,"pl-smi"],[32,33,"pl-pds"],[34,35,"pl-k"]],[[0,3,"pl-s"]],[],[[53,54,"pl-s"],[54,83,"pl-c1"],[83,84,"pl-s"],[92,93,"pl-s"],[93,122,"pl-c1"],[122,123,"pl-s"],[176,177,"pl-s"],[177,185,"pl-c1"],[185,186,"pl-s"]],[],[],[],[[6,7,"pl-s"],[7,12,"pl-c1"],[12,13,"pl-s"],[55,56,"pl-s"],[56,57,"pl-c1"],[57,58,"pl-s"],[231,232,"pl-s"],[232,233,"pl-c1"],[233,234,"pl-s"]],[],[[0,2,"pl-s"],[7,9,"pl-s"]],[],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[6,7,"pl-ml"],[15,16,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[74,75,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[89,90,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[47,48,"pl-s"],[48,49,"pl-c1"],[49,50,"pl-s"],[73,74,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[73,74,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[99,100,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[64,65,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[77,78,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[75,76,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[46,47,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[81,82,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[51,52,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[52,53,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[97,98,"pl-s"],[98,101,"pl-c1"],[101,102,"pl-s"],[172,173,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[58,59,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[43,44,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[73,74,"pl-ml"]],[],[[0,20,"pl-mh"],[4,20,"pl-en"]],[],[[270,271,"pl-s"],[271,272,"pl-c1"],[272,273,"pl-s"]],[],[[0,1,"pl-ml"],[7,8,"pl-ml"],[16,17,"pl-ml"],[26,27,"pl-ml"]],[[0,1,"pl-ml"],[7,8,"pl-ml"],[16,17,"pl-ml"],[26,27,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[34,35,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[63,64,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[43,44,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[29,30,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[28,29,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[58,59,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[45,46,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[35,36,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[48,49,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[14,15,"pl-s"],[15,20,"pl-c1"],[20,21,"pl-s"],[24,25,"pl-s"],[25,26,"pl-c1"],[26,27,"pl-s"],[28,29,"pl-ml"],[77,78,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[8,9,"pl-s"],[9,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[46,47,"pl-ml"]],[],[],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[],[],[],[[0,1,"pl-v"],[2,4,"pl-s"],[16,18,"pl-s"],[140,141,"pl-s"],[141,142,"pl-c1"],[142,143,"pl-s"],[144,145,"pl-s"],[145,146,"pl-c1"],[146,147,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[16,18,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[26,28,"pl-s"],[101,102,"pl-s"],[102,103,"pl-c1"],[103,104,"pl-s"],[105,106,"pl-s"],[106,107,"pl-c1"],[107,108,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[26,28,"pl-s"],[112,113,"pl-s"],[113,114,"pl-c1"],[114,115,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[30,32,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[34,36,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[38,40,"pl-s"],[92,93,"pl-s"],[93,98,"pl-c1"],[98,99,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[33,35,"pl-s"],[82,83,"pl-s"],[83,88,"pl-c1"],[88,89,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[33,35,"pl-s"],[81,82,"pl-s"],[82,87,"pl-c1"],[87,88,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[35,37,"pl-s"]],[],[[203,204,"pl-s"],[204,207,"pl-c1"],[207,208,"pl-s"]],[],[[0,2,"pl-s"],[26,28,"pl-s"]],[],[[0,1,"pl-v"],[2,4,"pl-s"],[9,11,"pl-s"],[18,19,"pl-s"],[19,29,"pl-c1"],[29,30,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[10,12,"pl-s"],[19,20,"pl-s"],[20,26,"pl-c1"],[26,27,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[11,13,"pl-s"],[65,66,"pl-s"],[66,71,"pl-c1"],[71,72,"pl-s"],[107,108,"pl-s"],[108,113,"pl-c1"],[113,114,"pl-s"],[118,119,"pl-s"],[125,126,"pl-s"],[293,294,"pl-s"],[294,316,"pl-c1"],[316,317,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[24,26,"pl-s"],[33,34,"pl-s"],[34,39,"pl-c1"],[39,40,"pl-s"]],[],[[251,252,"pl-s"],[252,262,"pl-c1"],[262,263,"pl-s"]],[],[[13,14,"pl-s"],[14,24,"pl-c1"],[24,25,"pl-s"],[27,28,"pl-s"],[28,49,"pl-c1"],[49,50,"pl-s"],[55,56,"pl-s"],[56,71,"pl-c1"],[71,72,"pl-s"]],[],[[0,22,"pl-mh"],[4,22,"pl-en"]],[],[[60,61,"pl-s"],[61,90,"pl-c1"],[90,91,"pl-s"],[116,117,"pl-s"],[117,123,"pl-c1"],[123,124,"pl-s"],[133,134,"pl-s"],[134,146,"pl-c1"],[146,147,"pl-s"]],[],[[23,24,"pl-s"],[24,27,"pl-c1"],[27,28,"pl-s"],[29,30,"pl-s"],[30,35,"pl-c1"],[35,36,"pl-s"],[61,62,"pl-s"],[62,63,"pl-c1"],[63,64,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,31,"pl-c1"]],[[0,25,"pl-c1"]],[[0,23,"pl-c1"]],[[0,10,"pl-c1"]],[[0,7,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[9,10,"pl-k"]],[[20,21,"pl-k"],[22,23,"pl-k"]],[[0,3,"pl-s"]],[],[[143,144,"pl-s"],[144,155,"pl-c1"],[155,156,"pl-s"]],[],[[0,2,"pl-s"],[37,39,"pl-s"],[40,41,"pl-s"],[41,42,"pl-c1"],[42,43,"pl-s"],[44,45,"pl-s"],[45,46,"pl-c1"],[46,47,"pl-s"],[122,123,"pl-s"],[123,129,"pl-c1"],[129,130,"pl-s"],[131,132,"pl-s"],[132,136,"pl-c1"],[136,137,"pl-s"],[142,143,"pl-s"],[143,149,"pl-c1"],[149,150,"pl-s"],[151,152,"pl-s"],[152,158,"pl-c1"],[158,159,"pl-s"],[218,219,"pl-s"],[219,237,"pl-c1"],[237,238,"pl-s"],[243,244,"pl-s"],[244,267,"pl-c1"],[267,268,"pl-s"],[308,309,"pl-s"],[309,310,"pl-c1"],[310,311,"pl-s"],[312,313,"pl-s"],[313,314,"pl-c1"],[314,315,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,32,"pl-c1"]],[[0,28,"pl-c1"]],[[0,37,"pl-c1"]],[[0,35,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[303,304,"pl-s"],[304,313,"pl-c1"],[313,314,"pl-s"],[316,317,"pl-s"],[317,324,"pl-c1"],[324,325,"pl-s"],[327,328,"pl-s"],[328,342,"pl-c1"],[342,343,"pl-s"],[348,349,"pl-s"],[349,361,"pl-c1"],[361,362,"pl-s"],[461,462,"pl-s"],[462,463,"pl-c1"],[463,464,"pl-s"],[474,475,"pl-s"],[475,476,"pl-c1"],[476,477,"pl-s"],[663,664,"pl-s"],[664,665,"pl-c1"],[665,666,"pl-s"],[684,685,"pl-s"],[685,696,"pl-c1"],[696,697,"pl-s"]],[],[[0,2,"pl-s"],[35,37,"pl-s"],[103,104,"pl-s"],[104,105,"pl-c1"],[105,106,"pl-s"],[129,130,"pl-s"],[130,136,"pl-c1"],[136,137,"pl-s"],[141,142,"pl-s"],[142,147,"pl-c1"],[147,148,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,26,"pl-c1"]],[[0,24,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[49,50,"pl-s"],[50,80,"pl-c1"],[80,81,"pl-s"],[120,121,"pl-s"],[121,124,"pl-c1"],[124,125,"pl-s"],[574,575,"pl-s"],[575,581,"pl-c1"],[581,582,"pl-s"],[609,610,"pl-s"],[610,621,"pl-c1"],[621,622,"pl-s"]],[],[[0,2,"pl-s"],[13,15,"pl-s"],[16,17,"pl-s"],[17,22,"pl-c1"],[22,23,"pl-s"],[151,152,"pl-s"],[152,160,"pl-c1"],[160,161,"pl-s"],[164,165,"pl-s"],[165,166,"pl-c1"],[166,167,"pl-s"],[236,237,"pl-s"],[279,280,"pl-s"],[280,284,"pl-c1"],[284,285,"pl-s"],[285,286,"pl-s"],[303,304,"pl-s"],[348,349,"pl-s"],[359,360,"pl-s"],[360,383,"pl-c1"],[383,384,"pl-s"],[396,397,"pl-s"],[397,423,"pl-c1"],[423,424,"pl-s"],[475,476,"pl-s"],[476,482,"pl-c1"],[482,483,"pl-s"]],[],[[1,8,"pl-ent"]],[[1,8,"pl-ent"],[46,53,"pl-ent"]],[],[[0,2,"pl-s"],[13,15,"pl-s"],[16,17,"pl-s"],[17,21,"pl-c1"],[21,22,"pl-s"],[24,25,"pl-s"],[25,27,"pl-c1"],[27,28,"pl-s"],[30,31,"pl-s"],[31,40,"pl-c1"],[40,41,"pl-s"],[43,44,"pl-s"],[44,51,"pl-c1"],[51,52,"pl-s"],[54,55,"pl-s"],[55,69,"pl-c1"],[69,70,"pl-s"],[72,73,"pl-s"],[73,85,"pl-c1"],[85,86,"pl-s"],[88,89,"pl-s"],[89,93,"pl-c1"],[93,94,"pl-s"],[96,97,"pl-s"],[97,100,"pl-c1"],[100,101,"pl-s"],[103,104,"pl-s"],[104,115,"pl-c1"],[115,116,"pl-s"],[118,119,"pl-s"],[119,131,"pl-c1"],[131,132,"pl-s"],[134,135,"pl-s"],[135,148,"pl-c1"],[148,149,"pl-s"],[151,152,"pl-s"],[152,162,"pl-c1"],[162,163,"pl-s"],[165,166,"pl-s"],[166,179,"pl-c1"],[179,180,"pl-s"],[182,183,"pl-s"],[183,199,"pl-c1"],[199,200,"pl-s"],[202,203,"pl-s"],[203,217,"pl-c1"],[217,218,"pl-s"],[220,221,"pl-s"],[221,242,"pl-c1"],[242,243,"pl-s"],[245,246,"pl-s"],[246,265,"pl-c1"],[265,266,"pl-s"],[268,269,"pl-s"],[269,295,"pl-c1"],[295,296,"pl-s"],[298,299,"pl-s"],[299,323,"pl-c1"],[323,324,"pl-s"]],[],[[0,2,"pl-s"],[12,14,"pl-s"],[15,16,"pl-s"],[16,25,"pl-c1"],[25,26,"pl-s"],[28,29,"pl-s"],[29,38,"pl-c1"],[38,39,"pl-s"],[41,42,"pl-s"],[42,51,"pl-c1"],[51,52,"pl-s"],[54,55,"pl-s"],[55,64,"pl-c1"],[64,65,"pl-s"],[67,68,"pl-s"],[68,77,"pl-c1"],[77,78,"pl-s"],[80,81,"pl-s"],[81,100,"pl-c1"],[100,101,"pl-s"]],[],[[0,2,"pl-s"],[7,9,"pl-s"],[10,11,"pl-s"],[11,22,"pl-c1"],[22,23,"pl-s"],[25,26,"pl-s"],[26,36,"pl-c1"],[36,37,"pl-s"],[39,40,"pl-s"],[40,50,"pl-c1"],[50,51,"pl-s"]],[],[[0,2,"pl-s"],[9,11,"pl-s"],[12,13,"pl-s"],[13,19,"pl-c1"],[19,20,"pl-s"]],[],[[0,2,"pl-s"],[14,16,"pl-s"],[17,18,"pl-s"],[18,25,"pl-c1"],[25,26,"pl-s"],[58,59,"pl-s"],[59,72,"pl-c1"],[72,73,"pl-s"],[75,76,"pl-s"],[76,93,"pl-c1"],[93,94,"pl-s"],[96,97,"pl-s"],[97,107,"pl-c1"],[107,108,"pl-s"],[110,111,"pl-s"],[111,122,"pl-c1"],[122,123,"pl-s"],[125,126,"pl-s"],[126,141,"pl-c1"],[141,142,"pl-s"],[144,145,"pl-s"],[145,160,"pl-c1"],[160,161,"pl-s"],[163,164,"pl-s"],[164,176,"pl-c1"],[176,177,"pl-s"]],[],[[0,2,"pl-s"],[7,9,"pl-s"],[10,11,"pl-s"],[11,27,"pl-c1"],[27,28,"pl-s"],[30,31,"pl-s"],[31,45,"pl-c1"],[45,46,"pl-s"],[48,49,"pl-s"],[49,60,"pl-c1"],[60,61,"pl-s"],[63,64,"pl-s"],[64,75,"pl-c1"],[75,76,"pl-s"],[78,79,"pl-s"],[79,98,"pl-c1"],[98,99,"pl-s"],[101,102,"pl-s"],[102,114,"pl-c1"],[114,115,"pl-s"],[117,118,"pl-s"],[118,134,"pl-c1"],[134,135,"pl-s"],[137,138,"pl-s"],[138,149,"pl-c1"],[149,150,"pl-s"],[152,153,"pl-s"],[153,169,"pl-c1"],[169,170,"pl-s"],[172,173,"pl-s"],[173,186,"pl-c1"],[186,187,"pl-s"],[189,190,"pl-s"],[190,207,"pl-c1"],[207,208,"pl-s"],[210,211,"pl-s"],[211,223,"pl-c1"],[223,224,"pl-s"],[226,227,"pl-s"],[227,233,"pl-c1"],[233,234,"pl-s"],[236,237,"pl-s"],[237,241,"pl-c1"],[241,242,"pl-s"],[244,245,"pl-s"],[245,251,"pl-c1"],[251,252,"pl-s"]],[],[[0,2,"pl-s"],[7,9,"pl-s"],[10,11,"pl-s"],[11,15,"pl-c1"],[15,16,"pl-s"],[18,19,"pl-s"],[19,31,"pl-c1"],[31,32,"pl-s"],[34,35,"pl-s"],[35,39,"pl-c1"],[39,40,"pl-s"],[42,43,"pl-s"],[43,50,"pl-c1"],[50,51,"pl-s"]],[],[[2,9,"pl-ent"]],[],[[0,21,"pl-mh"],[4,21,"pl-en"]],[],[[44,45,"pl-s"],[45,57,"pl-c1"],[57,58,"pl-s"],[60,61,"pl-s"],[61,84,"pl-c1"],[84,85,"pl-s"],[90,91,"pl-s"],[91,108,"pl-c1"],[108,109,"pl-s"]],[],[[0,1,"pl-ml"],[7,8,"pl-ml"],[16,17,"pl-ml"]],[[0,1,"pl-ml"],[7,8,"pl-ml"],[16,17,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,7,"pl-c1"],[7,8,"pl-s"],[11,12,"pl-s"],[12,16,"pl-c1"],[16,17,"pl-s"],[18,19,"pl-ml"],[68,69,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[7,8,"pl-ml"],[40,41,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[38,39,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,7,"pl-c1"],[7,8,"pl-s"],[9,10,"pl-ml"],[35,36,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[8,9,"pl-s"],[9,13,"pl-c1"],[13,14,"pl-s"],[15,16,"pl-ml"],[73,74,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[6,7,"pl-ml"],[47,48,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,4,"pl-c1"],[4,5,"pl-s"],[8,9,"pl-s"],[9,13,"pl-c1"],[13,14,"pl-s"],[15,16,"pl-ml"],[79,80,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[7,8,"pl-ml"],[47,48,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[7,8,"pl-ml"],[50,51,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[7,8,"pl-ml"],[53,54,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[7,8,"pl-ml"],[25,26,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[7,8,"pl-ml"],[49,50,"pl-ml"]],[],[[34,35,"pl-s"],[35,36,"pl-c1"],[36,37,"pl-s"],[38,39,"pl-s"],[39,40,"pl-c1"],[40,41,"pl-s"],[62,63,"pl-s"],[63,64,"pl-c1"],[64,65,"pl-s"],[67,68,"pl-s"],[68,69,"pl-c1"],[69,70,"pl-s"],[72,73,"pl-s"],[73,74,"pl-c1"],[74,75,"pl-s"],[199,200,"pl-s"],[200,204,"pl-c1"],[204,205,"pl-s"],[206,207,"pl-s"],[207,211,"pl-c1"],[211,212,"pl-s"],[213,214,"pl-s"],[214,218,"pl-c1"],[218,219,"pl-s"],[221,222,"pl-s"],[222,224,"pl-c1"],[224,225,"pl-s"],[226,227,"pl-s"],[227,229,"pl-c1"],[229,230,"pl-s"],[231,232,"pl-s"],[232,234,"pl-c1"],[234,235,"pl-s"],[236,237,"pl-s"],[237,239,"pl-c1"],[239,240,"pl-s"],[274,275,"pl-s"],[275,276,"pl-c1"],[276,277,"pl-s"],[278,279,"pl-s"],[279,280,"pl-c1"],[280,281,"pl-s"],[282,283,"pl-s"],[283,284,"pl-c1"],[284,285,"pl-s"],[375,376,"pl-s"],[376,378,"pl-c1"],[378,379,"pl-s"],[384,385,"pl-s"],[385,387,"pl-c1"],[387,388,"pl-s"],[436,437,"pl-s"],[437,438,"pl-c1"],[438,439,"pl-s"],[505,506,"pl-s"],[506,525,"pl-c1"],[525,526,"pl-s"],[586,587,"pl-s"],[587,590,"pl-c1"],[590,591,"pl-s"],[672,673,"pl-s"],[673,689,"pl-c1"],[689,690,"pl-s"],[728,729,"pl-s"],[729,730,"pl-c1"],[730,731,"pl-s"],[938,939,"pl-s"],[939,945,"pl-c1"],[945,946,"pl-s"],[947,948,"pl-s"],[948,953,"pl-c1"],[953,954,"pl-s"]],[],[[18,19,"pl-s"],[19,20,"pl-c1"],[20,21,"pl-s"],[41,43,"pl-s"],[53,55,"pl-s"],[104,105,"pl-s"],[105,117,"pl-c1"],[117,118,"pl-s"]],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,26,"pl-c1"]],[[0,49,"pl-c1"]],[[0,0,"pl-c1"]],[[0,20,"pl-c1"]],[[0,44,"pl-c1"]],[[0,0,"pl-c1"]],[[0,23,"pl-c1"]],[[0,36,"pl-c1"]],[[0,0,"pl-c1"]],[[0,18,"pl-c1"]],[[0,28,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[164,165,"pl-s"],[165,185,"pl-c1"],[185,186,"pl-s"],[198,199,"pl-s"],[199,216,"pl-c1"],[216,217,"pl-s"]],[],[[33,34,"pl-s"],[34,37,"pl-c1"],[37,38,"pl-s"],[132,133,"pl-s"],[133,136,"pl-c1"],[136,137,"pl-s"]],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[4,5,"pl-s"],[20,21,"pl-s"],[21,22,"pl-s"],[22,37,"pl-corl"],[37,38,"pl-s"]],[],[[0,10,"pl-mh"],[3,10,"pl-en"]],[],[[18,19,"pl-s"],[26,27,"pl-s"],[27,28,"pl-s"],[28,35,"pl-corl"],[35,36,"pl-s"]]],"colorizedLines":null}},"title":"revdiff/README.md at master · umputun/revdiff","appPayload":{},"meta":{"title":"revdiff/README.md at master · umputun/revdiff"}}</script>
  <div data-target="react-app.reactRoot"><meta name="github-code-view-meta-stats" id="github-code-view-meta-stats" data-hydrostats="publish"/> <!-- --> <a hidden="" id="code-view-repo-link" href="/umputun/revdiff" data-discover="true"></a> <div class="d-none"></div><div><div style="--spacing:var(--spacing-none)" class="prc-PageLayout-PageLayoutRoot--KH-d" data-component="SplitPageLayout" data-has-sidebar="true"><div class="prc-PageLayout-SidebarWrapper-kLG4B CopilotSidePanelSidebar-module__SidePanel__L3O0C CopilotSidePanelSidebar-module__HiddenSidePanel__TBRGn" style="--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="end" data-sticky="true" data-responsive-variant="fullscreen"><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-SidebarVerticalDivider-0Rl0V" data-component="PageLayout.VerticalDivider" data-variant="line" data-position="end" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="450" aria-valuemax="768" aria-valuenow="544" aria-valuetext="Pane width 544 pixels" tabindex="0"></div></div><div class="prc-PageLayout-Sidebar-iciWg" data-component="SplitPageLayout.Sidebar" data-resizable="true" style="--spacing:var(--spacing-normal);--pane-min-width:450px;--pane-max-width:768px;--pane-width-custom:544px;--pane-width-size:var(--pane-width-custom);--pane-width:544px"><div class="height-full" data-testid="copilot-code-view-side-panel"><div id="copilot-side-panel-content" class="height-full"></div></div></div></div><div class="prc-PageLayout-PageLayoutWrapper-2BhU2" data-width="full"><div class="prc-PageLayout-PageLayoutContent-BneH9"><div id="repos-file-tree-sidebar" class="CodeViewFileTreeLayout-module__sidebar__n_Aau" tabindex="0"><div class="prc-PageLayout-PaneWrapper-pHPop ReposFileTreePane-module__Pane__rBZpI ReposFileTreePane-module__HideTree__AYZnm ReposFileTreePane-module__HidePane__VHAVt" style="--offset-header:0px;--spacing-row:var(--spacing-none);--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="start" data-sticky="true"><div class="prc-PageLayout-HorizontalDivider-JLVqp prc-PageLayout-PaneHorizontalDivider-9tbnE" data-component="PageLayout.HorizontalDivider" data-variant-regular="none" data-variant-narrow="none" data-position="start" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)"></div><div class="prc-PageLayout-Pane-AyzHK" data-component="SplitPageLayout.Pane" data-resizable="true" style="--spacing:var(--spacing-none);--pane-min-width:256px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));--pane-width-size:var(--pane-width-large);--pane-width:320px"></div><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-PaneVerticalDivider-le57g" data-component="PageLayout.VerticalDivider" data-variant-narrow="none" data-variant-regular="line" data-variant-wide="line" data-position="start" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="256" aria-valuemax="600" aria-valuenow="320" aria-valuetext="Pane width 320 pixels" tabindex="0"></div></div></div></div><div data-component="SplitPageLayout.Content" class="prc-PageLayout-ContentWrapper-gR9eG"><div class="prc-PageLayout-Content-xWL-A" data-width="full" style="--spacing:var(--spacing-none)"><div class="SharedPageLayout-module__content__IwGAp" data-selector="repos-split-pane-content" id="repos-split-pane-content" tabindex="0"> <!-- --> <div class="container CodeViewHeader-module__Box__JkPOb"><div class="CodeViewHeader-module__StickyHeader__Qn7UN" id="StickyHeader"><div class="CodeViewHeader-module__Box_1__SbNDV"><div class="CodeViewHeader-module__Box_2__TB46f"><div class="react-code-view-header-wrap--narrow CodeViewHeader-module__Box_3__q1zUL"><div class="CodeViewHeader-module__treeToggleWrapper__RQ__9"><h2 class="use-tree-pane-module__Heading__s4QbZ prc-Heading-Heading-MtWFE" data-component="Heading"><button data-component="Button" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="prc-Button-ButtonBase-9n-Xk ExpandFileTreeButton-module__Button_1__Svs95" data-loading="false" data-size="medium" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Files</span></span></button><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-9n-Xk position-relative ExpandFileTreeButton-module__expandButton__hDOcv ExpandFileTreeButton-module__filesButtonBreakpoint__zEvz3 fgColor-muted prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_4lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="se" data-component="Tooltip" aria-hidden="true" id="_R_4lla9lik5_">Expand file tree</span><div class="d-none"></div></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="react-code-view-header-mb--narrow CodeViewHeader-module__Box_5__MQ0hL"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__lg__Rjz0A"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/umputun/revdiff/tree/master" data-discover="true">revdiff</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__lg__Rjz0A prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lla9lik5_">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><div><div class="CodeViewHeader-module__FileResultsList__JDzUy"><span class="d-flex FileResultsList-module__FilesSearchBox__ivVkc TextInput-wrapper prc-components-TextInputWrapper-Hpdqi prc-components-TextInputBaseWrapper-wY-n0" data-no-trailing-action="true" data-component="TextInput" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id="_R_1cpla9lik5_" aria-hidden="true" data-component="TextInput.LeadingVisual"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellCheck="false" placeholder="Go to file" aria-describedby="_R_1cpla9lik5_ _R_1cpla9lik5H1_" data-component="input" class="prc-components-Input-IwWrt" value=""/><span class="TextInput-icon" id="_R_1cpla9lik5H1_" aria-hidden="true" data-component="TextInput.TrailingVisual"></span></span></div><div class="d-none"></div></div><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7p9la9lik5_" id="_R_99la9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7p9la9lik5_">More file actions</span></div></div></div><div class="react-code-view-header-element--narrow"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7pdla9lik5_" id="_R_9dla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7pdla9lik5_">More file actions</span></div></div></div></div></div></div></div><div class="CodeView-module__contentWrapper__cG2JH"><div class="react-code-view-bottom-padding"><div class="BlobTopBanners-module__Box__v_nvx"></div></div> <div class="d-none"></div><div class="d-flex flex-column border rounded-2 tmp-mb-3 pl-1"><div class="LatestCommit-module__Box__B25ZT"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">History</h2><a data-component="LinkButton" href="/umputun/revdiff/commits/master/README.md" class="prc-Button-ButtonBase-9n-Xk d-none d-lg-flex LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><a data-component="LinkButton" aria-label="View commit history for this file." href="/umputun/revdiff/commits/master/README.md" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby="_R_4mlala9lik5_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" role="tooltip" aria-hidden="true" id="_R_4mlala9lik5_">History</span></div></div></div></div></div><div class="d-flex flex-row"><div class="container BlobViewContent-module__blobContainer__DtH2d"><div class="react-code-size-details-banner BlobViewContent-module__codeSizeDetails__e5sUw"><div class="react-code-size-details-banner CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="65.6 KB" style="--truncate-max-width:100%"><span>1001 lines (722 loc) · 65.6 KB</span></div></div></div></div><div class="react-blob-view-header-sticky BlobViewContent-module__stickyHeader__VwxB5" id="repos-sticky-header"><div class="BlobViewHeader-module__Box__yhm9u"><div class="react-blob-sticky-header"><div class="FileNameStickyHeader-module__outerWrapper__ZL4Xc FileNameStickyHeader-module__outerWrapperHidden__Zpynk"><div class="FileNameStickyHeader-module__Box_1__Hazu5"><div class="FileNameStickyHeader-module__Box_2__hoolP"><div class="FileNameStickyHeader-module__Box_3__MVKsk"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="FileNameStickyHeader-module__Box_4__FLhtt"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__md__Wb1Gs"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/umputun/revdiff/tree/master" data-discover="true">revdiff</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__md__Wb1Gs prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="sticky-file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lcpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lcpala9lik5_">Copy path</span></div></div></div><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk FileNameStickyHeader-module__Button__LSEU_ FileNameStickyHeader-module__GoToTopButton__nxAFn" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Top</span></span></button></div></div></div><div class="BlobViewHeader-module__Box_1__VEmuQ"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">File metadata and controls</h2><div class="BlobViewHeader-module__Box_2__icUs2"><ul aria-label="File view" class="prc-SegmentedControl-SegmentedControl-lqIXp BlobTabButtons-module__SegmentedControl__jen2u" data-variant="default" data-size="small" data-component="SegmentedControl"><li class="prc-SegmentedControl-Item-tSCQh" data-selected="" data-component="SegmentedControl.Button"><button aria-pressed="true" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:transparent"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><div class="d-none"></div><div class="react-code-size-details-in-header CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="65.6 KB" style="--truncate-max-width:100%"><span>1001 lines (722 loc) · 65.6 KB</span></div></div></div></div><div class="BlobViewHeader-module__Box_3__ng6v2"><div class="d-none"></div><div class="react-blob-header-edit-and-raw-actions BlobViewHeader-module__Box_4__J4Y4W"><div class="d-none"></div><div class="prc-ButtonGroup-ButtonGroup-vFUrY" data-component="ButtonGroup"><div class="prc-ButtonGroup-Item-PqvDl"><a data-component="LinkButton" href="https://github.com/umputun/revdiff/raw/refs/heads/master/README.md" data-testid="raw-button" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov BlobViewHeader-module__LinkButton__X9kx2" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Raw</span></span></a></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="copy-raw-button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_qaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_qaucpala9lik5_">Copy raw file</span></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="download-raw-button" class="prc-Button-ButtonBase-9n-Xk BlobViewHeader-module__downloadButton__ef459 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_eaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_eaucpala9lik5_">Download raw file</span></div></div></div><button data-component="IconButton" type="button" aria-pressed="false" class="prc-Button-ButtonBase-9n-Xk tmp-mr-2 TableOfContents-module__IconButton__jrlNM prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_3ucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_3ucpala9lik5_">Outline</span><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click BlobViewHeader-module__IconButton__XrMQY prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_fkecpala9lik5_" id="_R_kecpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_fkecpala9lik5_">Edit and raw actions</span></div></div></div></div><div></div></div><div class="BlobViewContent-module__blobContentWrapper__JS0W6"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="BlobContent-module__blobContentSection__VOgZq BlobContent-module__blobContentSectionMarkdown__mPLOK" style="margin-top:46px"><div class="js-snippet-clipboard-copy-unpositioned BlobContent-module__markdownBlob__T8jpG" data-hpc="true" containertiming="hpc"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto"><a target="_blank" rel="noopener noreferrer" href="/umputun/revdiff/blob/master/site/assets/logo.png"><img src="/umputun/revdiff/raw/master/site/assets/logo.png" alt="" width="28" style="max-width: 100%;"></a> revdiff  <a href="https://github.com/umputun/revdiff/actions/workflows/ci.yml"><img src="https://github.com/umputun/revdiff/actions/workflows/ci.yml/badge.svg" alt="build" style="max-width: 100%;"></a> <a href="https://coveralls.io/github/umputun/revdiff?branch=master" rel="nofollow"><img src="https://camo.githubusercontent.com/9a886abdcd335a7a5d197d30137e474e98627ce5472249d292957b53f78b98d2/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f756d707574756e2f726576646966662f62616467652e7376673f6272616e63683d6d6173746572" alt="Coverage Status" data-canonical-src="https://coveralls.io/repos/github/umputun/revdiff/badge.svg?branch=master" style="max-width: 100%;"></a> <a href="https://goreportcard.com/report/github.com/umputun/revdiff" rel="nofollow"><img src="https://camo.githubusercontent.com/fc0af9bf876e1195f867c8ab8ee0238f1e4e98d9f715d83cdfbcd71adc02cf3e/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f756d707574756e2f72657664696666" alt="Go Report Card" data-canonical-src="https://goreportcard.com/badge/github.com/umputun/revdiff" style="max-width: 100%;"></a></h1><a id="user-content-revdiff---" class="anchor" aria-label="Permalink:  revdiff  " href="#revdiff---"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">TUI for reviewing diffs, files, and documents with inline annotations. Outputs structured annotations to stdout on quit, making it easy to pipe results into AI agents, scripts, or other tools.</p>
<p dir="auto">Built for a specific use case: reviewing code changes, plans, and documents without leaving a terminal-based AI coding session (e.g., Claude Code). Just enough UI to navigate diffs and files, annotate specific lines, and return the results to the calling process - no more, no less.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Features</h2><a id="user-content-features" class="anchor" aria-label="Permalink: Features" href="#features"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Structured annotation output to stdout - pipe into AI agents, scripts, or other tools</li>
<li>Full-file diff view with syntax highlighting</li>
<li>Intra-line word-diff: highlights the specific changed words within paired add/remove lines using a brighter background overlay, off by default — enable with <code>--word-diff</code> or toggle with <code>W</code></li>
<li>Collapsed diff mode: shows final text with change markers, toggle with <code>v</code></li>
<li>Word wrap mode: wraps long lines at viewport boundary with <code>↪</code> continuation markers, toggle with <code>w</code>; optional <code>--wrap-indent N</code> for hanging-indent continuations (handy for markdown lists)</li>
<li>Page scroll overlap: <code>--page-overlap N</code> carries the bottom N lines of the screen to the top of the next one on PgUp/PgDn, so the seam between screens keeps context; the carryover is approximate on wrapped or annotated lines, which occupy several rows but are a single cursor stop</li>
<li>Horizontal scroll overflow indicators: truncated diff lines show <code>«</code> / <code>»</code> markers at the edges to signal hidden content off-screen</li>
<li>Vertical scrollbar thumb: a thicker <code>┃</code> segment on pane right borders indicates the visible portion of long diffs, file trees, and markdown TOCs; thumb size and position track scroll progress automatically</li>
<li>Line numbers: side-by-side old/new line number gutter for diffs, single column for full-context files, toggle with <code>L</code></li>
<li>Rename-aware diffs (git): a renamed file shows its origin in the diff-pane header as <code>old → new</code> and renders only the real line changes instead of a full delete-and-add</li>
<li>Mercurial support: auto-detects hg repos, translates git-style refs (HEAD, HEAD~N) to Mercurial revsets</li>
<li>Jujutsu support: auto-detects jj repos (including colocated git+jj), translates git-style refs to jj revsets (<code>HEAD</code> → <code>@-</code>, <code>HEAD~N</code> → <code>@</code> plus N+1 dashes); <code>--all-files</code> supported</li>
<li>Blame gutter: shows author name and commit age per line, toggle with <code>B</code></li>
<li>Annotate any line in the diff (added, removed, or context) plus file-level notes</li>
<li>Single-file auto-detection: when a diff contains exactly one file, hides the tree pane and gives full terminal width to the diff view</li>
<li>Two-pane TUI: file tree (left) + colorized diff viewport (right)</li>
<li>Vim-style <code>/</code> search within diff with <code>n</code>/<code>N</code> match navigation</li>
<li>Hunk navigation to jump between change groups</li>
<li>Annotation list popup (<code>@</code>): browse all annotations across files, jump to any annotation</li>
<li>Filter file tree to show only annotated files</li>
<li>Status line with filename, diff stats, hunk position, line number, and mode indicators</li>
<li>Help overlay (<code>?</code>) showing all keybindings organized by section</li>
<li>Info popup (<code>i</code>) showing launch scope (mode, VCS, ref, filters, file/status counts, aggregate <code>+/-</code> line stats), the optional <code>--description</code> prose, and the commit log subject + body for every commit in the current ref range (git/hg/jj) — useful for restoring narrative context when reviewing PR-style diffs</li>
<li>Markdown TOC navigation: single-file markdown files in context-only mode show a table-of-contents pane with header navigation and active section tracking</li>
<li>All-files mode: browse and annotate all tracked files with <code>--all-files</code> (git <code>ls-files</code> or jj <code>file list</code>), filter with <code>--include</code> and <code>--exclude</code></li>
<li>No-VCS file review: <code>--only</code> files outside a VCS repo (or not in any diff) are shown as context-only with full annotation support</li>
<li>Scratch-buffer review: annotate arbitrary piped or redirected text with <code>--stdin</code>, optionally naming it with <code>--stdin-name</code>. When the piped content sniffs as a git unified diff, revdiff parses it as a real multi-file diff (review <code>gh pr diff</code> or <code>git format-patch -1 --stdout</code> output directly); otherwise the input is shown as a single context-only buffer.</li>
<li>Pi package: launch revdiff from pi, capture annotations, and send them to the agent immediately for the normal review loop</li>
<li>Review history: auto-saves annotations and diffs to <code>~/.config/revdiff/history/</code> on quit as a safety net</li>
<li>Fully customizable colors via environment variables, CLI flags, or config file</li>
<li>Custom keybindings: remap any key via config file, export defaults with <code>--dump-keys</code></li>
</ul>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="/umputun/revdiff/blob/master/site/assets/screenshot.png"><img src="/umputun/revdiff/raw/master/site/assets/screenshot.png" alt="revdiff screenshot" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Requirements</h2><a id="user-content-requirements" class="anchor" aria-label="Permalink: Requirements" href="#requirements"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>git</code>, <code>hg</code>, or <code>jj</code> (used to generate diffs; optional when using <code>--only</code> or <code>--stdin</code>)</li>
<li>Jujutsu must be 0.27 or newer. Versions 0.23 through 0.26 have no <code>jj file annotate -T</code>, so the blame gutter does not work. Versions before 0.23 also reject the commit-log template behind the commit-info popup.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Installation</h2><a id="user-content-installation" class="anchor" aria-label="Permalink: Installation" href="#installation"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Homebrew (macOS/Linux):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="brew install umputun/apps/revdiff"><pre>brew install umputun/apps/revdiff</pre></div>
<p dir="auto"><strong>Arch Linux (AUR):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="paru -S revdiff"><pre>paru -S revdiff</pre></div>
<p dir="auto"><strong>Debian/Ubuntu (.deb):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# download the latest .deb for your architecture from GitHub Releases
sudo dpkg -i revdiff_*.deb"><pre><span class="pl-c"><span class="pl-c">#</span> download the latest .deb for your architecture from GitHub Releases</span>
sudo dpkg -i revdiff_<span class="pl-k">*</span>.deb</pre></div>
<p dir="auto"><strong>RPM-based (Fedora, RHEL, etc.):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# download the latest .rpm for your architecture from GitHub Releases
sudo rpm -i revdiff_*.rpm"><pre><span class="pl-c"><span class="pl-c">#</span> download the latest .rpm for your architecture from GitHub Releases</span>
sudo rpm -i revdiff_<span class="pl-k">*</span>.rpm</pre></div>
<p dir="auto"><strong>Go:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="go install github.com/umputun/revdiff/app/revdiff@latest"><pre>go install github.com/umputun/revdiff/app/revdiff@latest</pre></div>
<p dir="auto">Installs the <code>revdiff</code> binary into <code>GOBIN</code> (defaults to <code>$(go env GOPATH)/bin</code>). Add that directory to your <code>PATH</code>.</p>
<p dir="auto"><strong>Binary releases:</strong> download from <a href="https://github.com/umputun/revdiff/releases">GitHub Releases</a> (deb, rpm, archives for linux/darwin amd64/arm64).</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Claude Code Plugin</h2><a id="user-content-claude-code-plugin" class="anchor" aria-label="Permalink: Claude Code Plugin" href="#claude-code-plugin"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">revdiff ships with a Claude Code plugin for interactive code review directly from a Claude session. The plugin launches revdiff as a terminal overlay, captures annotations, and feeds them back to Claude for processing.</p>
<p dir="auto">The plugin requires one of the following terminals since Claude Code itself cannot display interactive TUI applications - the overlay runs revdiff in a separate terminal layer on top of the current session:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Terminal</th>
<th>Overlay method</th>
<th>Detection</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>agterm</strong></td>
<td><code>agtermctl session overlay open … --block</code> (full-pane overlay, blocks until quit)</td>
<td><code>$AGTERM_SESSION_ID</code> env var</td>
</tr>
<tr>
<td><strong>tmux</strong></td>
<td><code>display-popup</code> (blocks until quit)</td>
<td><code>$TMUX</code> env var</td>
</tr>
<tr>
<td><strong>Zellij</strong></td>
<td><code>zellij run --floating</code></td>
<td><code>$ZELLIJ</code> env var</td>
</tr>
<tr>
<td><strong>herdr</strong></td>
<td><code>herdr tab create</code> + <code>herdr pane run</code> (new tab), or a zoomed <code>herdr pane split</code> with <code>REVDIFF_HERDR_PANE=1</code></td>
<td><code>$HERDR_ENV</code> env var</td>
</tr>
<tr>
<td><strong>kitty</strong></td>
<td><code>kitty @ launch --type=overlay</code></td>
<td><code>$KITTY_LISTEN_ON</code> env var</td>
</tr>
<tr>
<td><strong>wezterm</strong></td>
<td><code>wezterm cli split-pane</code></td>
<td><code>$WEZTERM_PANE</code> env var</td>
</tr>
<tr>
<td><strong>Kaku</strong></td>
<td><code>kaku cli split-pane</code> (same API as wezterm)</td>
<td><code>$WEZTERM_PANE</code> env var</td>
</tr>
<tr>
<td><strong>cmux</strong></td>
<td><code>cmux new-split</code> + <code>cmux send</code></td>
<td><code>$CMUX_SURFACE_ID</code>, <code>__CFBundleIdentifier=com.cmuxterm.app</code>, or <code>GHOSTTY_RESOURCES_DIR</code> / <code>GHOSTTY_BIN_DIR</code> containing <code>cmux.app</code></td>
</tr>
<tr>
<td><strong>ghostty</strong></td>
<td>AppleScript split + zoom (macOS only)</td>
<td><code>$TERM_PROGRAM</code> + AppleScript probe</td>
</tr>
<tr>
<td><strong>iTerm2</strong></td>
<td><code>osascript</code> split pane (macOS only)</td>
<td><code>$ITERM_SESSION_ID</code> env var</td>
</tr>
<tr>
<td><strong>Emacs vterm</strong></td>
<td>New frame via <code>emacsclient</code></td>
<td><code>$INSIDE_EMACS</code> env var</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">Priority: agterm → tmux → Zellij → herdr → kitty → wezterm/Kaku → cmux → ghostty → iTerm2 → Emacs vterm (first detected wins). If none are available, the plugin exits with an error.</p>
<blockquote>
<p dir="auto"><strong>Note:</strong> cmux is detected before ghostty when <code>$CMUX_SURFACE_ID</code> is set, <code>__CFBundleIdentifier=com.cmuxterm.app</code>, or <code>GHOSTTY_RESOURCES_DIR</code> / <code>GHOSTTY_BIN_DIR</code> contains <code>cmux.app</code>. The cmux block uses the cmux CLI (<code>new-split</code> + <code>send --surface</code>) instead of Ghostty's AppleScript API.</p>
</blockquote>
<blockquote>
<p dir="auto"><strong>Note:</strong> iTerm2 uses a split pane (vertical or horizontal, auto-detected from terminal dimensions) rather than a full-screen overlay. The iTerm2 AppleScript API does not expose a zoom command, so the split view shares screen space with the invoking session.</p>
</blockquote>
<blockquote>
<p dir="auto"><strong>Note:</strong> Ghostty and iTerm2 launchers use <code>osascript</code> (Apple Events), which is blocked by Claude Code's sandbox. If you use these terminals with sandbox enabled, add the launcher to <code>excludedCommands</code> in your Claude Code <code>settings.json</code>:</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;sandbox&quot;: {
    &quot;excludedCommands&quot;: [&quot;*/launch-revdiff.sh*&quot;]
  }
}"><pre>{
  <span class="pl-ent">"sandbox"</span>: {
    <span class="pl-ent">"excludedCommands"</span>: [<span class="pl-s"><span class="pl-pds">"</span>*/launch-revdiff.sh*<span class="pl-pds">"</span></span>]
  }
}</pre></div>
<p dir="auto">Terminals that use CLI tools instead of AppleScript (agterm, tmux, Zellij, herdr, kitty, wezterm, Kaku, cmux) are not affected.</p>
</blockquote>
<blockquote>
<p dir="auto"><strong>Disconnect-resilient tmux window mode:</strong> set <code>REVDIFF_TMUX_WINDOW=1</code> in the launcher's environment to open revdiff in a persistent, server-owned tmux window instead of a client-owned <code>display-popup</code>. A dropped SSH or tmux client tears down a popup and kills the review, but a server-owned window survives the disconnect — reattach and the live review is still there. This is a launcher environment variable, not a revdiff flag.</p>
</blockquote>
<blockquote>
<p dir="auto"><strong>Pane-scoped overlay (herdr):</strong> Set <code>REVDIFF_HERDR_PANE=1</code> in the launcher's environment to open revdiff in a zoomed split of the agent's own herdr pane instead of a new fullscreen tab, so the agent pane stays one keypress away. It needs a herdr whose CLI carries <code>pane split</code>, <code>pane get</code> and <code>pane close</code>; an unsupported CLI or a refused split falls back to the tab overlay; a split that succeeds but returns no usable pane id fails closed with a warning rather than opening a second surface, and may leave a stray pane to close by hand. This is a launcher environment variable, not a revdiff flag.</p>
</blockquote>
<blockquote>
<p dir="auto"><strong>Pane-scoped overlay (agterm):</strong> set <code>REVDIFF_AGTERM_PANE=1</code> in the launcher's environment to open revdiff in the agent's own split pane instead of over the whole session, leaving the sibling pane live and visible. It applies only when that session is split — the session-wide overlay stands otherwise, and the launcher retries session-wide if agterm refuses the pane. The review gets pane width rather than session width, which is why it is opt-in. This is a launcher environment variable, not a revdiff flag.</p>
</blockquote>
<p dir="auto"><strong>Install:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# add marketplace and install
/plugin marketplace add umputun/revdiff
/plugin install revdiff@revdiff"><pre><span class="pl-c"><span class="pl-c">#</span> add marketplace and install</span>
/plugin marketplace add umputun/revdiff
/plugin install revdiff@revdiff</pre></div>
<p dir="auto"><strong>Use with <code>/revdiff</code> command:</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/revdiff                  -- smart detection: uncommitted, last commit, or branch diff
/revdiff HEAD~1 HEAD      -- review last commit
/revdiff main             -- review current branch against main
/revdiff --staged         -- review staged changes only
/revdiff HEAD~3 HEAD      -- review last 3 commits"><pre class="notranslate"><code>/revdiff                  -- smart detection: uncommitted, last commit, or branch diff
/revdiff HEAD~1 HEAD      -- review last commit
/revdiff main             -- review current branch against main
/revdiff --staged         -- review staged changes only
/revdiff HEAD~3 HEAD      -- review last 3 commits
</code></pre></div>
<p dir="auto"><strong>Use with free text</strong> (no slash command needed):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&quot;review diff&quot;                     -- smart detection, same as /revdiff
&quot;review diff HEAD~1 HEAD&quot;         -- last commit
&quot;review diff against main&quot;        -- branch diff
&quot;review changes from last 2 days&quot; -- Claude resolves the ref automatically
&quot;revdiff for staged changes&quot;      -- staged only"><pre class="notranslate"><code>"review diff"                     -- smart detection, same as /revdiff
"review diff HEAD~1 HEAD"         -- last commit
"review diff against main"        -- branch diff
"review changes from last 2 days" -- Claude resolves the ref automatically
"revdiff for staged changes"      -- staged only
</code></pre></div>
<p dir="auto">When no ref is provided, the plugin auto-detects the VCS (git, hg, or jj) and inspects the current repo state to pick what to review:</p>
<ul dir="auto">
<li>On main/master with uncommitted changes — reviews uncommitted changes</li>
<li>On main/master with clean tree — reviews the last commit</li>
<li>On a feature branch with clean tree — reviews branch diff against main</li>
<li>On a feature branch with uncommitted changes — asks whether to review uncommitted only or the full branch diff</li>
<li>Outside a VCS repo — falls back to asking the user what to review</li>
</ul>
<p dir="auto">The plugin includes built-in reference documentation and can answer questions about revdiff usage, available themes, keybindings, and configuration options. It can also create or modify the local config file (<code>~/.config/revdiff/config</code>) on request:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&quot;what chroma themes does revdiff support?&quot;
&quot;switch revdiff to dracula theme&quot;
&quot;what are the revdiff keybindings?&quot;
&quot;set tree width to 3 in revdiff config&quot;"><pre class="notranslate"><code>"what chroma themes does revdiff support?"
"switch revdiff to dracula theme"
"what are the revdiff keybindings?"
"set tree width to 3 in revdiff config"
</code></pre></div>
<p dir="auto">The plugin supports the full review loop: annotate → plan → fix → re-review until no more annotations remain. The bundled launcher treats exit code <code>10</code> as success-with-annotations and processes stdout normally.</p>
<p dir="auto"><strong>Ask instead of instruct:</strong> an annotation containing <code>??</code> anywhere in its text is treated as a question rather than a directive, so the agent explains that code instead of changing it. Openers <code>explain</code>, <code>remind</code>, <code>describe</code>, <code>what is</code>, <code>what are</code>, <code>how does</code>, <code>how do</code> and <code>clarify</code> do the same. <code>??</code> is the language-neutral form and works whatever you write in.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="## renderer.go:142 (+)
why a pointer here??

## store.go:88 (-)
explain what this lock protects"><pre class="notranslate"><code>## renderer.go:142 (+)
why a pointer here??

## store.go:88 (-)
explain what this lock protects
</code></pre></div>
<p dir="auto">The answer comes back as a markdown document reopened in revdiff, with a TOC sidebar, so you can annotate the explanation itself to ask follow-ups. That loop repeats until you quit without annotating. Any code-change annotations from the same batch are held and applied afterwards. The Codex plugin behaves the same way; the Pi package classifies questions too but answers them in chat.</p>
<p dir="auto"><strong>Custom launchers:</strong> the Claude diff-review skill and the cross-runtime planning plugin resolve launchers through a two-layer chain (user → bundled). Claude uses <code>${CLAUDE_PLUGIN_DATA}/scripts/&lt;launcher&gt;</code>; the Codex planning hook uses <code>${PLUGIN_DATA}/scripts/launch-plan-review.sh</code>. There is no project-level executable override by design because these hooks auto-fire in any opened repository. See <code>.claude-plugin/skills/revdiff/references/install.md</code> for diff review and <a href="/umputun/revdiff/blob/master/plugins/revdiff-planning/README.md">plugins/revdiff-planning/README.md</a> for plan review.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Plan Review Plugin</h3><a id="user-content-plan-review-plugin" class="anchor" aria-label="Permalink: Plan Review Plugin" href="#plan-review-plugin"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A separate <code>revdiff-planning</code> plugin automatically opens revdiff when Claude or Codex completes a plan, letting you annotate it before implementation. If you add annotations, the agent revises the full plan and presents it again — looping until you're satisfied. Exit code <code>10</code> means annotations were captured, not launcher failure.</p>
<p dir="auto">Claude Code:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/plugin marketplace add umputun/revdiff
/plugin install revdiff-planning@revdiff"><pre>/plugin marketplace add umputun/revdiff
/plugin install revdiff-planning@revdiff</pre></div>
<p dir="auto">Codex:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="codex plugin marketplace add umputun/revdiff
codex plugin add revdiff-planning@revdiff"><pre>codex plugin marketplace add umputun/revdiff
codex plugin add revdiff-planning@revdiff</pre></div>
<p dir="auto">Start a new Codex session and trust the hook through <code>/hooks</code>. Codex automatic review is opt-in and only fires for complete <code>&lt;proposed_plan&gt;</code> blocks in Plan mode; <code>/revdiff-plan</code> remains the manual fallback.</p>
<p dir="auto">This plugin is independent from the main <code>revdiff</code> plugin. In Claude Code it hooks <code>ExitPlanMode</code>, and so does <code>planning</code> from <code>cc-thingz</code>; Claude Code runs both hooks, so enabling both can review the same plan twice.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Pi Package</h2><a id="user-content-pi-package" class="anchor" aria-label="Permalink: Pi Package" href="#pi-package"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">revdiff also ships as a <a href="https://github.com/badlogic/pi-mono">pi</a> package. The <code>/revdiff</code> command routes requests through the revdiff skill, which resolves refs, files, and natural-language targets before launching the existing <code>revdiff</code> binary through the <code>revdiff_review</code> tool. If no annotations were captured, the agent stops the review loop unless you explicitly ask for another review.</p>
<p dir="auto"><strong>Install:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="pi install https://github.com/umputun/revdiff"><pre>pi install https://github.com/umputun/revdiff</pre></div>
<p dir="auto"><strong>Command inside pi:</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/revdiff [args]"><pre lang="text" class="notranslate"><code>/revdiff [args]
</code></pre></div>
<p dir="auto">Useful args:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/revdiff                         -- detect uncommitted, staged, or branch changes, then open revdiff
/revdiff HEAD~1 HEAD             -- review last commit
/revdiff main                    -- review against main
/revdiff --staged                -- review staged changes
/revdiff --untracked             -- include untracked files in working-tree review
/revdiff --all-files             -- browse all tracked files
/revdiff --all-files --exclude vendor
/revdiff --only README.md        -- review a single file in context-only mode
/revdiff HEAD~3 --description=&quot;why this refactor matters&quot;
/revdiff HEAD~3 --description-file=/tmp/revdiff-desc.md
/revdiff main --annotations=/tmp/revdiff-review.md"><pre lang="text" class="notranslate"><code>/revdiff                         -- detect uncommitted, staged, or branch changes, then open revdiff
/revdiff HEAD~1 HEAD             -- review last commit
/revdiff main                    -- review against main
/revdiff --staged                -- review staged changes
/revdiff --untracked             -- include untracked files in working-tree review
/revdiff --all-files             -- browse all tracked files
/revdiff --all-files --exclude vendor
/revdiff --only README.md        -- review a single file in context-only mode
/revdiff HEAD~3 --description="why this refactor matters"
/revdiff HEAD~3 --description-file=/tmp/revdiff-desc.md
/revdiff main --annotations=/tmp/revdiff-review.md
</code></pre></div>
<p dir="auto">Natural-language targets are supported because <code>/revdiff</code> routes through the skill:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/revdiff prev commit
/revdiff last tag
/revdiff 2 weeks ago"><pre lang="text" class="notranslate"><code>/revdiff prev commit
/revdiff last tag
/revdiff 2 weeks ago
</code></pre></div>
<p dir="auto">You can also call the skill explicitly with <code>/skill:revdiff &lt;request&gt;</code>.</p>
<p dir="auto"><strong>Agent workflow:</strong></p>
<ul dir="auto">
<li><code>/revdiff</code> is a Pi command alias for <code>/skill:revdiff</code>; the skill resolves the request and calls <code>revdiff_review</code>.</li>
<li><code>revdiff_review</code> suspends pi, hands the terminal to revdiff, then returns captured annotations to the agent.</li>
<li>The agent classifies annotations into explanation requests and code-change directives.</li>
<li>Explanation requests are answered first in normal chat, without opening another revdiff session for the explanation.</li>
<li>Any no-annotation <code>revdiff_review</code> result stops the loop. The agent must not relaunch revdiff unless you explicitly ask for another review.</li>
<li>For explanation-only annotations, the agent asks whether to continue the original review or finish.</li>
<li>Before editing repository files, the agent lists planned code/file changes, applies the changes, then reruns <code>revdiff_review</code> with the same args until no annotations are captured.</li>
</ul>
<p dir="auto"><strong>Notes:</strong></p>
<ul dir="auto">
<li>Requires the <code>revdiff</code> binary on <code>PATH</code></li>
<li>Set <code>REVDIFF_BIN=/absolute/path/to/revdiff</code> if pi can't find the binary</li>
<li>Direct terminal handoff is the only Pi launch mode</li>
<li>Exit code <code>10</code> means annotations were captured, not failure</li>
<li>Use <code>--untracked</code> when agent-created files should be reviewed before they are staged</li>
<li>Use <code>--description</code> or <code>--description-file</code> after analysis/refactor work so the info popup carries review context</li>
<li>Use <code>--annotations=&lt;tempfile&gt;</code> to preload in-session review notes</li>
<li>Successful <code>revdiff_review</code> results include captured annotation text; history is only for explicit latest-history requests or missing-output fallback</li>
<li>For "use my latest revdiff annotations", the agent should read the newest file under <code>$REVDIFF_HISTORY_DIR</code> or <code>~/.config/revdiff/history/</code> instead of relaunching revdiff</li>
<li>In the repo, the pi-specific resources live under <code>plugins/pi/</code> to keep harness integrations clearly separated</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Codex Plugin</h2><a id="user-content-codex-plugin" class="anchor" aria-label="Permalink: Codex Plugin" href="#codex-plugin"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">revdiff ships with a <a href="https://github.com/openai/codex">Codex CLI</a> plugin for interactive diff review and plan annotation directly from a Codex session. The plugin provides two skills:</p>
<ul dir="auto">
<li><code>/revdiff</code> — same diff review workflow as the Claude Code plugin (detect ref, launch overlay, capture annotations, feedback loop)</li>
<li><code>/revdiff-plan</code> — extracts the last Codex assistant message from session rollout files, opens it in revdiff for annotation, and feeds feedback back</li>
</ul>
<p dir="auto">The plugin uses the same terminal overlay mechanism (tmux, Zellij, herdr, kitty, wezterm, etc.) as the Claude Code plugin.</p>
<p dir="auto"><strong>Install the diff-review skills and automatic plan-review plugin:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="codex plugin marketplace add umputun/revdiff
codex plugin add revdiff@revdiff
codex plugin add revdiff-planning@revdiff"><pre>codex plugin marketplace add umputun/revdiff
codex plugin add revdiff@revdiff
codex plugin add revdiff-planning@revdiff</pre></div>
<p dir="auto">If you previously copied the skills manually, remove <code>~/.codex/skills/revdiff</code> and <code>~/.codex/skills/revdiff-plan</code> after installing the plugin so the plugin copy is the only one in use.</p>
<p dir="auto">Start a new session and trust the plugin hook through <code>/hooks</code>. The <code>Stop</code> hook runs only in Plan mode and first checks <code>last_assistant_message</code>; whenever that field has no complete <code>&lt;proposed_plan&gt;</code>, it reads the exact event transcript and selects the last assistant message for the matching <code>session_id</code> and <code>turn_id</code>, without depending on a provider-specific phase. A readable clarification turn is ignored. Missing or mismatched event data, dependencies, and launcher failures warn and fail open.</p>
<p dir="auto">When annotations are present, the hook asks Codex to return the complete revised plan with a snapshot marker on the first line inside <code>&lt;proposed_plan&gt;</code>. The next round opens a rolling compare (<code>&lt;new&gt; &lt;old&gt;</code>); reviewed snapshots are replaced, and a clean review removes the final snapshot.</p>
<p dir="auto">The <code>revdiff</code> plugin installs both interactive skills. The separate <code>revdiff-planning</code> plugin adds automatic Plan-mode review.</p>
<p dir="auto"><strong>Requirements:</strong></p>
<ul dir="auto">
<li><code>revdiff</code> binary on <code>PATH</code></li>
<li><code>jq</code> (required only for manual <code>/revdiff-plan</code> session extraction)</li>
<li>One of the supported terminal multiplexers for overlay mode</li>
</ul>
<p dir="auto"><strong>Notes:</strong></p>
<ul dir="auto">
<li>Codex treats exit code <code>10</code> as success-with-annotations and keeps captured output</li>
<li>Automatic review uses the opt-in <code>revdiff-planning</code> plugin; <code>/revdiff-plan</code> remains a manual fallback</li>
<li>Scripts are portable copies from the Claude Code plugin, not symlinks</li>
<li>Codex plugin source lives under <code>plugins/codex/</code> in the repository</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Integration with Other Tools</h3><a id="user-content-integration-with-other-tools" class="anchor" aria-label="Permalink: Integration with Other Tools" href="#integration-with-other-tools"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">OpenCode</h4><a id="user-content-opencode" class="anchor" aria-label="Permalink: OpenCode" href="#opencode"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">revdiff integrates with <a href="https://opencode.ai" rel="nofollow">OpenCode</a>. V1 provides a tool, slash command, and plan-review plugin. V2 provides a CLI plugin for <code>/revdiff</code> and automatic plan review, using the shared launcher in the client's terminal environment.</p>
<p dir="auto"><strong>Install (automatically detects OpenCode v1 or v2):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cd plugins/opencode &amp;&amp; bash setup.sh"><pre><span class="pl-c1">cd</span> plugins/opencode <span class="pl-k">&amp;&amp;</span> bash setup.sh</pre></div>
<p dir="auto">The v2 CLI plugin is discovered automatically under <code>plugins/revdiff/</code>. It runs reviews locally and returns annotations to the session captured at launch. Automatic plan review handles live completion events only, deduplicated between local clients using an atomic marker per event ID. Markers older than one day are removed on the next claim. Clients must share the same state directory and local checkout; the winner may be in a window the user is not looking at. Restart OpenCode after installing.</p>
<p dir="auto">The installer uses <code>opencode --version</code> from <code>PATH</code>; use <code>bash setup.sh --opencode /path/to/opencode /path/to/config</code> to select another v2 installation. The v2 integration supports OpenCode v2.0.0+ and has no runtime npm dependencies. Its config directory follows <code>OPENCODE_CONFIG_DIR</code>, then XDG defaults. V1 installs only to <code>~/.config/opencode</code>. Upgrade removes the obsolete v1 plan plugin, Markdown command and exact JSON registration; JSONC is left untouched with a notice. V1 code remains unchanged, and rollback leaves the inert v2 directory in place. See <a href="/umputun/revdiff/blob/master/plugins/opencode/README.md">plugins/opencode/README.md</a> for prerequisites, ownership rules and migration details.</p>
<p dir="auto"><strong>Commands inside OpenCode:</strong></p>
<p dir="auto">V2 also supports <code>/revdiff</code> from the home screen. A clean review leaves it unchanged; annotations create a feedback session using the configured default agent and selected model, falling back to the configured model on older v2 clients.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/revdiff                         -- review git diff with revdiff TUI
/revdiff HEAD~3..HEAD             -- review last 3 commits"><pre lang="text" class="notranslate"><code>/revdiff                         -- review git diff with revdiff TUI
/revdiff HEAD~3..HEAD             -- review last 3 commits
</code></pre></div>
<p dir="auto">The v2 plan-review plugin automatically launches revdiff after a completed plan-agent response in the displayed root session. Annotations and a line-numbered snapshot of the reviewed plan are returned to that session for revision, so the agent does not need the deleted temporary file. V1 uses the plan-mode idle hook.</p>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">General</h4><a id="user-content-general" class="anchor" aria-label="Permalink: General" href="#general"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The structured stdout output works with any tool that can read text. By default revdiff exits <code>0</code> even when annotations are produced; pass <code>--exit-code-on-annotations</code> to return <code>10</code> for successful annotation output:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# capture annotations for processing
rc=0
annotations=$(revdiff --exit-code-on-annotations main) || rc=$?
case &quot;$rc&quot; in
  0) [ -n &quot;$annotations&quot; ] &amp;&amp; echo &quot;$annotations&quot; | your-tool ;;
  10) echo &quot;$annotations&quot; | your-tool ;;
  *) exit &quot;$rc&quot; ;;
esac"><pre><span class="pl-c"><span class="pl-c">#</span> capture annotations for processing</span>
rc=0
annotations=<span class="pl-s"><span class="pl-pds">$(</span>revdiff --exit-code-on-annotations main<span class="pl-pds">)</span></span> <span class="pl-k">||</span> rc=<span class="pl-smi">$?</span>
<span class="pl-k">case</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$rc</span><span class="pl-pds">"</span></span> <span class="pl-k">in</span>
  0) [ <span class="pl-k">-n</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$annotations</span><span class="pl-pds">"</span></span> ] <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$annotations</span><span class="pl-pds">"</span></span> <span class="pl-k">|</span> your-tool ;;
  10) <span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$annotations</span><span class="pl-pds">"</span></span> <span class="pl-k">|</span> your-tool ;;
  <span class="pl-k">*</span>) <span class="pl-c1">exit</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$rc</span><span class="pl-pds">"</span></span> ;;
<span class="pl-k">esac</span></pre></div>
<p dir="auto">Exit status: <code>0</code> = no annotations, discarded annotations, or default mode; <code>10</code> = annotations were produced with <code>--exit-code-on-annotations</code>; <code>1</code> = real errors.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Usage</h2><a id="user-content-usage" class="anchor" aria-label="Permalink: Usage" href="#usage"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="revdiff [OPTIONS] [base] [against]"><pre class="notranslate"><code>revdiff [OPTIONS] [base] [against]
</code></pre></div>
<p dir="auto">Positional arguments support several forms:</p>
<ul dir="auto">
<li><code>revdiff</code> — uncommitted changes</li>
<li><code>revdiff HEAD~3</code> — diff a single ref against the working tree</li>
<li><code>revdiff HEAD~1 HEAD</code> — review exactly the last commit</li>
<li><code>revdiff main feature</code> — diff between two refs</li>
<li><code>revdiff main..feature</code> — same as above, using git's dot-dot syntax</li>
<li><code>revdiff main...feature</code> — changes since <code>feature</code> diverged from <code>main</code></li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Options</h3><a id="user-content-options" class="anchor" aria-label="Permalink: Options" href="#options"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Option</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>base</code></td>
<td>Git ref to diff against</td>
<td>uncommitted changes</td>
</tr>
<tr>
<td><code>against</code></td>
<td>Second git ref for two-ref diff</td>
<td></td>
</tr>
<tr>
<td><code>--staged</code></td>
<td>Show staged changes, env: <code>REVDIFF_STAGED</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--untracked</code></td>
<td>Show untracked files in the tree, env: <code>REVDIFF_UNTRACKED</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--tree-width</code></td>
<td>File tree panel width in units (1-10), env: <code>REVDIFF_TREE_WIDTH</code></td>
<td><code>2</code></td>
</tr>
<tr>
<td><code>--tab-width</code></td>
<td>Number of spaces per tab character, env: <code>REVDIFF_TAB_WIDTH</code></td>
<td><code>4</code></td>
</tr>
<tr>
<td><code>--no-colors</code></td>
<td>Disable all colors including syntax highlighting, env: <code>REVDIFF_NO_COLORS</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--no-status-bar</code></td>
<td>Hide the status bar, env: <code>REVDIFF_NO_STATUS_BAR</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--wrap</code></td>
<td>Enable line wrapping in diff view, env: <code>REVDIFF_WRAP</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--wrap-indent</code></td>
<td>Indent wrap continuation rows by N columns so they hang under the first row's content (helps when reviewing markdown lists where unindented continuation can be misread as a new bullet), env: <code>REVDIFF_WRAP_INDENT</code></td>
<td><code>0</code></td>
</tr>
<tr>
<td><code>--page-overlap</code></td>
<td>Keep N lines from the previous screen when paging the diff, env: <code>REVDIFF_PAGE_OVERLAP</code></td>
<td><code>0</code></td>
</tr>
<tr>
<td><code>--collapsed</code></td>
<td>Start in collapsed diff mode, env: <code>REVDIFF_COLLAPSED</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--compact</code></td>
<td>Start in compact diff mode (small context around changes), env: <code>REVDIFF_COMPACT</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--compact-context</code></td>
<td>Number of context lines around changes when in compact mode, env: <code>REVDIFF_COMPACT_CONTEXT</code></td>
<td><code>5</code></td>
</tr>
<tr>
<td><code>--cross-file-hunks</code></td>
<td>Allow <code>[</code> and <code>]</code> to continue into adjacent files, env: <code>REVDIFF_CROSS_FILE_HUNKS</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--cross-file-motion</code></td>
<td>Allow cursor motion (<code>j</code>/<code>k</code>, <code>PgDown</code>/<code>PgUp</code>, <code>Ctrl+d</code>/<code>Ctrl+u</code>) to continue into adjacent files at a boundary, env: <code>REVDIFF_CROSS_FILE_MOTION</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--start-at-change</code></td>
<td>Position the cursor on the first changed line, env: <code>REVDIFF_START_AT_CHANGE</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--line-numbers</code></td>
<td>Show line numbers in diff gutter, env: <code>REVDIFF_LINE_NUMBERS</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--blame</code></td>
<td>Show blame gutter, env: <code>REVDIFF_BLAME</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--word-diff</code></td>
<td>Highlight intra-line word-level changes in paired add/remove lines, env: <code>REVDIFF_WORD_DIFF</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--filter-unreviewed</code></td>
<td>Show only files not marked reviewed, env: <code>REVDIFF_FILTER_UNREVIEWED</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--annotation-marker</code></td>
<td>Prefix shown before annotation lines, env: <code>REVDIFF_ANNOTATION_MARKER</code></td>
<td><code>💬</code></td>
</tr>
<tr>
<td><code>--exit-code-on-annotations</code></td>
<td>Exit 10 when annotations are produced, env: <code>REVDIFF_EXIT_CODE_ON_ANNOTATIONS</code>, config: <code>exit-code-on-annotations</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--no-confirm-discard</code></td>
<td>Skip confirmation when discarding annotations with Q, env: <code>REVDIFF_NO_CONFIRM_DISCARD</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--no-confirm-reload</code></td>
<td>Skip confirmation when dropping annotations on reload with R, env: <code>REVDIFF_NO_CONFIRM_RELOAD</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--no-mouse</code></td>
<td>Disable mouse support (scroll wheel, click), env: <code>REVDIFF_NO_MOUSE</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--no-tree</code></td>
<td>Hide the file tree pane, env: <code>REVDIFF_NO_TREE</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--vim-motion</code></td>
<td>Enable vim-style motion preset (counts, <code>gg</code>, <code>G</code>, <code>H</code>/<code>M</code>/<code>L</code>, <code>zz</code>/<code>zt</code>/<code>zb</code>, <code>ZZ</code>/<code>ZQ</code>), env: <code>REVDIFF_VIM_MOTION</code></td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--chroma-style</code></td>
<td>Chroma color theme for syntax highlighting, env: <code>REVDIFF_CHROMA_STYLE</code></td>
<td><code>catppuccin-macchiato</code></td>
</tr>
<tr>
<td><code>--theme</code></td>
<td>Load color theme from <code>~/.config/revdiff/themes/</code>; use <code>auto</code> to choose by terminal background, env: <code>REVDIFF_THEME</code></td>
<td></td>
</tr>
<tr>
<td><code>--auto-theme-dark</code></td>
<td>Theme used by <code>--theme auto</code> on dark terminal backgrounds, env: <code>REVDIFF_AUTO_THEME_DARK</code></td>
<td><code>revdiff</code></td>
</tr>
<tr>
<td><code>--auto-theme-light</code></td>
<td>Theme used by <code>--theme auto</code> on light terminal backgrounds, env: <code>REVDIFF_AUTO_THEME_LIGHT</code></td>
<td><code>catppuccin-latte</code></td>
</tr>
<tr>
<td><code>--dump-theme</code></td>
<td>Print currently resolved colors as theme file to stdout and exit</td>
<td></td>
</tr>
<tr>
<td><code>--list-themes</code></td>
<td>Print available theme names to stdout and exit</td>
<td></td>
</tr>
<tr>
<td><code>--init-themes</code></td>
<td>Write bundled theme files to themes dir and exit</td>
<td></td>
</tr>
<tr>
<td><code>--init-all-themes</code></td>
<td>Write all gallery themes (bundled + community) to themes dir and exit</td>
<td></td>
</tr>
<tr>
<td><code>--install-theme</code></td>
<td>Install theme(s) from gallery or local file path and exit (repeatable)</td>
<td></td>
</tr>
<tr>
<td><code>-A</code>, <code>--all-files</code></td>
<td>Browse all tracked files, not just diffs (git or jj)</td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--compare-old</code></td>
<td>Compare mode: old file path (use with <code>--compare-new</code>; uses <code>git diff --no-index</code>, no VCS repo needed)</td>
<td></td>
</tr>
<tr>
<td><code>--compare-new</code></td>
<td>Compare mode: new file path (use with <code>--compare-old</code>)</td>
<td></td>
</tr>
<tr>
<td><code>--stdin</code></td>
<td>Review stdin as a scratch buffer (piped or redirected input only)</td>
<td><code>false</code></td>
</tr>
<tr>
<td><code>--stdin-name</code></td>
<td>Synthetic file name for stdin content; enables extension-based highlighting/TOC</td>
<td><code>scratch-buffer</code></td>
</tr>
<tr>
<td><code>--description</code></td>
<td>Prose context shown in the info popup (markdown; for multi-line text, use a multi-line quoted shell string or <code>--description-file</code>)</td>
<td></td>
</tr>
<tr>
<td><code>--description-file</code></td>
<td>Read the info-popup description from this file (markdown)</td>
<td></td>
</tr>
<tr>
<td><code>-I</code>, <code>--include</code></td>
<td>Include only files matching prefix, may be repeated, env: <code>REVDIFF_INCLUDE</code> (comma-separated)</td>
<td></td>
</tr>
<tr>
<td><code>-X</code>, <code>--exclude</code></td>
<td>Exclude files matching prefix, may be repeated, env: <code>REVDIFF_EXCLUDE</code> (comma-separated)</td>
<td></td>
</tr>
<tr>
<td><code>-F</code>, <code>--only</code></td>
<td>Show only matching files by exact path or suffix, may be repeated (e.g. <code>--only=model.go</code>)</td>
<td></td>
</tr>
<tr>
<td><code>-o</code>, <code>--output</code></td>
<td>Write annotations to file instead of stdout, env: <code>REVDIFF_OUTPUT</code></td>
<td></td>
</tr>
<tr>
<td><code>--post-flush-command</code></td>
<td>Run command after a successful <code>O</code> flush, env: <code>REVDIFF_POST_FLUSH_COMMAND</code>, config: <code>post-flush-command</code></td>
<td></td>
</tr>
<tr>
<td><code>--annotations</code></td>
<td>Preload annotations from a markdown file in <code>-o</code> format</td>
<td></td>
</tr>
<tr>
<td><code>--history-dir</code></td>
<td>Directory for review history auto-saves, env: <code>REVDIFF_HISTORY_DIR</code></td>
<td><code>~/.config/revdiff/history/</code></td>
</tr>
<tr>
<td><code>--config</code></td>
<td>Path to config file, env: <code>REVDIFF_CONFIG</code></td>
<td><code>~/.config/revdiff/config</code></td>
</tr>
<tr>
<td><code>--keys</code></td>
<td>Path to keybindings file, env: <code>REVDIFF_KEYS</code></td>
<td><code>~/.config/revdiff/keybindings</code></td>
</tr>
<tr>
<td><code>--dump-keys</code></td>
<td>Print effective keybindings to stdout and exit</td>
<td></td>
</tr>
<tr>
<td><code>--dump-config</code></td>
<td>Print default config to stdout and exit</td>
<td></td>
</tr>
<tr>
<td><code>-V</code>, <code>--version</code></td>
<td>Show version info</td>
<td></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Config File</h3><a id="user-content-config-file" class="anchor" aria-label="Permalink: Config File" href="#config-file"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">All options can be set in a config file at <code>~/.config/revdiff/config</code> (INI format). CLI flags and environment variables override config file values. For annotation exit status, use <code>exit-code-on-annotations = true</code>.</p>
<p dir="auto">Generate a default config file:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="mkdir -p ~/.config/revdiff
revdiff --dump-config &gt; ~/.config/revdiff/config"><pre>mkdir -p <span class="pl-k">~</span>/.config/revdiff
revdiff --dump-config <span class="pl-k">&gt;</span> <span class="pl-k">~</span>/.config/revdiff/config</pre></div>
<p dir="auto">Then uncomment and edit the values you want to change.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Themes</h3><a id="user-content-themes" class="anchor" aria-label="Permalink: Themes" href="#themes"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">revdiff ships with eight bundled color themes: <strong>basic</strong>, <strong>catppuccin-latte</strong>, <strong>catppuccin-mocha</strong>, <strong>dracula</strong>, <strong>gruvbox</strong>, <strong>nord</strong>, <strong>revdiff</strong>, and <strong>solarized-dark</strong>. Themes are stored in <code>~/.config/revdiff/themes/</code> and are automatically created on first run.</p>
<p dir="auto">Press <code>T</code> inside revdiff to open the interactive theme selector with live preview — browse themes, see colors applied instantly, and persist your choice to the config file on confirm.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# apply a theme
revdiff --theme dracula

# choose a theme from the terminal background color
revdiff --theme auto

# list available themes
revdiff --list-themes

# re-create bundled theme files (overwrites bundled, keeps custom themes)
revdiff --init-themes

# install a specific theme from the gallery
revdiff --install-theme catppuccin-latte

# install all gallery themes (bundled + community)
revdiff --init-all-themes

# export current colors as a custom theme
revdiff --dump-theme &gt; ~/.config/revdiff/themes/my-custom"><pre><span class="pl-c"><span class="pl-c">#</span> apply a theme</span>
revdiff --theme dracula

<span class="pl-c"><span class="pl-c">#</span> choose a theme from the terminal background color</span>
revdiff --theme auto

<span class="pl-c"><span class="pl-c">#</span> list available themes</span>
revdiff --list-themes

<span class="pl-c"><span class="pl-c">#</span> re-create bundled theme files (overwrites bundled, keeps custom themes)</span>
revdiff --init-themes

<span class="pl-c"><span class="pl-c">#</span> install a specific theme from the gallery</span>
revdiff --install-theme catppuccin-latte

<span class="pl-c"><span class="pl-c">#</span> install all gallery themes (bundled + community)</span>
revdiff --init-all-themes

<span class="pl-c"><span class="pl-c">#</span> export current colors as a custom theme</span>
revdiff --dump-theme <span class="pl-k">&gt;</span> <span class="pl-k">~</span>/.config/revdiff/themes/my-custom</pre></div>
<p dir="auto"><strong>Creating custom themes</strong> — two approaches:</p>
<ol dir="auto">
<li><strong>From current colors:</strong> customize individual colors in your config file or via <code>--color-*</code> flags, then dump the resolved result as a theme: <code>revdiff --dump-theme &gt; ~/.config/revdiff/themes/my-custom</code></li>
<li><strong>From scratch:</strong> copy a bundled theme and edit it directly — each file defines all 23 color keys plus <code>chroma-style</code> in INI format:</li>
</ol>
<div class="highlight highlight-source-ini notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# name: my-custom
# description: custom color scheme
chroma-style = dracula
color-accent = #bd93f9
color-border = #6272a4
...all 23 color keys..."><pre><span class="pl-c"><span class="pl-c">#</span> name: my-custom</span>
<span class="pl-c"><span class="pl-c">#</span> description: custom color scheme</span>
<span class="pl-k">chroma-style</span> = dracula
<span class="pl-k">color-accent</span> = <span class="pl-c"><span class="pl-c">#</span>bd93f9</span>
<span class="pl-k">color-border</span> = <span class="pl-c"><span class="pl-c">#</span>6272a4</span>
...all 23 color keys...</pre></div>
<p dir="auto">Set a default theme in the config file:</p>
<div class="highlight highlight-source-ini notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="theme = dracula"><pre><span class="pl-k">theme</span> = dracula</pre></div>
<p dir="auto">Or via environment variable: <code>REVDIFF_THEME=dracula</code>.</p>
<p dir="auto">Set <code>theme = auto</code> to query the terminal background and choose a matching theme. By default, auto mode uses <code>revdiff</code> for dark backgrounds and <code>catppuccin-latte</code> for light backgrounds:</p>
<div class="highlight highlight-source-ini notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="theme = auto
auto-theme-dark = revdiff
auto-theme-light = catppuccin-latte"><pre><span class="pl-k">theme</span> = auto
<span class="pl-k">auto-theme-dark</span> = revdiff
<span class="pl-k">auto-theme-light</span> = catppuccin-latte</pre></div>
<p dir="auto"><strong>Contributing themes</strong> — community themes live in the <code>themes/gallery/</code> directory. See <a href="/umputun/revdiff/blob/master/themes/README.md">themes/README.md</a> for the contribution guide, format requirements, and validation instructions.</p>
<p dir="auto"><strong>Precedence:</strong> When <code>--theme</code> is set, it takes over completely — all 23 color fields and chroma-style are overwritten by the theme, ignoring any <code>--color-*</code> flags or env vars. Without <code>--theme</code>: built-in defaults → config file → env vars → CLI flags. <code>--theme</code> + <code>--no-colors</code> prints a warning and applies the theme.</p>
<details>
<summary>Color customization flags (click to expand)</summary>
<p dir="auto">All color options accept hex values (<code>#rrggbb</code>) and have corresponding <code>REVDIFF_COLOR_*</code> env vars.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Option</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--color-accent</code></td>
<td>Active pane borders and directory names</td>
<td><code>#D5895F</code></td>
</tr>
<tr>
<td><code>--color-border</code></td>
<td>Inactive pane borders</td>
<td><code>#585858</code></td>
</tr>
<tr>
<td><code>--color-normal</code></td>
<td>File entries and context lines</td>
<td><code>#d0d0d0</code></td>
</tr>
<tr>
<td><code>--color-muted</code></td>
<td>Divider lines and status bar</td>
<td><code>#585858</code></td>
</tr>
<tr>
<td><code>--color-selected-fg</code></td>
<td>Selected file text</td>
<td><code>#ffffaf</code></td>
</tr>
<tr>
<td><code>--color-selected-bg</code></td>
<td>Selected file background</td>
<td><code>#D5895F</code></td>
</tr>
<tr>
<td><code>--color-annotation</code></td>
<td>Annotation text and markers</td>
<td><code>#ffd700</code></td>
</tr>
<tr>
<td><code>--color-cursor-fg</code></td>
<td>Cursor indicator color</td>
<td><code>#bbbb44</code></td>
</tr>
<tr>
<td><code>--color-cursor-bg</code></td>
<td>Cursor indicator background</td>
<td>terminal default</td>
</tr>
<tr>
<td><code>--color-add-fg</code></td>
<td>Added line text</td>
<td><code>#87d787</code></td>
</tr>
<tr>
<td><code>--color-add-bg</code></td>
<td>Added line background</td>
<td><code>#123800</code></td>
</tr>
<tr>
<td><code>--color-remove-fg</code></td>
<td>Removed line text</td>
<td><code>#ff8787</code></td>
</tr>
<tr>
<td><code>--color-remove-bg</code></td>
<td>Removed line background</td>
<td><code>#4D1100</code></td>
</tr>
<tr>
<td><code>--color-word-add-bg</code></td>
<td>Intra-line word-diff add background</td>
<td>auto-derived from add-bg</td>
</tr>
<tr>
<td><code>--color-word-remove-bg</code></td>
<td>Intra-line word-diff remove background</td>
<td>auto-derived from remove-bg</td>
</tr>
<tr>
<td><code>--color-modify-fg</code></td>
<td>Modified line text (collapsed mode)</td>
<td><code>#f5c542</code></td>
</tr>
<tr>
<td><code>--color-modify-bg</code></td>
<td>Modified line background (collapsed mode)</td>
<td><code>#3D2E00</code></td>
</tr>
<tr>
<td><code>--color-tree-bg</code></td>
<td>File tree pane background</td>
<td>terminal default</td>
</tr>
<tr>
<td><code>--color-diff-bg</code></td>
<td>Diff pane background</td>
<td>terminal default</td>
</tr>
<tr>
<td><code>--color-status-fg</code></td>
<td>Status bar foreground</td>
<td><code>#202020</code></td>
</tr>
<tr>
<td><code>--color-status-bg</code></td>
<td>Status bar background</td>
<td><code>#C5794F</code></td>
</tr>
<tr>
<td><code>--color-search-fg</code></td>
<td>Search match text</td>
<td><code>#1a1a1a</code></td>
</tr>
<tr>
<td><code>--color-search-bg</code></td>
<td>Search match background</td>
<td><code>#4a4a00</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary>Available chroma styles (click to expand)</summary>
<p dir="auto"><strong>Dark themes:</strong> <code>aura-theme-dark</code>, <code>aura-theme-dark-soft</code>, <code>base16-snazzy</code>, <code>catppuccin-frappe</code>, <code>catppuccin-macchiato</code> (default), <code>catppuccin-mocha</code>, <code>doom-one</code>, <code>doom-one2</code>, <code>dracula</code>, <code>evergarden</code>, <code>fruity</code>, <code>github-dark</code>, <code>gruvbox</code>, <code>hrdark</code>, <code>monokai</code>, <code>modus-vivendi</code>, <code>native</code>, <code>nord</code>, <code>nordic</code>, <code>onedark</code>, <code>paraiso-dark</code>, <code>rose-pine</code>, <code>rose-pine-moon</code>, <code>rrt</code>, <code>solarized-dark</code>, <code>solarized-dark256</code>, <code>tokyonight-moon</code>, <code>tokyonight-night</code>, <code>tokyonight-storm</code>, <code>vim</code>, <code>vulcan</code>, <code>witchhazel</code>, <code>xcode-dark</code></p>
<p dir="auto"><strong>Light themes:</strong> <code>autumn</code>, <code>borland</code>, <code>catppuccin-latte</code>, <code>colorful</code>, <code>emacs</code>, <code>friendly</code>, <code>github</code>, <code>gruvbox-light</code>, <code>igor</code>, <code>lovelace</code>, <code>manni</code>, <code>modus-operandi</code>, <code>monokailight</code>, <code>murphy</code>, <code>paraiso-light</code>, <code>pastie</code>, <code>perldoc</code>, <code>pygments</code>, <code>rainbow_dash</code>, <code>rose-pine-dawn</code>, <code>solarized-light</code>, <code>tango</code>, <code>tokyonight-day</code>, <code>trac</code>, <code>vs</code>, <code>xcode</code></p>
<p dir="auto"><strong>Other:</strong> <code>RPGLE</code>, <code>abap</code>, <code>algol</code>, <code>algol_nu</code>, <code>arduino</code>, <code>ashen</code>, <code>average</code>, <code>bw</code>, <code>hr_high_contrast</code>, <code>onesenterprise</code>, <code>swapoff</code></p>
</details>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Examples</h3><a id="user-content-examples" class="anchor" aria-label="Permalink: Examples" href="#examples"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# review uncommitted changes
revdiff

# review changes against a branch
revdiff main

# review staged changes
revdiff --staged

# review last commit
revdiff HEAD~1 HEAD

# diff between two refs
revdiff main feature

# same with git dot-dot syntax
revdiff main..feature

# review only specific files
revdiff --only=model.go --only=README.md

# browse all git-tracked files in a project
revdiff --all-files

# browse all files, excluding vendor and mocks directories
revdiff --all-files --exclude vendor --exclude mocks

# include only src/ files
revdiff --include src

# include src/ but exclude src/vendor/
revdiff --include src --exclude src/vendor

# exclude paths in normal diff mode
revdiff main --exclude vendor

# review a file outside a VCS repo (context-only, no diff markers)
revdiff --only=/tmp/plan.md

# review a file that has no VCS changes (context-only view with annotations)
revdiff --only=docs/notes.txt

# diff two arbitrary files (no VCS repo needed)
revdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md

# review arbitrary piped text as a scratch buffer
printf '# Plan\n\nShip it\n' | revdiff --stdin --stdin-name plan.md

# capture annotations from generated output
some-command | revdiff --stdin --output /tmp/annotations.txt

# round-trip: capture, edit externally, reload
revdiff -o review.md HEAD~1
$EDITOR review.md
revdiff --annotations=review.md HEAD~1"><pre><span class="pl-c"><span class="pl-c">#</span> review uncommitted changes</span>
revdiff

<span class="pl-c"><span class="pl-c">#</span> review changes against a branch</span>
revdiff main

<span class="pl-c"><span class="pl-c">#</span> review staged changes</span>
revdiff --staged

<span class="pl-c"><span class="pl-c">#</span> review last commit</span>
revdiff HEAD~1 HEAD

<span class="pl-c"><span class="pl-c">#</span> diff between two refs</span>
revdiff main feature

<span class="pl-c"><span class="pl-c">#</span> same with git dot-dot syntax</span>
revdiff main..feature

<span class="pl-c"><span class="pl-c">#</span> review only specific files</span>
revdiff --only=model.go --only=README.md

<span class="pl-c"><span class="pl-c">#</span> browse all git-tracked files in a project</span>
revdiff --all-files

<span class="pl-c"><span class="pl-c">#</span> browse all files, excluding vendor and mocks directories</span>
revdiff --all-files --exclude vendor --exclude mocks

<span class="pl-c"><span class="pl-c">#</span> include only src/ files</span>
revdiff --include src

<span class="pl-c"><span class="pl-c">#</span> include src/ but exclude src/vendor/</span>
revdiff --include src --exclude src/vendor

<span class="pl-c"><span class="pl-c">#</span> exclude paths in normal diff mode</span>
revdiff main --exclude vendor

<span class="pl-c"><span class="pl-c">#</span> review a file outside a VCS repo (context-only, no diff markers)</span>
revdiff --only=/tmp/plan.md

<span class="pl-c"><span class="pl-c">#</span> review a file that has no VCS changes (context-only view with annotations)</span>
revdiff --only=docs/notes.txt

<span class="pl-c"><span class="pl-c">#</span> diff two arbitrary files (no VCS repo needed)</span>
revdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md

<span class="pl-c"><span class="pl-c">#</span> review arbitrary piped text as a scratch buffer</span>
<span class="pl-c1">printf</span> <span class="pl-s"><span class="pl-pds">'</span># Plan\n\nShip it\n<span class="pl-pds">'</span></span> <span class="pl-k">|</span> revdiff --stdin --stdin-name plan.md

<span class="pl-c"><span class="pl-c">#</span> capture annotations from generated output</span>
some-command <span class="pl-k">|</span> revdiff --stdin --output /tmp/annotations.txt

<span class="pl-c"><span class="pl-c">#</span> round-trip: capture, edit externally, reload</span>
revdiff -o review.md HEAD~1
<span class="pl-smi">$EDITOR</span> review.md
revdiff --annotations=review.md HEAD~1</pre></div>
<p dir="auto"><code>--annotations</code> reads the same markdown format that <code>-o</code> writes (see <a href="#output-format">Output Format</a> below), so any file revdiff produces can be loaded back. You can also hand-author or generate that file from any other source — each record is <code>## path/to/file.go:LINE (+)</code> followed by the comment body — then step through the comments inline against the actual diff, edit or delete them in the TUI, and quit with <code>q</code> to write the final set to stdout (or to <code>-o</code>).</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">All-Files Mode</h3><a id="user-content-all-files-mode" class="anchor" aria-label="Permalink: All-Files Mode" href="#all-files-mode"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use <code>--all-files</code> (or <code>-A</code>) to browse all tracked files in a project, not just files with changes. This turns revdiff into a general-purpose code annotation tool. All files are shown in context-only mode (no <code>+</code>/<code>-</code> markers) with full annotation and syntax highlighting support.</p>
<p dir="auto"><code>--all-files</code> requires a git or jj repository (uses <code>git ls-files</code> or <code>jj file list</code> for file discovery) and is mutually exclusive with refs, <code>--staged</code>, and <code>--only</code>. Not supported in hg repos.</p>
<p dir="auto">Combine with <code>--include</code> (or <code>-I</code>) to narrow to specific paths and <code>--exclude</code> (or <code>-X</code>) to filter out unwanted paths:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="revdiff --all-files --include src
revdiff --all-files --include src --exclude src/vendor
revdiff --all-files --exclude vendor --exclude mocks"><pre>revdiff --all-files --include src
revdiff --all-files --include src --exclude src/vendor
revdiff --all-files --exclude vendor --exclude mocks</pre></div>
<p dir="auto"><code>--include</code> and <code>--exclude</code> both use prefix matching: <code>--include src</code> keeps only <code>src/</code>, <code>src/foo.go</code>, etc. <code>--exclude vendor</code> skips <code>vendor/</code>, <code>vendor/foo.go</code>, etc. Both work in <code>--all-files</code> and normal diff modes and are composable: include narrows first, then exclude removes from the included set.</p>
<p dir="auto">Both options can be persisted in the config file:</p>
<div class="highlight highlight-source-ini notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="include = src
exclude = vendor
exclude = mocks"><pre><span class="pl-k">include</span> = src
<span class="pl-k">exclude</span> = vendor
<span class="pl-k">exclude</span> = mocks</pre></div>
<p dir="auto">Or via environment variables (comma-separated): <code>REVDIFF_INCLUDE=src</code>, <code>REVDIFF_EXCLUDE=vendor,mocks</code>.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Context-Only File Review</h3><a id="user-content-context-only-file-review" class="anchor" aria-label="Permalink: Context-Only File Review" href="#context-only-file-review"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When <code>--only</code> specifies a file that has no VCS changes (or when no VCS repo exists at all), revdiff shows the file in context-only mode: all lines are displayed without <code>+</code>/<code>-</code> gutter markers, with full annotation and syntax highlighting support. This enables reviewing arbitrary files without requiring VCS context.</p>
<p dir="auto">Two scenarios trigger this mode:</p>
<ol dir="auto">
<li><strong>Inside a repo (git/hg/jj)</strong> - <code>--only</code> files not in the diff are read from disk and shown alongside any changed files</li>
<li><strong>Outside a VCS repo</strong> - <code>--only</code> is required; files are read directly from disk</li>
</ol>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Two-File Diff</h3><a id="user-content-two-file-diff" class="anchor" aria-label="Permalink: Two-File Diff" href="#two-file-diff"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use <code>--compare-old=&lt;path&gt;</code> together with <code>--compare-new=&lt;path&gt;</code> to diff two arbitrary files on disk using <code>git diff --no-index</code>. No VCS repository is required — this works anywhere <code>git</code> is installed.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="revdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md
revdiff --compare-old=a.txt --compare-new=b.txt"><pre>revdiff --compare-old=/tmp/plan-old.md --compare-new=docs/plans/plan.md
revdiff --compare-old=a.txt --compare-new=b.txt</pre></div>
<p dir="auto"><code>--compare-old</code> and <code>--compare-new</code> must be used together and are mutually exclusive with refs, <code>--staged</code>, <code>--only</code>, <code>--all-files</code>, <code>--stdin</code>, <code>--include</code>, <code>--exclude</code>, and <code>--annotations</code>. All standard diff features work: word-diff, compact mode, syntax highlighting, scrollbar, and inline annotations.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Scratch-Buffer Review</h3><a id="user-content-scratch-buffer-review" class="anchor" aria-label="Permalink: Scratch-Buffer Review" href="#scratch-buffer-review"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use <code>--stdin</code> to review arbitrary piped or redirected text. revdiff sniffs the input for a git unified-diff signature: when a line beginning with <code>diff --git a/</code> is found near the start, the input is parsed as a real multi-file diff (one tree entry per file, with <code>+</code>/<code>-</code> markers, hunk navigation, word-diff, compact mode, and per-file annotations); otherwise the input is shown as a single context-only buffer with all lines as context, supporting annotations, file-level notes, search, wrap, collapsed mode, and structured output. Any per-section parse failure falls the whole input back to raw-text mode so a malformed patch never silently drops files. Input is capped at 64 MiB.</p>
<p dir="auto"><code>--stdin</code> is explicit and mutually exclusive with refs, <code>--staged</code>, <code>--only</code>, <code>--all-files</code>, <code>--include</code>, <code>--exclude</code>, and <code>--annotations</code>. stdin mode requires piped or redirected input; plain terminal stdin is rejected to avoid accidentally launching an empty scratch buffer.</p>
<p dir="auto">Use <code>--stdin-name</code> to control the synthetic filename for the context-only case (it is ignored in multi-file diff mode, where the tree shows the real paths). This gives annotation output a stable key and enables filename-based syntax highlighting or markdown TOC activation:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="echo &quot;plain text&quot; | revdiff --stdin
printf '# Plan\n\nBody\n' | revdiff --stdin --stdin-name plan.md
git show HEAD~1:README.md | revdiff --stdin --stdin-name README.md

# multi-file diff parsing — tree shows real paths, per-file annotations
gh pr diff 123 | revdiff --stdin
git format-patch -1 --stdout | revdiff --stdin"><pre><span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">"</span>plain text<span class="pl-pds">"</span></span> <span class="pl-k">|</span> revdiff --stdin
<span class="pl-c1">printf</span> <span class="pl-s"><span class="pl-pds">'</span># Plan\n\nBody\n<span class="pl-pds">'</span></span> <span class="pl-k">|</span> revdiff --stdin --stdin-name plan.md
git show HEAD~1:README.md <span class="pl-k">|</span> revdiff --stdin --stdin-name README.md

<span class="pl-c"><span class="pl-c">#</span> multi-file diff parsing — tree shows real paths, per-file annotations</span>
gh pr diff 123 <span class="pl-k">|</span> revdiff --stdin
git format-patch -1 --stdout <span class="pl-k">|</span> revdiff --stdin</pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Review Description</h3><a id="user-content-review-description" class="anchor" aria-label="Permalink: Review Description" href="#review-description"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use <code>--description</code> (or <code>--description-file=path.md</code>) to attach prose context to a review. The text is rendered at the top of the info popup (<code>i</code> key), with the same markdown highlighting used for <code>.md</code> files in the diff view. Useful when an agent (or a script) launches revdiff on your behalf and you come back to it later — the popup tells you what the change is and why.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="revdiff HEAD~3 --description=&quot;# Refactor auth middleware

Drop session-token storage to meet new compliance requirements.
See ticket SEC-441 for context.&quot;

# longer descriptions: keep the markdown in a file
revdiff HEAD~3 --description-file=.review-description.md"><pre>revdiff HEAD~3 --description=<span class="pl-s"><span class="pl-pds">"</span># Refactor auth middleware</span>
<span class="pl-s"></span>
<span class="pl-s">Drop session-token storage to meet new compliance requirements.</span>
<span class="pl-s">See ticket SEC-441 for context.<span class="pl-pds">"</span></span>

<span class="pl-c"><span class="pl-c">#</span> longer descriptions: keep the markdown in a file</span>
revdiff HEAD~3 --description-file=.review-description.md</pre></div>
<p dir="auto"><code>--description</code> and <code>--description-file</code> are mutually exclusive. The description section is hidden when neither is set, so the flag is purely additive — existing invocations are unchanged.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Markdown TOC Navigation</h3><a id="user-content-markdown-toc-navigation" class="anchor" aria-label="Permalink: Markdown TOC Navigation" href="#markdown-toc-navigation"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When reviewing a single markdown file in context-only mode (e.g., <code>revdiff --only=README.md</code> or <code>printf '# title\n' | revdiff --stdin --stdin-name plan.md</code>), revdiff shows a table-of-contents pane on the left listing all markdown headers. Use <code>Tab</code> to switch focus between the TOC and diff panes, <code>j</code>/<code>k</code> to navigate headers, and <code>Enter</code> to jump to a header in the diff. The TOC automatically highlights the current section as you scroll through the file.</p>
<p dir="auto">This mode activates when all three conditions are met: single file, markdown extension (<code>.md</code>/<code>.markdown</code>), and all lines are context (no diff changes). Headers inside fenced code blocks are excluded from the TOC.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Beyond Code Review</h3><a id="user-content-beyond-code-review" class="anchor" aria-label="Permalink: Beyond Code Review" href="#beyond-code-review"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The <code>--only</code> flag enables use cases beyond VCS diffs. Any text file can be loaded for annotation — no VCS repo required.</p>
<p dir="auto"><strong>Reviewing AI-generated drafts</strong> — When an AI assistant drafts text to be posted publicly (PR comments, issue responses, release notes), write it to a temp file and review in revdiff. Annotate specific lines with changes, the assistant reads annotations and rewrites, re-open to verify. Same annotate-fix-verify loop as code review.</p>
<p dir="auto"><strong>Reviewing documentation and specs</strong> — Markdown files, API specs, config files, and plan documents can all be reviewed with inline annotations. Useful for reviewing RFCs, annotating configs before deployment, or marking up plans with questions.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="revdiff --only=docs/plans/feature.md
revdiff --only=/tmp/draft-comment.md"><pre>revdiff --only=docs/plans/feature.md
revdiff --only=/tmp/draft-comment.md</pre></div>
<p dir="auto"><strong>Reviewing generated output</strong> — CI configs, Terraform plans, generated migrations, or command output. Load files with <code>--only</code> or stream ephemeral output with <code>--stdin</code>, annotate what needs fixing, feed annotations back to the generator.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Zed Integration</h3><a id="user-content-zed-integration" class="anchor" aria-label="Permalink: Zed Integration" href="#zed-integration"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Zed's <a href="https://zed.dev/docs/tasks" rel="nofollow">custom tasks</a> can launch revdiff directly in an editor terminal tab.</p>
<p dir="auto">See the <a href="https://revdiff.com/docs.html#zed-integration" rel="nofollow">Zed integration guide</a> for ready-to-use task definitions, keybinding setup, and platform-specific clipboard notes.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Review History</h3><a id="user-content-review-history" class="anchor" aria-label="Permalink: Review History" href="#review-history"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When you quit with annotations (<code>q</code>), revdiff automatically saves a copy of the review session to <code>~/.config/revdiff/history/&lt;repo-name&gt;/&lt;timestamp&gt;.md</code>. This is a safety net — if annotations are lost (process crash, agent fails to capture stdout), the history file preserves them.</p>
<p dir="auto">Each history file contains:</p>
<ul dir="auto">
<li>Header with path, refs, and (git only) a short commit hash</li>
<li>Full annotation output (same format as stdout)</li>
<li>Raw git diff for annotated files only</li>
</ul>
<p dir="auto">History auto-save is always on and silent — errors are logged to stderr, never fail the process. No history is saved on discard quit (<code>Q</code>) or when there are no annotations. For <code>--stdin</code> mode, files are saved under <code>stdin/</code> subdirectory; for <code>--only</code> without git, the parent directory name is used instead of a repo name.</p>
<p dir="auto">The history file is also a crash-recovery save when the process is terminated by a signal — a SIGHUP from a dropped SSH or tmux client, or a SIGTERM. On a signal exit only the history file is written, never the <code>-o</code> output, because a signal is not the deliberate handoff that <code>q</code> and <code>O</code> perform. Recover the annotations the usual way — load the newest history file. A signal-delivered SIGTERM previously wrote the <code>-o</code> output; it no longer does.</p>
<p dir="auto">Override the history directory with <code>--history-dir</code>, <code>REVDIFF_HISTORY_DIR</code> env var, or <code>history-dir</code> in the config file.</p>
<p dir="auto">In the Claude Code and Codex plugins, you can also tell the agent to use a past review by saying things like "locate my latest revdiff review" or "use the annotations from the review I just did in another terminal". The plugin reads the newest history file for the current repo via the helper script <code>read-latest-history.sh</code> and processes the annotations as if they had come from a fresh launcher call. This is useful for standalone revdiff runs outside the plugin, or when the live launcher output is unavailable (e.g., a broken custom launcher or a crashed agent).</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Key Bindings</h3><a id="user-content-key-bindings" class="anchor" aria-label="Permalink: Key Bindings" href="#key-bindings"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Navigation:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Key</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>j/k</code> or up/down</td>
<td>Navigate files (tree) / scroll diff (diff pane); with <code>--cross-file-motion</code>, continues to the previous/next file at the boundary</td>
</tr>
<tr>
<td><code>h/l</code></td>
<td>Switch between file tree and diff pane</td>
</tr>
<tr>
<td>left/right</td>
<td>Horizontal scroll in diff pane (truncated lines show <code>«</code> / <code>»</code> overflow indicators at the edges)</td>
</tr>
<tr>
<td><code>Tab</code></td>
<td>Switch between file tree and diff pane</td>
</tr>
<tr>
<td><code>PgDown/PgUp</code></td>
<td>Page scroll in file tree and diff pane; with <code>--cross-file-motion</code>, continues to the previous/next file at the boundary</td>
</tr>
<tr>
<td><code>Ctrl+d/Ctrl+u</code></td>
<td>Half-page scroll in file tree and diff pane; with <code>--cross-file-motion</code>, continues to the previous/next file at the boundary</td>
</tr>
<tr>
<td><code>J/K</code></td>
<td>Scroll diff viewport (works from either pane)</td>
</tr>
<tr>
<td><code>Home/End</code></td>
<td>Jump to first/last item</td>
</tr>
<tr>
<td><code>Enter</code></td>
<td>Switch to diff pane (tree) / start annotation (diff pane)</td>
</tr>
<tr>
<td><code>n/p</code></td>
<td>Next/previous changed file; next/prev header in markdown TOC mode (n = next match when search active)</td>
</tr>
<tr>
<td><code>P</code></td>
<td>Open the file picker</td>
</tr>
<tr>
<td><code>[</code> / <code>]</code></td>
<td>Jump to previous/next change hunk in diff; add <code>--cross-file-hunks</code> to continue into the previous/next file at the boundary</td>
</tr>
<tr>
<td><code>e</code></td>
<td>Open focused file in <code>$EDITOR</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">The file picker lists paths currently visible in the sidebar, so annotated-only and unreviewed-only filters remain active. Printable keys always filter full relative paths; use the arrow keys or mouse wheel to move, and press <code>Enter</code> or left-click to jump. <code>Backspace</code> edits the filter. The first <code>Esc</code> clears a non-empty filter and keeps the picker open; the second closes it. Because printable keys always filter, <code>P</code> typed inside the picker adds to the filter rather than closing it; a <code>jump_file</code> binding with a modifier (e.g. <code>map alt+f jump_file</code>) closes the picker when pressed again.</p>
<p dir="auto"><strong>Search:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Key</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>/</code></td>
<td>Start search in diff pane</td>
</tr>
<tr>
<td><code>n</code></td>
<td>Next search match (overrides next file when search active)</td>
</tr>
<tr>
<td><code>N</code></td>
<td>Previous file (previous search match when searching)</td>
</tr>
<tr>
<td><code>↑</code> / <code>Ctrl+P</code></td>
<td>Recall previous search query (in search prompt)</td>
</tr>
<tr>
<td><code>↓</code> / <code>Ctrl+N</code></td>
<td>Recall next search query / clear (in search prompt)</td>
</tr>
<tr>
<td><code>Esc</code></td>
<td>Cancel search input / clear search results</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Annotations:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Key</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>a</code> or <code>Enter</code> (diff pane)</td>
<td>Annotate current diff line</td>
</tr>
<tr>
<td><code>A</code></td>
<td>Add file-level annotation (stored at top of diff)</td>
</tr>
<tr>
<td><code>@</code></td>
<td>Toggle annotation list popup (navigate and jump to any annotation)</td>
</tr>
<tr>
<td><code>}</code> / <code>{</code></td>
<td>Jump to next/previous annotation (always crosses file boundaries; silent no-op at the first/last annotation)</td>
</tr>
<tr>
<td><code>d</code></td>
<td>Delete annotation under cursor</td>
</tr>
<tr>
<td><code>O</code></td>
<td>Export annotations without exiting (requires <code>--output</code> and/or <code>--post-flush-command</code>)</td>
</tr>
<tr>
<td><code>Ctrl+E</code> (during annotation input)</td>
<td>Open <code>$EDITOR</code> for multi-line annotation (<code>open_editor</code> — rebindable)</td>
</tr>
<tr>
<td><code>Esc</code></td>
<td>Cancel annotation input</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">While the annotation input is active, press <code>Ctrl+E</code> (or whatever key is bound to <code>open_editor</code>) to hand off the current text to an external editor for multi-line comments. Editor resolution: <code>$EDITOR</code> → <code>$VISUAL</code> → <code>vi</code>. Values with arguments work (e.g. <code>EDITOR="code --wait"</code>). On editor save and quit, the full file contents (including newlines) become the annotation. Quitting the editor with an empty file cancels the annotation and preserves any previously stored note on that line. Multi-line annotations are rendered line-by-line in the diff view, shown flattened in the annotation list popup (<code>@</code>), and emitted with embedded newlines in the structured output.</p>
<p dir="auto">Press <code>e</code> in the diff pane to open the focused file in <code>$EDITOR</code> (<code>open_file_in_editor</code> — rebindable) when revdiff has a stable source path. Editor resolution is the same <code>$EDITOR</code> → <code>$VISUAL</code> → <code>vi</code> chain. Known editors receive either <code>$EDITOR +N path</code> or <code>$EDITOR --goto path:N</code> as appropriate; unknown editors receive only the file path. File lines are resolved on a best-effort basis. For working tree changes, a clean editor exit reloads the displayed file. For <code>--staged</code> or refs, a clean editor exit returns to revdiff without reloading the displayed diff. In compare mode, <code>e</code> opens the <code>--compare-new</code> side. Working tree files with line annotations cannot be opened for editing because edits can orphan those annotations. Diffs read with <code>--stdin</code> do not support opening files. Unsupported rows or files and editor errors show a status hint instead of launching an editor or changing the diff.</p>
<p dir="auto">Press <code>O</code> to export the current annotations without exiting (<code>flush_output</code>, rebindable). Configure <code>--output</code>, <code>--post-flush-command</code>, or both. With <code>--output</code>, each flush atomically overwrites the file with the full current annotation set (a snapshot, not an append log). With <code>--post-flush-command</code>, the same snapshot is sent to the command on stdin. If neither is configured, or if there are no annotations, revdiff shows a status hint and does nothing.</p>
<p dir="auto">The output file supports a keep-open review loop with an AI agent: annotate, flush with <code>O</code>, let the agent read the file and edit code, then reload with <code>R</code> and continue in the same session.</p>
<p dir="auto">For a local clipboard-only workflow on macOS, set this in <code>~/.config/revdiff/config</code>:</p>
<div class="highlight highlight-source-ini notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="post-flush-command = pbcopy"><pre><span class="pl-k">post-flush-command</span> = pbcopy</pre></div>
<p dir="auto">Each <code>O</code> copies the full current annotation set without requiring <code>--output</code>. On Linux, use <code>xclip -selection clipboard</code> for X11 or <code>wl-copy</code> for Wayland.</p>
<p dir="auto">For a terminal clipboard over SSH or a multiplexer, use OSC 52. revdiff does not include an OSC 52 helper; create an <code>osc-copy</code> shell script on your <code>PATH</code> that reads stdin and writes the clipboard sequence to <code>/dev/tty</code>:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#!/bin/sh
data=$(base64 | tr -d '\n')
printf '\033]52;c;%s\007' &quot;$data&quot; &gt; /dev/tty"><pre><span class="pl-c"><span class="pl-c">#!</span>/bin/sh</span>
data=<span class="pl-s"><span class="pl-pds">$(</span>base64 <span class="pl-k">|</span> tr -d <span class="pl-s"><span class="pl-pds">'</span>\n<span class="pl-pds">'</span></span><span class="pl-pds">)</span></span>
<span class="pl-c1">printf</span> <span class="pl-s"><span class="pl-pds">'</span>\033]52;c;%s\007<span class="pl-pds">'</span></span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$data</span><span class="pl-pds">"</span></span> <span class="pl-k">&gt;</span> /dev/tty</pre></div>
<p dir="auto">After making the script executable, run revdiff with <code>--post-flush-command=osc-copy</code> or set <code>post-flush-command = osc-copy</code> in the config file. No output file is required; add <code>--output</code> only when the same flush should also write a snapshot file.</p>
<p dir="auto">The post-flush command runs synchronously. Use a fast, non-interactive command because revdiff waits for it to finish before restoring the TUI.</p>
<p dir="auto">Press <code>Space</code> to mark the focused file reviewed. Press <code>F</code> to toggle the sidebar between all files and unreviewed files; while filtered, marking a file reviewed removes it from the list and advances to the next unfinished file. On <code>R</code> reload, revdiff keeps the mark only when the file's effective text diff is unchanged; rebases that only shift line numbers or surrounding context keep it, while changed or removed files lose it. Binary files and opaque placeholders are conservatively unmarked on reload because their rendered diff does not expose enough content to prove they are unchanged.</p>
<p dir="auto"><strong>View:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Key</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>v</code></td>
<td>Toggle collapsed diff mode (shows final text with change markers)</td>
</tr>
<tr>
<td><code>C</code></td>
<td>Toggle compact diff view (small context around changes, re-fetches current file)</td>
</tr>
<tr>
<td><code>w</code></td>
<td>Toggle word wrap (long lines wrap with <code>↪</code> continuation markers)</td>
</tr>
<tr>
<td><code>t</code></td>
<td>Toggle tree/TOC pane visibility (gives diff full terminal width)</td>
</tr>
<tr>
<td><code>L</code></td>
<td>Toggle line numbers (side-by-side old/new for diffs, single column for full-context files)</td>
</tr>
<tr>
<td><code>B</code></td>
<td>Toggle blame gutter (author name + commit age per line)</td>
</tr>
<tr>
<td><code>W</code></td>
<td>Toggle intra-line word-diff highlighting for paired add/remove lines</td>
</tr>
<tr>
<td><code>.</code></td>
<td>Expand/collapse individual hunk under cursor (collapsed mode only)</td>
</tr>
<tr>
<td><code>T</code></td>
<td>Open theme selector with live preview</td>
</tr>
<tr>
<td><code>f</code></td>
<td>Toggle filter: all files / annotated only (shown when annotations exist)</td>
</tr>
<tr>
<td><code>F</code></td>
<td>Toggle filter: all files / unreviewed only</td>
</tr>
<tr>
<td><code>?</code></td>
<td>Toggle help overlay showing all keybindings</td>
</tr>
<tr>
<td><code>i</code></td>
<td>Toggle info popup — review scope (mode, VCS, ref, filters, file/status counts, aggregate <code>+/-</code> stats) plus the commit log for the current ref range when applicable</td>
</tr>
<tr>
<td><code>R</code></td>
<td>Reload diff from VCS (warns if annotations exist)</td>
</tr>
<tr>
<td><code>q</code></td>
<td>Quit, output annotations to stdout</td>
</tr>
<tr>
<td><code>Q</code></td>
<td>Discard all annotations and quit (confirms if annotations exist)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Status Bar Icons</h3><a id="user-content-status-bar-icons" class="anchor" aria-label="Permalink: Status Bar Icons" href="#status-bar-icons"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The status bar shows a fixed row of mode indicators on the right side. All slots are always rendered — active modes use the status bar foreground color, inactive modes use muted gray, so the row occupies the same width regardless of what's toggled on. The help overlay (<code>?</code>) shows each icon beside the key that controls it.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Icon</th>
<th>Toggle</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>▼</code></td>
<td><code>v</code></td>
<td>Collapsed diff mode</td>
</tr>
<tr>
<td><code>⊂</code></td>
<td><code>C</code></td>
<td>Compact diff mode (small context around changes)</td>
</tr>
<tr>
<td><code>◉</code></td>
<td><code>f</code></td>
<td>Filter: annotated files only</td>
</tr>
<tr>
<td><code>↩</code></td>
<td><code>w</code></td>
<td>Word wrap mode</td>
</tr>
<tr>
<td><code>≋</code></td>
<td><code>/</code></td>
<td>Search active</td>
</tr>
<tr>
<td><code>⊟</code></td>
<td><code>t</code></td>
<td>Tree/TOC pane hidden (diff uses full width)</td>
</tr>
<tr>
<td><code>#</code></td>
<td><code>L</code></td>
<td>Line numbers visible in gutter</td>
</tr>
<tr>
<td><code>b</code></td>
<td><code>B</code></td>
<td>Blame gutter visible</td>
</tr>
<tr>
<td><code>±</code></td>
<td><code>W</code></td>
<td>Intra-line word-diff highlighting</td>
</tr>
<tr>
<td><code>✓</code> / <code>○</code></td>
<td><code>Space</code> / <code>F</code></td>
<td>Reviewed files / unreviewed-only filter active</td>
</tr>
<tr>
<td><code>∅</code></td>
<td><code>u</code></td>
<td>Untracked files visible in tree</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">On narrow terminals, the left-hand segments are dropped before the icons: search position first, then line and hunk info, then the filename truncates. The icon row on the right stays put.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Mouse Support</h3><a id="user-content-mouse-support" class="anchor" aria-label="Permalink: Mouse Support" href="#mouse-support"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">revdiff enables mouse tracking by default so the scroll wheel and left-click work consistently across terminals.</p>
<ul dir="auto">
<li><strong>Scroll wheel</strong>: scrolls whichever pane the cursor is over. In the tree/TOC pane the wheel moves the cursor one entry per notch (matches <code>j</code>/<code>k</code>). In the diff pane the wheel scrolls the viewport by three lines per notch — the diff cursor stays on its current logical line and is pinned to the visible edge if scrolling pushes it off-screen. During fast scrolls (a trackpad flick) the cursor highlight catches up after a brief pause once the burst settles, matching less/vim behavior.</li>
<li><strong>Shift+scroll</strong>: half-page scroll in the diff pane. In the tree/TOC pane Shift+wheel behaves the same as plain wheel (one entry per notch — no page step).</li>
<li><strong>Left-click in the tree</strong>: focuses the tree and selects/loads the clicked entry (same as pressing <code>j</code>/<code>k</code> to land there). Clicking a directory row moves the cursor but does not load a file.</li>
<li><strong>Left-click in the diff</strong>: focuses the diff and moves the cursor to the clicked line. Enables a "click, then <code>a</code>" annotation flow.</li>
<li><strong>Left-click in the TOC pane</strong> (single-file markdown): focuses the TOC and selects the clicked header.</li>
<li><strong>Scroll wheel in overlay popups</strong> (info, annotations, themes, help): scrolls the popup content or moves its cursor. Shift+wheel uses a half-page step. In the theme selector, wheel previews each theme live.</li>
<li><strong>Left-click in the annotation popup</strong>: jumps to the clicked annotation (same as pressing <code>Enter</code>).</li>
<li><strong>Left-click in the theme popup</strong>: confirms the clicked theme (same as pressing <code>Enter</code>). Clicks on the filter row or blank separator are ignored.</li>
<li><strong>Left-click in the file picker</strong>: jumps to the clicked file (same as pressing <code>Enter</code>). Clicks on the filter row or blank separator are ignored.</li>
<li><strong>Scroll wheel in the file picker</strong>: moves the picker cursor. Shift+wheel uses a half-page step.</li>
</ul>
<p dir="auto">Horizontal wheel, right-click, middle-click, drag selection, and clicks on the status bar or diff header are intentionally ignored. Clicks outside an open overlay are swallowed — dismiss an overlay with <code>Esc</code> or its toggle key. Modal states (annotation input, search input, confirm discard, reload confirm) swallow mouse events entirely.</p>
<p dir="auto"><strong>Text selection trade-off</strong> — once mouse tracking is on, plain drag is captured by revdiff. For terminal-native text selection:</p>
<ul dir="auto">
<li><strong>kitty</strong>: hold <code>Ctrl+Shift</code> while dragging</li>
<li><strong>iTerm2</strong>: hold <code>Option</code> while dragging</li>
<li><strong>ghostty</strong> (and ghostty-based terminals such as agterm): hold <code>Shift</code> while dragging. Ghostty also uses <code>Shift</code> to <em>extend</em> an existing selection, so if text is already selected the drag grows that selection instead of starting a new one - clear it first. Ghostty 1.3.0+ additionally has a <code>toggle_mouse_reporting</code> keybind, unbound by default, which suspends mouse capture without restarting revdiff</li>
<li><strong>most other terminals</strong>: hold <code>Shift</code> while dragging</li>
</ul>
<p dir="auto">Because the tree pane is rendered alongside the diff on the same rows, multi-line Shift+drag will include tree content. For clean copies of diff text, use your terminal's block-select mode (Option+drag in iTerm2, Ctrl+Shift+drag in kitty) or run with <code>--no-mouse</code> to disable mouse capture entirely.</p>
<p dir="auto">Opt out with <code>--no-mouse</code>, <code>REVDIFF_NO_MOUSE=true</code>, or <code>no-mouse = true</code> in the config file.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Custom Keybindings</h3><a id="user-content-custom-keybindings" class="anchor" aria-label="Permalink: Custom Keybindings" href="#custom-keybindings"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">All keybindings can be customized via a keybindings file at <code>~/.config/revdiff/keybindings</code>. Override the path with <code>--keys</code> flag or <code>REVDIFF_KEYS</code> env var.</p>
<p dir="auto">The file uses a simple <code>map</code>/<code>unmap</code> format (blank lines and <code>#</code> comments are ignored):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# ~/.config/revdiff/keybindings
map ctrl+d half_page_down
map ctrl+u half_page_up
map x quit
unmap q"><pre class="notranslate"><code># ~/.config/revdiff/keybindings
map ctrl+d half_page_down
map ctrl+u half_page_up
map x quit
unmap q
</code></pre></div>
<ul dir="auto">
<li><code>map &lt;key&gt; &lt;action&gt;</code> — binds a key to an action (additive, defaults are kept unless explicitly unmapped)</li>
<li><code>unmap &lt;key&gt;</code> — removes a default binding</li>
</ul>
<p dir="auto">Generate a template with all current bindings:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="mkdir -p ~/.config/revdiff
revdiff --dump-keys &gt; ~/.config/revdiff/keybindings"><pre>mkdir -p <span class="pl-k">~</span>/.config/revdiff
revdiff --dump-keys <span class="pl-k">&gt;</span> <span class="pl-k">~</span>/.config/revdiff/keybindings</pre></div>
<p dir="auto">Then edit to taste. Fixed modal keys (Enter, Esc in annotation/search input, confirm discard) are not remappable. Keymap-resolved actions like <code>open_editor</code> work during annotation input and can be rebound.</p>
<p dir="auto"><strong>Paging the diff from the file tree:</strong> <code>J</code>/<code>K</code> scroll the diff viewport from either pane, but only by a few lines, while <code>PgDown</code>/<code>PgUp</code> and <code>Ctrl+d</code>/<code>Ctrl+u</code> stay pane-relative and page whichever pane has focus. The <code>scroll_diff_page_*</code> and <code>scroll_diff_half_page_*</code> actions are the page-sized versions of <code>J</code>/<code>K</code> — they ship with no default key, so bind them to get lazygit-style paging that always targets the diff:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="map pgdown scroll_diff_page_down
map pgup scroll_diff_page_up
map ctrl+d scroll_diff_half_page_down
map ctrl+u scroll_diff_half_page_up"><pre class="notranslate"><code>map pgdown scroll_diff_page_down
map pgup scroll_diff_page_up
map ctrl+d scroll_diff_half_page_down
map ctrl+u scroll_diff_half_page_up
</code></pre></div>
<p dir="auto">Three consequences worth knowing. This also replaces cursor paging while the diff pane has focus: the keys scroll the viewport and pin the cursor back into view instead of walking the cursor a page at a time. The file tree and markdown TOC lose their own page-sized traversal on those keys. And because <code>page_down</code>, <code>page_up</code>, <code>half_page_down</code> and <code>half_page_up</code> have no other default key, rebinding all four lines leaves them unbound everywhere, including the <code>?</code> help and <code>i</code> info overlays, which page through the same actions. Omit one pair of mapping lines to keep its default paging. Because they have no default binding, these actions appear in neither the <code>?</code> help overlay nor <code>--dump-keys</code> until you bind them.</p>
<p dir="auto"><strong>Chord bindings (ctrl/alt leader):</strong> bind a two-stage chord by joining the leader and second key with <code>&gt;</code>. The leader must be a <code>ctrl+*</code> or <code>alt+*</code> combo; the second stage is any single key. Only two stages are supported.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="map ctrl+w&gt;x mark_reviewed
map alt+t&gt;n theme_select"><pre class="notranslate"><code>map ctrl+w&gt;x mark_reviewed
map alt+t&gt;n theme_select
</code></pre></div>
<p dir="auto">When the leader is pressed, the status bar shows <code>Pending: ctrl+w, esc to cancel</code>; press the second key to dispatch, or <code>esc</code> to cancel silently. Binding a key as both a standalone action and a chord prefix drops the standalone binding (the chord wins, with a warning). Chord bindings work under non-Latin keyboard layouts — the second-stage key is translated via the same layout-resolve fallback as single-key bindings. Note: chord bindings do not fire during text input (annotation and search prompts) — the leader key is consumed by the text input widget. Use single-key <code>ctrl+*</code> bindings for actions like <code>open_editor</code> that need to work during annotation input.</p>
<p dir="auto"><strong>macOS note:</strong> <code>alt+*</code> leaders require your terminal to send Option as Meta/Alt. Most terminals default to "Option composes special characters" (e.g. <code>Option+T</code> → <code>†</code>), in which case Alt chords silently won't fire. To enable: iTerm2 → <em>Profiles → Keys → Left/Right Option key → <code>Esc+</code></em>; Terminal.app → <em>Profiles → Keyboard → Use Option as Meta key</em>; Kitty → <code>macos_option_as_alt yes</code>; Ghostty → <code>macos-option-as-alt = true</code>. If you'd rather not touch terminal settings, use <code>ctrl+*</code> leaders — those work everywhere with no configuration.</p>
<details>
<summary>Available actions (click to expand)</summary>
<p dir="auto"><strong>Navigation:</strong> <code>down</code>, <code>up</code>, <code>page_down</code>, <code>page_up</code>, <code>half_page_down</code>, <code>half_page_up</code>, <code>home</code>, <code>end</code>, <code>scroll_left</code>, <code>scroll_right</code>, <code>scroll_center</code>, <code>scroll_top</code>, <code>scroll_bottom</code>, <code>scroll_diff_down</code>, <code>scroll_diff_up</code>, <code>scroll_diff_page_down</code>, <code>scroll_diff_page_up</code>, <code>scroll_diff_half_page_down</code>, <code>scroll_diff_half_page_up</code></p>
<p dir="auto"><strong>File/Hunk:</strong> <code>next_item</code>, <code>prev_item</code>, <code>jump_file</code>, <code>next_hunk</code>, <code>prev_hunk</code>, <code>open_file_in_editor</code></p>
<p dir="auto"><strong>Pane:</strong> <code>toggle_pane</code>, <code>focus_tree</code>, <code>focus_diff</code></p>
<p dir="auto"><strong>Search:</strong> <code>search</code></p>
<p dir="auto"><strong>Annotations:</strong> <code>confirm</code> (annotate line / select file), <code>annotate_file</code>, <code>delete_annotation</code>, <code>annot_list</code>, <code>open_editor</code>, <code>next_annotation</code>, <code>prev_annotation</code>, <code>flush_output</code></p>
<p dir="auto"><strong>View:</strong> <code>toggle_collapsed</code>, <code>toggle_compact</code>, <code>toggle_wrap</code>, <code>toggle_tree</code>, <code>toggle_line_numbers</code>, <code>toggle_blame</code>, <code>toggle_word_diff</code>, <code>toggle_hunk</code>, <code>toggle_untracked</code>, <code>mark_reviewed</code>, <code>filter_unreviewed</code>, <code>theme_select</code>, <code>filter</code>, <code>info</code>, <code>reload</code></p>
<p dir="auto"><strong>Quit:</strong> <code>quit</code>, <code>discard_quit</code>, <code>help</code>, <code>dismiss</code></p>
</details>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Vim-motion Preset</h3><a id="user-content-vim-motion-preset" class="anchor" aria-label="Permalink: Vim-motion Preset" href="#vim-motion-preset"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Opt-in vim-style motion layer activated via <code>--vim-motion</code>, <code>REVDIFF_VIM_MOTION=true</code>, or <code>vim-motion = true</code> in the config file. Off by default — when off, existing single-key bindings are unchanged.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Keys</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;N&gt;j</code> / <code>&lt;N&gt;k</code></td>
<td>Move cursor N lines down/up (diff pane, 1-9999)</td>
</tr>
<tr>
<td><code>gg</code></td>
<td>Jump to first line (diff pane)</td>
</tr>
<tr>
<td><code>G</code></td>
<td>Jump to last line (diff pane)</td>
</tr>
<tr>
<td><code>&lt;N&gt;G</code></td>
<td>Goto line N (diff pane)</td>
</tr>
<tr>
<td><code>H</code> / <code>&lt;N&gt;H</code></td>
<td>Cursor to top of screen / Nth line from top (diff pane)</td>
</tr>
<tr>
<td><code>M</code></td>
<td>Cursor to middle of screen (diff pane)</td>
</tr>
<tr>
<td><code>L</code> / <code>&lt;N&gt;L</code></td>
<td>Cursor to bottom of screen / Nth line from bottom (diff pane)</td>
</tr>
<tr>
<td><code>zz</code></td>
<td>Center viewport on cursor (diff pane)</td>
</tr>
<tr>
<td><code>zt</code></td>
<td>Align viewport top on cursor (diff pane)</td>
</tr>
<tr>
<td><code>zb</code></td>
<td>Align viewport bottom on cursor (diff pane)</td>
</tr>
<tr>
<td><code>ZZ</code></td>
<td>Quit (any pane)</td>
</tr>
<tr>
<td><code>ZQ</code></td>
<td>Discard annotations and quit (any pane)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">When the preset is on, the digits <code>0</code>-<code>9</code> and the leader keys <code>g</code>, <code>z</code>, <code>Z</code> are intercepted before the regular keymap, so any standalone binding on those keys is overridden while the flag is active. <code>&lt;N&gt;j</code>/<code>&lt;N&gt;k</code>/<code>&lt;N&gt;G</code>, <code>gg</code>/<code>zz</code>/<code>zt</code>/<code>zb</code>, and the screen-position motions <code>H</code>/<code>M</code>/<code>L</code> apply to the diff pane only — in the file tree they fall through to the normal bindings. <code>ZZ</code> and <code>ZQ</code> work from any pane. While the preset is active <code>L</code> is a screen-position motion rather than the line-numbers toggle (<code>toggle_line_numbers</code>); remap it in the keybindings file if you need both. Press <code>Esc</code> to silently cancel a pending leader; an unknown second key surfaces a transient <code>Unknown: &lt;chord&gt;</code> hint in the status bar. A bare digit <code>0</code> is not consumed (falls through to whatever binding is mapped); counts over 9999 are clamped. Modal keys (search input, annotation input, overlay navigation) always take precedence over the interceptor, and <code>ctrl+*</code>/<code>alt+*</code> chord bindings keep working orthogonally.</p>
<p dir="auto">The help overlay (<code>?</code>) shows a dedicated <strong>Vim motion</strong> section listing all eleven preset bindings when <code>--vim-motion</code> is on; when off, the section is hidden.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Output Format</h3><a id="user-content-output-format" class="anchor" aria-label="Permalink: Output Format" href="#output-format"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="## handler.go (file-level)
consider splitting this file into smaller modules

## handler.go:43 (+)
use errors.Is() instead of direct comparison

## handler.go:43-67 (+)
refactor this hunk to reduce nesting

## store.go:18 (-)
don't remove this validation"><pre class="notranslate"><code>## handler.go (file-level)
consider splitting this file into smaller modules

## handler.go:43 (+)
use errors.Is() instead of direct comparison

## handler.go:43-67 (+)
refactor this hunk to reduce nesting

## store.go:18 (-)
don't remove this validation
</code></pre></div>
<p dir="auto">When annotation text contains the keyword "hunk" (case-insensitive, whole word), the output header automatically expands to include the full hunk line range (e.g., <code>handler.go:43-67 (+)</code> instead of <code>handler.go:43 (+)</code>). This gives AI consumers the range context without any extra steps.</p>
<p dir="auto">Comment body lines starting with <code>## </code> (the record-header form) are prefixed with a single space on output so parsers that split on <code>## </code> record headers cannot confuse a multi-line comment for a new record.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Contributing</h2><a id="user-content-contributing" class="anchor" aria-label="Permalink: Contributing" href="#contributing"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="/umputun/revdiff/blob/master/CONTRIBUTING.md">CONTRIBUTING.md</a> for details.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MIT License - see <a href="/umputun/revdiff/blob/master/LICENSE">LICENSE</a> file for details.</p>
</article></div><div class="d-none"></div></section></div></div></div> </div> <!-- --> </div></div></div></div></div></div><div class="ScrollMarksContainer-module__scrollMarksContainer__Eu7uU" id="find-result-marks-container"></div><div class="d-none"></div><div class="d-none"></div></div> <!-- --> <!-- --> </div>
</react-app>




  </div>

</turbo-frame>

    </main>
  </div>

  </div>

          <footer class="footer f6 color-fg-muted color-border-subtle tmp-pt-7 tmp-pb-6 p-responsive" role="contentinfo"  >
  <h2 class='sr-only'>Footer</h2>

  


  <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap">
    <div class="d-flex flex-items-center flex-shrink-0 mx-2">
      <a aria-label="GitHub Homepage" class="footer-octicon mr-2" href="https://github.com">
        <svg aria-hidden="true" data-component="Octicon" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github">
    <path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
      <span>
        &copy; 2026 GitHub,&nbsp;Inc.
      </span>
    </div>

    <nav aria-label="Footer">
      <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3>

      <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading">


          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a>
          </li>


            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a>
            </li>

            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a>
            </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to community&quot;,&quot;label&quot;:&quot;text:community&quot;}" href="https://github.community/" data-view-component="true" class="Link--secondary Link">Community</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a>
          </li>

          
<li class="mx-2" >
  <cookie-consent-link>
    <button
      type="button"
      class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
      data-action="click:cookie-consent-link#showConsentManagement"
      data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
    >
      Manage cookies
    </button>
  </cookie-consent-link>
</li>

  <li class="mx-2">
    <cookie-consent-link>
      <button
        type="button"
        class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
        data-action="click:cookie-consent-link#showConsentManagement"
        data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
      >
        Do not share my personal information
      </button>
    </cookie-consent-link>
  </li>

      </ul>
    </nav>
  </div>
</footer>



    <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
      data-locale="en"
      data-initial-cookie-consent-allowed=""
      data-cookie-consent-required="true"
    ></ghcc-consent>




  <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden>
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    You can’t perform that action at this time.
  </div>

    <template id="site-details-dialog">
  <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open>
    <summary role="button" aria-label="Close dialog"></summary>
    <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
      <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
      </button>
      <div class="octocat-spinner tmp-my-6 js-details-dialog-spinner"></div>
    </details-dialog>
  </details>
</template>

    <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;">
  <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;">
  </div>
</div>

    <template id="snippet-clipboard-copy-button">
  <div class="zeroclipboard-container position-absolute right-0 top-0">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2 tmp-m-2">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2 tmp-m-2">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
  <div class="zeroclipboard-container">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>




    </div>
    <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
    <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
  </body>
</html>

