Files
2023-11-20 11:57:03 -08:00

350 lines
25 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Using API graphs in Python &#8212; CodeQL</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=93459777" />
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
<script src="../_static/doctools.js?v=888ff710"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Functions in Python" href="functions-in-python.html" />
<link rel="prev" title="Analyzing data flow in Python" href="analyzing-data-flow-in-python.html" />
<title>CodeQL docs</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<link rel="stylesheet" href="../_static/primer.css" type="text/css" />
</head><body>
<header class="Header">
<div class="Header-item--full">
<a href="https://codeql.github.com/docs" class="Header-link f2 d-flex flex-items-center">
<!-- <%= octicon "mark-github", class: "mr-2", height: 32 %> -->
<svg height="32" class="octicon octicon-mark-github mr-2" viewBox="0 0 16 16" version="1.1" width="32"
aria-hidden="true">
<path fill-rule="evenodd"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z">
</path>
</svg>
<span class="hide-sm">CodeQL documentation</span>
</a>
</div>
<div class="Header-item hide-sm hide-md">
<script src="https://addsearch.com/js/?key=93b4d287e2fc079a4089412b669785d5&categories=!0xhelp.semmle.com,0xcodeql.github.com,1xdocs,1xcodeql-standard-libraries,1xcodeql-query-help"></script>
</div>
<div class="Header-item">
<details class="dropdown details-reset details-overlay d-inline-block">
<summary class="btn bg-gray-dark text-white border" aria-haspopup="true">
CodeQL resources
<div class="dropdown-caret"></div>
</summary>
<ul class="dropdown-menu dropdown-menu-se dropdown-menu-dark">
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-overview">CodeQL overview</a></li>
<li class="dropdown-divider" role="separator"></li>
<div class="dropdown-header">
CodeQL tools
</div>
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-for-visual-studio-code">CodeQL for VS Code</a>
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-cli">CodeQL CLI</a>
</li>
<li class="dropdown-divider" role="separator"></li>
<div class="dropdown-header">
CodeQL guides
</div>
<li><a class="dropdown-item" href="https://codeql.github.com/docs/writing-codeql-queries">Writing CodeQL queries</a></li>
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-language-guides">CodeQL language guides</a>
<li class="dropdown-divider" role="separator"></li>
<div class="dropdown-header">
Reference docs
</div>
<li><a class="dropdown-item" href="https://codeql.github.com/docs/ql-language-reference/">QL language
reference</a>
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-standard-libraries">CodeQL
standard-libraries</a>
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-query-help">CodeQL
query help</a>
<li class="dropdown-divider" role="separator"></li>
<div class="dropdown-header">
Source files
</div>
<li><a class="dropdown-item" href="https://github.com/github/codeql">CodeQL repository</a>
</ul>
</details>
</div>
</header>
<main class="bg-gray-light clearfix">
<nav class="SideNav position-sticky top-0 col-lg-3 col-md-3 float-left p-4 hide-sm hide-md overflow-y-auto">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../codeql-overview/index.html">CodeQL overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../codeql-for-visual-studio-code/index.html">CodeQL for Visual Studio Code</a></li>
<li class="toctree-l1"><a class="reference internal" href="../codeql-cli/index.html">CodeQL CLI</a></li>
<li class="toctree-l1"><a class="reference internal" href="../writing-codeql-queries/index.html">Writing CodeQL queries</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">CodeQL language guides</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="codeql-for-cpp.html">CodeQL for C and C++</a></li>
<li class="toctree-l2"><a class="reference internal" href="codeql-for-csharp.html">CodeQL for C#</a></li>
<li class="toctree-l2"><a class="reference internal" href="codeql-for-go.html">CodeQL for Go</a></li>
<li class="toctree-l2"><a class="reference internal" href="codeql-for-java.html">CodeQL for Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="codeql-for-javascript.html">CodeQL for JavaScript</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="codeql-for-python.html">CodeQL for Python</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="basic-query-for-python-code.html">Basic query for Python code</a></li>
<li class="toctree-l3"><a class="reference internal" href="codeql-library-for-python.html">CodeQL library for Python</a></li>
<li class="toctree-l3"><a class="reference internal" href="analyzing-data-flow-in-python.html">Analyzing data flow in Python</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Using API graphs in Python</a></li>
<li class="toctree-l3"><a class="reference internal" href="functions-in-python.html">Functions in Python</a></li>
<li class="toctree-l3"><a class="reference internal" href="expressions-and-statements-in-python.html">Expressions and statements in Python</a></li>
<li class="toctree-l3"><a class="reference internal" href="analyzing-control-flow-in-python.html">Analyzing control flow in Python</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="codeql-for-ruby.html">CodeQL for Ruby</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../ql-language-reference/index.html">QL language reference</a></li>
</ul>
</nav>
<div class="body col-sm-12 col-md-9 col-lg-9 float-left border-left">
<div class="hide-lg hide-xl px-4 pt-4">
<div class="related" role="navigation" aria-label="related navigation">
<ul>
<li class="nav-item nav-item-0"><a href="../contents.html">CodeQL</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="index.html"
>CodeQL language guides</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="codeql-for-python.html"
accesskey="U">CodeQL for Python</a> &#187;</li>
</ul>
</div>
</div>
<article class="p-4 col-lg-10 col-md-10 col-sm-12">
<section id="using-api-graphs-in-python">
<span id="id1"></span><h1>Using API graphs in Python<a class="headerlink" href="#using-api-graphs-in-python" title="Link to this heading"></a></h1>
<p>API graphs are a uniform interface for referring to functions, classes, and methods defined in
external libraries.</p>
<section id="about-this-article">
<h2>About this article<a class="headerlink" href="#about-this-article" title="Link to this heading"></a></h2>
<p>This article describes how to use API graphs to reference classes and functions defined in library
code. You can use API graphs to conveniently refer to external library functions when defining things like
remote flow sources.</p>
</section>
<section id="module-imports">
<h2>Module imports<a class="headerlink" href="#module-imports" title="Link to this heading"></a></h2>
<p>The most common entry point into the API graph will be the point where an external module or package is
imported. For example, you can access the API graph node corresponding to the <code class="docutils literal notranslate"><span class="pre">re</span></code> library
by using the <code class="docutils literal notranslate"><span class="pre">API::moduleImport</span></code> method defined in the <code class="docutils literal notranslate"><span class="pre">semmle.python.ApiGraphs</span></code> module, as the
following snippet demonstrates.</p>
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
import semmle.python.ApiGraphs
select API::moduleImport(&quot;re&quot;)
</pre></div>
</div>
<p><a class="reference external" href="https://lgtm.com/query/1876172022264324639/">See this in the query console on LGTM.com</a>.</p>
<p>This query selects the API graph node corresponding to the <code class="docutils literal notranslate"><span class="pre">re</span></code> module. This node represents the fact that the <code class="docutils literal notranslate"><span class="pre">re</span></code> module has been imported rather than a specific location in the program where the import happens. Therefore, there will be at most one result per project, and it will not have a useful location, so youll have to click <cite>Show 1 non-source result</cite> in order to see it.</p>
<p>To find where the <code class="docutils literal notranslate"><span class="pre">re</span></code> module is referenced in the program, you can use the <code class="docutils literal notranslate"><span class="pre">getAUse</span></code> method. The following query selects all references to the <code class="docutils literal notranslate"><span class="pre">re</span></code> module in the current database.</p>
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
import semmle.python.ApiGraphs
select API::moduleImport(&quot;re&quot;).getAUse()
</pre></div>
</div>
<p><a class="reference external" href="https://lgtm.com/query/8072356519514905526/">See this in the query console on LGTM.com</a>.</p>
<p>Note that the <code class="docutils literal notranslate"><span class="pre">getAUse</span></code> method accounts for local flow, so that <code class="docutils literal notranslate"><span class="pre">my_re_compile</span></code>
in the following snippet is
correctly recognized as a reference to the <code class="docutils literal notranslate"><span class="pre">re.compile</span></code> function.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">re</span> <span class="kn">import</span> <span class="nb">compile</span> <span class="k">as</span> <span class="n">re_compile</span>
<span class="n">my_re_compile</span> <span class="o">=</span> <span class="n">re_compile</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">my_re_compile</span><span class="p">(</span><span class="s2">&quot;.*&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>If you only require immediate uses, without taking local flow into account, then you can use
the <code class="docutils literal notranslate"><span class="pre">getAnImmediateUse</span></code> method instead.</p>
<p>Note that the given module name <em>must not</em> contain any dots. Thus, something like
<code class="docutils literal notranslate"><span class="pre">API::moduleImport(&quot;flask.views&quot;)</span></code> will not do what you expect. Instead, this should be decomposed
into an access of the <code class="docutils literal notranslate"><span class="pre">views</span></code> member of the API graph node for <code class="docutils literal notranslate"><span class="pre">flask</span></code>, as described in the next
section.</p>
</section>
<section id="accessing-attributes">
<h2>Accessing attributes<a class="headerlink" href="#accessing-attributes" title="Link to this heading"></a></h2>
<p>Given a node in the API graph, you can access its attributes by using the <code class="docutils literal notranslate"><span class="pre">getMember</span></code> method. Using
the above <code class="docutils literal notranslate"><span class="pre">re.compile</span></code> example, you can now find references to <code class="docutils literal notranslate"><span class="pre">re.compile</span></code>.</p>
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
import semmle.python.ApiGraphs
select API::moduleImport(&quot;re&quot;).getMember(&quot;compile&quot;).getAUse()
</pre></div>
</div>
<p><a class="reference external" href="https://lgtm.com/query/7970570434725297676/">See this in the query console on LGTM.com</a>.</p>
<p>In addition to <code class="docutils literal notranslate"><span class="pre">getMember</span></code>, you can use the <code class="docutils literal notranslate"><span class="pre">getUnknownMember</span></code> method to find references to API
components where the name is not known statically. You can use the <code class="docutils literal notranslate"><span class="pre">getAMember</span></code> method to
access all members, both known and unknown.</p>
</section>
<section id="calls-and-class-instantiations">
<h2>Calls and class instantiations<a class="headerlink" href="#calls-and-class-instantiations" title="Link to this heading"></a></h2>
<p>To track instances of classes defined in external libraries, or the results of calling externally
defined functions, you can use the <code class="docutils literal notranslate"><span class="pre">getReturn</span></code> method. The following snippet finds all places
where the return value of <code class="docutils literal notranslate"><span class="pre">re.compile</span></code> is used:</p>
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
import semmle.python.ApiGraphs
select API::moduleImport(&quot;re&quot;).getMember(&quot;compile&quot;).getReturn().getAUse()
</pre></div>
</div>
<p><a class="reference external" href="https://lgtm.com/query/4346050399960356921/">See this in the query console on LGTM.com</a>.</p>
<p>Note that this includes all uses of the result of <code class="docutils literal notranslate"><span class="pre">re.compile</span></code>, including those reachable via
local flow. To get just the <em>calls</em> to <code class="docutils literal notranslate"><span class="pre">re.compile</span></code>, you can use <code class="docutils literal notranslate"><span class="pre">getAnImmediateUse</span></code> instead of
<code class="docutils literal notranslate"><span class="pre">getAUse</span></code>. As this is a common occurrence, you can use <code class="docutils literal notranslate"><span class="pre">getACall</span></code> instead of
<code class="docutils literal notranslate"><span class="pre">getReturn</span></code> followed by <code class="docutils literal notranslate"><span class="pre">getAnImmediateUse</span></code>.</p>
<p><a class="reference external" href="https://lgtm.com/query/8143347716552092926/">See this in the query console on LGTM.com</a>.</p>
<p>Note that the API graph does not distinguish between class instantiations and function calls. As far
as its concerned, both are simply places where an API graph node is called.</p>
</section>
<section id="subclasses">
<h2>Subclasses<a class="headerlink" href="#subclasses" title="Link to this heading"></a></h2>
<p>For many libraries, the main mode of usage is to extend one or more library classes. To track this
in the API graph, you can use the <code class="docutils literal notranslate"><span class="pre">getASubclass</span></code> method to get the API graph node corresponding to
all the immediate subclasses of this node. To find <em>all</em> subclasses, use <code class="docutils literal notranslate"><span class="pre">*</span></code> or <code class="docutils literal notranslate"><span class="pre">+</span></code> to apply the
method repeatedly, as in <code class="docutils literal notranslate"><span class="pre">getASubclass*</span></code>.</p>
<p>Note that <code class="docutils literal notranslate"><span class="pre">getASubclass</span></code> does not account for any subclassing that takes place in library code
that has not been extracted. Thus, it may be necessary to account for this in the models you write.
For example, the <code class="docutils literal notranslate"><span class="pre">flask.views.View</span></code> class has a predefined subclass <code class="docutils literal notranslate"><span class="pre">MethodView</span></code>. To find
all subclasses of <code class="docutils literal notranslate"><span class="pre">View</span></code>, you must explicitly include the subclasses of <code class="docutils literal notranslate"><span class="pre">MethodView</span></code> as well.</p>
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
import semmle.python.ApiGraphs
API::Node viewClass() {
result =
API::moduleImport(&quot;flask&quot;).getMember(&quot;views&quot;).getMember([&quot;View&quot;, &quot;MethodView&quot;]).getASubclass*()
}
select viewClass().getAUse()
</pre></div>
</div>
<p><a class="reference external" href="https://lgtm.com/query/288293322319747121/">See this in the query console on LGTM.com</a>.</p>
<p>Note the use of the set literal <code class="docutils literal notranslate"><span class="pre">[&quot;View&quot;,</span> <span class="pre">&quot;MethodView&quot;]</span></code> to match both classes simultaneously.</p>
</section>
<section id="built-in-functions-and-classes">
<h2>Built-in functions and classes<a class="headerlink" href="#built-in-functions-and-classes" title="Link to this heading"></a></h2>
<p>You can access built-in functions and classes using the <code class="docutils literal notranslate"><span class="pre">API::builtin</span></code> method, giving the name of
the built-in as an argument.</p>
<p>For example, to find all calls to the built-in <code class="docutils literal notranslate"><span class="pre">open</span></code> function, you can use the following snippet.</p>
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
import semmle.python.ApiGraphs
select API::builtin(&quot;open&quot;).getACall()
</pre></div>
</div>
</section>
<section id="further-reading">
<h2>Further reading<a class="headerlink" href="#further-reading" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/python/ql/src">CodeQL queries for Python</a></p></li>
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/python/ql/examples">Example queries for Python</a></p></li>
<li><p><a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/">CodeQL library reference for Python</a></p></li>
</ul>
<ul class="simple">
<li><p><a class="reference internal" href="../ql-language-reference/index.html#ql-language-reference"><span class="std std-ref">QL language reference</span></a></p></li>
<li><p><a class="reference internal" href="../codeql-overview/codeql-tools.html#codeql-tools"><span class="std std-ref">CodeQL tools</span></a></p></li>
</ul>
</section>
</section>
</article>
<!-- GitHub footer, with links to terms and privacy statement -->
<div class="px-3 px-md-6 f6 py-4 d-sm-flex flex-justify-between flex-row-reverse flex-items-center border-top">
<ul class="list-style-none d-flex flex-items-center mb-3 mb-sm-0 lh-condensed-ultra">
<li class="mr-3">
<a href="https://twitter.com/github" title="GitHub on Twitter" style="color: #959da5;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 273.5 222.3" class="d-block" height="18">
<path
d="M273.5 26.3a109.77 109.77 0 0 1-32.2 8.8 56.07 56.07 0 0 0 24.7-31 113.39 113.39 0 0 1-35.7 13.6 56.1 56.1 0 0 0-97 38.4 54 54 0 0 0 1.5 12.8A159.68 159.68 0 0 1 19.1 10.3a56.12 56.12 0 0 0 17.4 74.9 56.06 56.06 0 0 1-25.4-7v.7a56.11 56.11 0 0 0 45 55 55.65 55.65 0 0 1-14.8 2 62.39 62.39 0 0 1-10.6-1 56.24 56.24 0 0 0 52.4 39 112.87 112.87 0 0 1-69.7 24 119 119 0 0 1-13.4-.8 158.83 158.83 0 0 0 86 25.2c103.2 0 159.6-85.5 159.6-159.6 0-2.4-.1-4.9-.2-7.3a114.25 114.25 0 0 0 28.1-29.1"
fill="currentColor"></path>
</svg>
</a>
</li>
<li class="mr-3">
<a href="https://www.facebook.com/GitHub" title="GitHub on Facebook" style="color: #959da5;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.3 15.4" class="d-block" height="18">
<path
d="M14.5 0H.8a.88.88 0 0 0-.8.9v13.6a.88.88 0 0 0 .8.9h7.3v-6h-2V7.1h2V5.4a2.87 2.87 0 0 1 2.5-3.1h.5a10.87 10.87 0 0 1 1.8.1v2.1h-1.3c-1 0-1.1.5-1.1 1.1v1.5h2.3l-.3 2.3h-2v5.9h3.9a.88.88 0 0 0 .9-.8V.8a.86.86 0 0 0-.8-.8z"
fill="currentColor"></path>
</svg>
</a>
</li>
<li class="mr-3">
<a href="https://www.youtube.com/github" title="GitHub on YouTube" style="color: #959da5;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.17 13.6" class="d-block" height="16">
<path
d="M18.77 2.13A2.4 2.4 0 0 0 17.09.42C15.59 0 9.58 0 9.58 0a57.55 57.55 0 0 0-7.5.4A2.49 2.49 0 0 0 .39 2.13 26.27 26.27 0 0 0 0 6.8a26.15 26.15 0 0 0 .39 4.67 2.43 2.43 0 0 0 1.69 1.71c1.52.42 7.5.42 7.5.42a57.69 57.69 0 0 0 7.51-.4 2.4 2.4 0 0 0 1.68-1.71 25.63 25.63 0 0 0 .4-4.67 24 24 0 0 0-.4-4.69zM7.67 9.71V3.89l5 2.91z"
fill="currentColor"></path>
</svg>
</a>
</li>
<li class="mr-3 flex-self-start">
<a href="https://www.linkedin.com/company/github" title="GitHub on Linkedin" style="color: #959da5;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" class="d-block" height="18">
<path
d="M3.94 2A2 2 0 1 1 2 0a2 2 0 0 1 1.94 2zM4 5.48H0V18h4zm6.32 0H6.34V18h3.94v-6.57c0-3.66 4.77-4 4.77 0V18H19v-7.93c0-6.17-7.06-5.94-8.72-2.91z"
fill="currentColor"></path>
</svg>
</a>
</li>
<li>
<a href="https://github.com/github" title="GitHub's organization" style="color: #959da5;">
<svg version="1.1" width="20" height="20" viewBox="0 0 16 16" class="octicon octicon-mark-github"
aria-hidden="true">
<path fill-rule="evenodd"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z">
</path>
</svg>
</a>
</li>
</ul>
<ul class="list-style-none d-flex text-gray">
<li class="mr-3">&copy;
<script type="text/javascript">document.write(new Date().getFullYear());</script> GitHub, Inc.</li>
<li class="mr-3"><a
href="https://docs.github.com/github/site-policy/github-terms-of-service"
class="link-gray">Terms </a></li>
<li><a href="https://docs.github.com/github/site-policy/github-privacy-statement"
class="link-gray">Privacy </a></li>
</ul>
</div>
</div>
</main>
<script type="text/javascript">
$(document).ready(function () {
$(".toggle > *").hide();
$(".toggle .name").show();
$(".toggle .name").click(function () {
$(this).parent().children().not(".name").toggle(400);
$(this).parent().children(".name").toggleClass("open");
})
});
</script>
</body>
</html>