PageSourceSearch

https://www.erlang.org/

html erlang.org collected 2026-09-24 08:26:25 UTC 27,063 bytes, 577 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en" class="h-100">
3
4
5
6<head>
7    <meta charset="utf-8">
8    <meta http-equiv="X-UA-Compatible" content="IE=edge">
9
10    <!-- Allow pinning of website on windows -->
11    <meta name="application-name" content="Erlang.org">
12    <meta name="msapplication-tooltip" content="The official home of the Erlang Programming Language">
13    <meta name="msapplication-starturl" content="/" >
14
15    <!-- Make the site look nicer on facebook -->
16    <meta property="og:type" content="website">
17    <meta property="og:site_name" content="Erlang.org">
18    <meta property="og:title" content="Index - Erlang/OTP">
19    <meta property="og:description" content="The official home of the Erlang Programming Language">
20    <meta property="og:image" content="https://www.erlang.org/assets/img/erlang-228x200.png">
21    <meta property="og:image:secure_url" content="https://www.erlang.org/assets/img/erlang-228x200.png">
22    <meta property="og:url" content="https://www.erlang.org/">
23
24    <!-- Rich data for google search -->
25    
25<script type="application/ld+json">
26{"@type":"WebSite","url":"https://erlang.org/","headline":"Index - Erlang/OTP","name":"Erlang.org","sameAs":["https://github.com/erlang/otp"],"@context":"https://schema.org"}</script>
26
27
28    <title>Index - Erlang/OTP</title>
29
30    
31    
31<script>
32      (function() {
33        try {
34          var s = JSON.parse(localStorage.getItem("ex_doc:settings") || "{}");
35          var t = s.theme;
36          var dark = t === "dark" || (t !== "light" && window.matchMedia &&
37            window.matchMedia("(prefers-color-scheme: dark)").matches);
38          if (dark) {
39            document.documentElement.classList.add("dark");
40            document.documentElement.setAttribute("data-bs-theme", "dark");
41          }
42        } catch (e) { /* localStorage may be unavailable; just skip */ }
43      })();
44    </script>
44
45
46    <meta name="viewport" content="width=device-width, initial-scale=1">
47    <!-- tells iOS browsers to not show telephone numbers as links -->
48    <meta name="format-detection" content="telephone=no">
49
50    <meta name="application-name" content="Erlang.org">
51    <meta name="description" content="The official home of the Erlang Programming Language">
52    <!-- https://www.rssboard.org/rss-autodiscovery -->
53    <link rel="alternate" type="application/atom+xml" title="News Atom Feed" href="https://www.erlang.org/news.xml" />
54    <link rel="alternate" type="application/atom+xml" title="Blog Atom Feed" href="https://www.erlang.org/blog.xml" />
55    <link rel="icon" href="/favicon.ico" />
56    
57    <link rel="stylesheet" href="/assets/css/index.css">
58</head>
59
60<body class="d-flex flex-column h-100">
61    <header class="navbar navbar-expand-lg navbar-light bg-body">
62        <nav class="container">
63            <button class="navbar-toggler" type="button" data-toggle="collapse" data-bs-toggle="collapse"
64                data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
65                aria-label="Toggle navigation">
66                <span class="navbar-toggler-icon"></span>
67            </button>
68            <a class="navbar-brand" href="/"><img
69                    src="/assets/img/erlang-logo.svg" width="60" alt="Erlang.org main page"/></a>
70            <div class="collapse navbar-collapse fw-bold" id="navbarSupportedContent">
71                <ul class="navbar-nav text-uppercase me-auto mb-2 mb-lg-0">
72                    <li class="nav-item"><a class="nav-link" href="/downloads">Download</a></li>
73                    <li class="nav-item"><a class="nav-link" href="/docs">Documentation</a></li>
74                    <li class="nav-item"><a class="nav-link" href="/community">Community</a></li>
75                    <li class="nav-item"><a class="nav-link" href="/news">News</a></li>
76                    <li class="nav-item"><a class="nav-link" href="/blog">Blog</a></li>
77                    <li class="nav-item"><a class="nav-link" href="/security">Security</a></li>
78                    <li class="nav-item"><a class="nav-link" href="/eep">EEP</a></li>
79                    <li class="nav-item"><a class="nav-link" href="/about">About</a></li>
80                </ul>
81                <form class="d-flex" role="search" method="get" action="https://duckduckgo.com/">
82                    <input type="hidden" name="sites" value="erlang.org">
83                    <input class="form-control me-2" id="searchfield" name="q" type="search" placeholder="Search erlang.org"
84                        aria-label="Search">
85                    <button class="btn btn-outline-primary" type="submit">Search</button>
86                </form>
87            </div>
88        </nav>
89    </header>
90    <div class="flex-shrink-0 border-top-dark">
91        <div class="bg-erlang-grey">
92    <div class="container banner px-0 px-md-2">
93        <div class="slogan text-center">
94            <h1 class="h4 px-4 pt-4 text-light">
95                Practical functional programming<br /> for a parallel world
96            </h1>
97            <!-- <h4 class="px-4 pt-4 text-light">
98                        Build massively scalable soft real-time systems
99                    </h4> -->
100        </div>
101        <div class="download text-center">
102            <!-- We hide the download button on small screens as most likely it is a mobile
103                 and no one want to workload Erlang on a mobile -->
104            <div class="btn-group">
105                
106                <a href="/downloads"
107                    class="btn btn-success d-inline-flex align-items-center gap-1">
108                    Get Erlang/OTP 29
109                    <svg width="20" height="20" >
110    
111    <use xlink:href="#download"></use>
112</svg>
113
114                </a>
115            </div>
116        </div>
117        <!-- We have two different examples that are shown
118             depending on the size of the viewport -->
119        <div class="example">
120            
121            
122            <div class="large">
123                <div id="large-example-carousel" class="h-100 carousel slide" data-bs-ride="carousel">
124                    <div class="carousel-inner h-100">
125                        
126                        
127                        
128                        <div class="h-100 carousel-item active" data-bs-interval="10000">
129                            <div class="h-100 d-flex flex-column">
130                                <div class="flex-grow-1 mx-auto">
131                                    <!-- This file has to be 15 lines long -->
132<pre><code class="language-erlang">fact(0) -&gt; 1;              %% Pattern matching for control-flow
133fact(N) -&gt; N * fact(N-1).  %% Recursion to create loops
134
135&gt; example:fact(10).        %% Interactive shell for fast iterations
1363628800
137&gt; [{I, example:fact(I)} || I &lt;- lists:seq(1,10)].
138[{1, 1}, {2, 2}, {3, 6}, {4, 24}, {5, 120}, {6, 720},
139 {7, 5040}, {8, 40320}, {9, 362880}, {10, 3628800}]
140</code></pre>
141
142                                </div>
143                                <div class="text-light text-center">
144                                    <p>Functional programming</p>
145                                </div>
146                            </div>
147                        </div>
148                        
149                        
150                        
151                        
152                        
153                        
154                        <div class="h-100 carousel-item " data-bs-interval="10000">
155                            <div class="h-100 d-flex flex-column">
156                                <div class="flex-grow-1 mx-auto">
157                                    <!-- This file has to be 15 lines long -->
158<pre><code class="language-erlang">&gt; Fruits = ["banana","monkey","jungle"].     %% Immutable variables
159["banana","monkey","jungle"]
160&gt; lists:map(fun string:uppercase/1, Fruits). %% Map values using stdlib functions
161["BANANA","MONKEY","JUNGLE"]
162%% Fold over lists using custom functions
163&gt; lists:foldl(fun(Str, Cnt) -&gt; string:length(Str) + Cnt end, 0, Fruits).
16418
165
166</code></pre>
167
168                                </div>
169                                <div class="text-light text-center">
170                                    <p>Higher-order functions</p>
171                                </div>
172                            </div>
173                        </div>
174                        
175                        
176                        
177                        
178                        
179                        
180                        <div class="h-100 carousel-item " data-bs-interval="10000">
181                            <div class="h-100 d-flex flex-column">
182                                <div class="flex-grow-1 mx-auto">
183                                    <!-- This file has to be 15 lines long -->
184<pre><code class="language-erlang">&gt; Parent = self().                         %% Get own process id
185&lt;0.376.0&gt;
186&gt; Child = spawn(fun() -&gt; receive go -&gt; Parent ! lists:seq(1,100) end end).
187&lt;0.930.0&gt;
188&gt; Child ! go.                              %% Send message to child
189go
190&gt; receive Reply -&gt; Reply end.              %% Receive response from child
191[1,2,3,4,5,6,7,8,9,10,11|...]
192</code></pre>
193
194                                </div>
195                                <div class="text-light text-center">
196                                    <p>Lightweight processes</p>
197                                </div>
198                            </div>
199                        </div>
200                        
201                        
202                        
203                        
204                        
205                        
206                        
207                        
208                        <div class="h-100 carousel-item " data-bs-interval="10000">
209                            <div class="h-100 d-flex flex-column">
210                                <div class="flex-grow-1 mx-auto">
211                                    <!-- This file has to be 15 lines long -->
212<pre><code class="language-erlang">-spec even(list(integer())) -&gt; list(integer()).
213even(Numbers) -&gt;
214  mapreduce(Numbers, fun(Number) -&gt; Number rem 2 == 0 end).
215mapreduce(Numbers, Function) -&gt;
216  Parent = self(),
217  [spawn(fun() -&gt; Parent ! {Number, Function(Number)} end) || Number &lt;- Numbers],
218  lists:flatten(
219    [receive {Number, true} -&gt; Number; _ -&gt; [] end || Number &lt;- Numbers]).
220</code></pre>
221
222                                </div>
223                                <div class="text-light text-center">
224                                    <p>Parallel map-reduce to find even numbers</p>
225                                </div>
226                            </div>
227                        </div>
228                        
229                        
230                        
231                    </div>
232                    <button class="carousel-control-prev" type="button" data-bs-target="#large-example-carou
232sel"
233                        data-bs-slide="prev">
234                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
235                        <span class="visually-hidden">Previous</span>
236                    </button>
237                    <button class="carousel-control-next" type="button" data-bs-target="#large-example-carousel"
238                        data-bs-slide="next">
239                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
240                        <span class="visually-hidden">Next</span>
241                    </button>
242                </div>
243            </div>
244            
245            <div class="small">
246                <div id="small-example-carousel" class="h-100 carousel slide" data-bs-ride="carousel">
247                    <div class="carousel-inner h-100">
248                        
249                        
250                        
251                        
252                        
253                        <div class="h-100 carousel-item active" data-bs-interval="10000">
254                            <div class="h-100 d-flex flex-column">
255                                <div class="flex-grow-1 mx-auto">
256                                    <!-- This file has to be 13 lines long -->
257<pre><code class="language-erlang">%% Return factorial for N
258fact(0) -&gt; 1;
259fact(N) -&gt; N * fact(N-1).
260
261&gt; example:fact(10).
2623628800
263</code></pre>
264
265                                </div>
266                                <div class="text-light text-center">
267                                    <p>Functional programming</p>
268                                </div>
269                            </div>
270                        </div>
271                        
272                        
273                        
274                        
275                        
276                        
277                        <div class="h-100 carousel-item " data-bs-interval="10000">
278                            <div class="h-100 d-flex flex-column">
279                                <div class="flex-grow-1 mx-auto">
280                                    <!-- This file has to be 13 lines long -->
281<pre><code class="language-erlang">&gt; Fruits = ["banana","monkey"].
282["banana","monkey"]
283&gt; lists:map(
284    fun string:uppercase/1,
285    Fruits).
286["BANANA","MONKEY"]
287</code></pre>
288
289                                </div>
290                                <div class="text-light text-center">
291                                    <p>Higher-order functions</p>
292                                </div>
293                            </div>
294                        </div>
295                        
296                        
297                        
298                        
299                        
300                        
301                        <div class="h-100 carousel-item " data-bs-interval="10000">
302                            <div class="h-100 d-flex flex-column">
303                                <div class="flex-grow-1 mx-auto">
304                                    <!-- This file has to be 13 lines long -->
305<pre><code class="language-erlang">&gt; Me = self().
306&lt;0.376.0&gt;        %% Send msg using !
307&gt; spawn(fun() -&gt; Me!lists:seq(1,10) end).
308&lt;0.930.0&gt;
309&gt; receive Reply -&gt; Reply end.
310[1,2,3,4,5,6,7,8,9,10]
311</code></pre>
312
313                                </div>
314                                <div class="text-light text-center">
315                                    <p>Light-weight processes</p>
316                                </div>
317                            </div>
318                        </div>
319                        
320                        
321                        
322                        
323                        <div class="h-100 carousel-item " data-bs-interval="10000">
324                            <div class="h-100 d-flex flex-column">
325                                <div class="flex-grow-1 mx-auto">
326                                    <pre><code class="language-erlang">-spec even(In) -&gt; Out
327  when In :: list(integer()),
328       Out :: list(integer()).
329even(Numbers) -&gt;
330  [Number || Number &lt;- Numbers,
331   Number rem 2 == 0].
332</code></pre>
333
334                                </div>
335                                <div class="text-light text-center">
336                                    <p>Find even numbers</p>
337                                </div>
338                            </div>
339                        </div>
340                        
341                        
342                        
343                        
344                        
345                    </div>
346                    <button class="carousel-control-prev" type="button" data-bs-target="#small-example-carou
346sel"
347                        data-bs-slide="prev">
348                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
349                        <span class="visually-hidden">Previous</span>
350                    </button>
351                    <button class="carousel-control-next" type="button" data-bs-target="#small-example-carousel"
352                        data-bs-slide="next">
353                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
354                        <span class="visually-hidden">Next</span>
355                    </button>
356                </div>
357            </div>
358            
359
360        </div>
361    </div>
362</div>
363<main class="content container">
364    <div class="what-is-erlang">
365        <h2 class="h4">What is Erlang?</h2>
366        <p class="ps-3">Erlang is a programming language used to build massively scalable soft real-time
367            systems with requirements on high availability. Some of its uses are in telecoms, banking,
368            e-commerce, computer telep
368hony and instant messaging. Erlang's runtime system has built-in
369            support for concurrency, distribution and fault tolerance.</p>
370        <a href="/doc/getting_started/intro.html" role="button"
371            class="btn btn-primary float-end d-inline-flex align-items-center">
372            Erlang Quickstart
373            <svg width="24" height="24" >
374    
375    <use xlink:href="#arrow-right"></use>
376</svg>
377
378        </a>
379    </div>
380    <div class="what-is-otp">
381        <h2 class="h4">What is OTP?</h2>
382        <p class="ps-3">OTP is set of Erlang libraries and design principles providing middle-ware to
383            develop these systems. It includes its own distributed database, applications to interface
384            towards other languages, debugging and release handling tools.</p>
385        <a href="/doc/design_principles/des_princ.html" role="button"
386            class="btn btn-primary float-end d-inline-flex align-items-center">
387            Getting Started with OTP
388            <svg width="24" height="24" >
389    
390    <use xlink:href="#arrow-right"></use>
391</svg>
392
393        </a>
394    </div>
395    <div class="news">
396        <h2 class="h4">News</h2>
397        <dl class="ps-3">
398            
399            
400            
401            
402            
403            <dt>
404                <h3 class="h5"><a href="/news/191">Erlang/OTP 29.1 Release</a></h3>
405                <small class="ps-2">September 16, 2026 by Henrik Nord</small>
406            </dt>
407            <dd class="px-3 py-1">
408                Erlang/OTP 29.1 is the first maintenance patch package for OTP 29, with mostly bug fixes.
409            </dd>
410            
411            
412            
413            
414            <dt>
415                <h3 class="h5"><a href="/news/190">Björn on BEAM on the BEAM There, Done That Podcast</a></h3>
416                <small class="ps-2">June 26, 2026 by Björn Gustavsson</small>
417            </dt>
418            <dd class="px-3 py-1">
419                Björn on BEAM on the BEAM There, Done That Podcast
420            </dd>
421            
422            
423            
424            
425            <dt>
426                <h3 class="h5"><a href="/news/189">Native Records on the Podcast BEAM There, Done That</a></h3>
427                <small class="ps-2">May 28, 2026 by Björn Gustavsson</small>
428            </dt>
429            <dd class="px-3 py-1">
430                Native Records on the Podcast BEAM There, Done That
431            </dd>
432            
433        </dl>
434    </div>
435    <div class="participate">
436        <h2 class="h4">Participate</h2>
437        <p class="ps-3">
438            <a href="https://erlef.org"><img alt="Join the Erlang Ecosystem Foundation"
439                    src="/assets/img/eef.png" class="eef-logo" width="174"></a>
440        </p>
441    </div>
442</main>
443<script src="/assets/js/prismjs/prism.js"></script>
vendor: 1 bytes, line 443
443
444<script src="/assets/js/prismjs/components/prism-erlang.js"></script>
444
445
446    </div>
447    <footer class="container-fluid footer mt-auto text-center border-top border-bottom">
448        <div>
449            <a href="/downloads.html" title="DOWNLOAD">
450                <svg width="36" height="24" role="img">
451    
452        <title>Download Erlang/OTP</title>
453    
454    <use xlink:href="#download-cloud"></use>
455</svg>
456
457            </a>
458        </div>
459        <div>
460            <a href="http://www.github.com/erlang/otp">
461                <svg width="32" height="32" role="img">
462    
463        <title>Erlang/OTP on Github</title>
464    
465    <use xlink:href="#github"></use>
466</svg>
467
468            </a>
469        </div>
470        
471        <div>
472            <button type="button" id="theme-toggle" class="theme-toggle"
473                    aria-label="Toggle theme" title="Toggle theme (light / dark / system)">
474                <svg width="20" height="20"  class="icon-theme-light">
475    
476    <use xlink:href="#theme-light"></use>
477</svg>
478
479                <svg width="20" height="20"  class="icon-theme-dark">
480    
481    <use xlink:href="#theme-dark"></use>
482</svg>
483
484                <svg width="20" height="20"  class="icon-theme-system">
485    
486    <use xlink:href="#theme-system"></use>
487</svg>
488
489            </button>
490        </div>
491    </footer>
492    <!-- SVG icons -->
493    <svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
494        <symbol id="download-cloud" viewBox="0 0 36 24">
495            <path fill="currentColor" d="M30.096 10.54S30.76 1.59 22.56.568c-7.03-.718-9.168 5.814-9.168 5.814s-2.117-2.035-4.99-.372c-2.57 1.587-2.116 4.492-2.116 4.492s-5.709 1.11-5.709 6.93c.128 5.812 6.2 5.87 6.2 5.87h11.621l-5.12-5.119h3.072V12.04h4.096v6.143h3.071l-5.119 5.12h10.716s5.652.005 6.446-5.524c.377-6.047-5.464-7.239-5.464-7.239Z"/>
496        </symbol>
497        <symbol id="download" viewBox="0 0 20 20">
498            <path fill="currentColor" d="M10.75 2.75a.75.75 0 0 0-1.5 0v8.614L6.295 8.235a.75.75 0 1 0-1.09 1.03l4.25 4.5a.75.75 0 0 0 1.09 0l4.25-4.5a.75.75 0 0 0-1.09-1.03l-2.955 3.129V2.75Z" />
499            <path fill="currentColor" d="M3.5 12.75a.75.75 0 0 0-1.5 0v2.5A2.75 2.75 0 0 0 4.75 18h10.5A2.75 2.75 0 0 0 18 15.25v-2.5a.75.75 0 0 0-1.5 0v2.5c0 .69-.56 1.25-1.25 1.25H4.75c-.69 0-1.25-.56-1.25-1.25v-2.5Z" />
500        </symbol>
501        <symbol id="arrow-right" viewBox="0 0 20 20">
502            <path fill="currentColor" fill-rule="evenodd" d="M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
503        </symbol>
504        <symbol id="theme-light" viewBox="0 0 24 24">
505            <path fill="currentColor" d="M12 17a5 5 0 1 1 0-10 5 5 0 0 1 0 10Zm0-2a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM12 2a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1Zm0 17a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1ZM2 12a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm17 0a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1ZM4.93 4.93a1 1 0 0 1 1.41 0l1.42 1.42A1 1 0 1 1 6.34 7.76L4.93 6.34a1 1 0 0 1 0-1.41Zm11.31 11.31a1 1 0 0 1 1.41 0l1.42 1.42a1 1 0 0 1-1.41 1.41l-1.42-1.42a1 1 0 0 1 0-1.41ZM19.07 4.93a1 1 0 0 1 0 1.41l-1.42 1.42a1 1 0 0 1-1.41-1.41l1.42-1.42a1 1 0 0 1 1.41 0ZM7.76 16.24a1 1 0 0 1 0 1.41l-1.42 1.42a1 1 0 0 1-1.41-1.41l1.42-1.42a1 1 0 0 1 1.41 0Z"/>
506        </symbol>
507        <symbol id="theme-dark" viewBox="0 0 24 24">
508            <path fill="currentColor" d="M20 14.6A8 8 0 0 1 9.4 4a8.001 8.001 0 1 0 10.6 10.6Z"/>
509        </symbol>
510        <symbol id="theme-system" viewBox="0 0 24 24">
511            <path fill="currentColor" fill-rule="evenodd" d="M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Zm0 16V5a7 7 0 0 1 0 14Z" clip-rule="evenodd"/>
512        </symbol>
513        <symbol id="github" viewBox="0 0 32 32">
514            <path fill="currentColor" fill-rule="evenodd" d="M16 0c8.837 0 16 7.344 16 16.405 0 7.246-4.58 13.393-10.933 15.565-.811.161-1.099-.35-1.099-.788 0-.54.02-2.307.02-4.502 0-1.53-.513-2.528-1.087-3.037 3.563-.406 7.307-1.793 7.307-8.094 0-1.792-.62-3.255-1.648-4.403.166-.415.715-2.084-.157-4.343 0 0-1.34-.44-4.395 1.682A15.034 15.034 0 0 0 16 7.933a15 15 0 0 0-4.005.552C8.938 6.363 7.594 6.803 7.594 6.803c-.87 2.26-.32 3.928-.156 4.343-1.022 1.148-1.648 2.61-1.648 4.403 0 6.285 3.736 7.693 7.29 8.107-.458.41-.872 1.133-1.016 2.194-.912.419-3.229 1.144-4.656-1.364 0 0-.846-1.576-2.453-1.69 0 0-1.56-.022-.109.996 0 0 1.048.504 1.776 2.4 0 0 .94 2.928 5.39 1.936.009 1.371.023 2.664.023 3.054 0 .434-.294.941-1.093.79C4.584 29.802 0 23.651 0 16.404 0 7.344 7.165 0 16 0Z" clip-rule="evenodd"/>
515        </symbol>
516        <symbol id="twitter" viewBox="0 0 32 27">
517            <path fill="#00AAEC" fill-rule="evenodd" d="M32 3.157a12.822 12.822 0 0 1-3.77 1.06A6.717 6.717 0 0 0 31.115.493a12.93 12.93 0 0 1-4.171 1.632A6.472 6.472 0 0 0 22.153 0c-3.623 0-6.562 3.014-6.562 6.732 0 .527.056 1.04.169 1.533-5.457-.282-10.294-2.958-13.534-7.037a6.854 6.854 0 0 0-.887 3.389 6.778 6.778 0 0 0 2.92 5.603 6.446 6.446 0 0 1-2.974-.84v.083c0 3.262 2.263 5.984 5.268 6.6-.562.16-1.145.24-1.73.238-.422 0-.836-.041-1.236-.12.836 2.673 3.259 4.621 6.133 4.673a12.963 12.963 0 0 1-8.153 2.883c-.53 0-1.054-.031-1.567-.092a18.278 18.278 0 0 0 10.063 3.022c12.077 0 18.68-10.257 18.68-19.154 0-.292-.006-.585-.018-.872 1.29-.957 2.4-2.137 3.274-3.484Z" clip-rule="evenodd"/>
518        </symbol>
519    </svg>
520    
520<script src="/assets/js/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
520
521    
521<script>
522      // Theme toggle: cycles light -> dark -> system. Persists into the
523      // same `ex_doc:settings` localStorage entry that ExDoc uses, so
524      // the choice flows between Jekyll-rendered pages and the
525      // ExDoc-generated docs without a separate switch.
526      (function () {
527        var KEY = "ex_doc:settings";
528        var btn = document.getElementById("theme-toggle");
529        if (!btn) return;
530
531        function loadSettings() {
532          try { return JSON.parse(localStorage.getItem(KEY) || "{}"); }
533          catch (_) { return {}; }
534        }
535        function saveSettings(s) {
536          try { localStorage.setItem(KEY, JSON.stringify(s)); } catch (_) {}
537        }
538        function effectiveDark(theme) {
539          if (theme === "dark") return true;
540          if (theme === "light") return false;
541          return window.matchMedia &&
542                 window.matchMedia("(prefers-color-scheme: dark)").matches;
543        }
544        function apply(theme) {
545          var dark = effectiveDark(theme);
546          document.documentElement.classList.toggle("dark", dark);
547          document.documentElement.setAttribute(
548            "data-bs-theme", dark ? "dark" : "light");
549          btn.setAttribute("data-theme", theme || "system");
550        }
551
552        // Initial: reflect the current saved choice on the button.
553        var current = loadSettings().theme || "system";
554        apply(current);
555
556        btn.addEventListener("click", function () {
557          var order = ["light", "dark", "system"];
558          var next = order[(order.indexOf(current) + 1) % order.length];
559          current = next;
560          var s = loadSettings();
561          if (next === "system") delete s.theme; else s.theme = next;
562          saveSettings(s);
563          apply(next);
564        });
565
566        // When in system mode, react to OS theme changes live.
567        if (window.matchMedia) {
568          var mq = window.matchMedia("(prefers-color-scheme: dark)");
569          var listener = function () { if (current === "system") apply("system"); };
570          if (mq.addEventListener) mq.addEventListener("change", listener);
571          else if (mq.addListener) mq.addListener(listener);  // Safari < 14
572        }
573      })();
574    </script>
574
575</body>
576
577</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.