diff --git a/404.html b/404.html new file mode 100644 index 0000000..d1f167c --- /dev/null +++ b/404.html @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 404 Page not found | Guekka's blog + + + + + + + + + +
+ +
+
+
+

404 :(

+

Page not found, maybe moved. Try searching or go to homepage.

+ +
+
+ + + diff --git a/_headers b/_headers new file mode 100644 index 0000000..ccca3e1 --- /dev/null +++ b/_headers @@ -0,0 +1,68 @@ +# This _headers file is used to set headers on cloudflare pages: https://developers.cloudflare.com/pages/configuration/headers/ +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy (disabled everything except autoplay, local-fonts, screen-wake-lock, speaker-selection) +# opt out of Federated Learning of Cohorts (aka "FLoC") - https://amifloced.org/ +/* + X-Frame-Options: DENY + X-Content-Type-Options: nosniff + X-XSS-Protection: 1; mode=block + Referrer-Policy: strict-origin-when-cross-origin + Strict-Transport-Security: max-age=63072000; includeSubdomains + Permissions-Policy: interest-cohort=(), accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), browsing-topics=(), camera=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), identity-credentials-get=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), otp-credentials=(), payment=(), picture-in-picture=(), publickey-credentials-create=(), publickey-credentials-get=(), serial=(), storage-access=(), sync-xhr=(), usb=(), web-share=(), window-management=(), xr-spatial-tracking=() + Content-Security-Policy: default-src 'none'; frame-ancestors 'none'; object-src 'none'; base-uri 'self'; manifest-src 'self'; worker-src 'self'; form-action 'self'; connect-src 'self' *.hyvor.com ws://*.hyvor.com; script-src 'self' talk.hyvor.com; img-src 'self' data: talk.hyvor.com cdn.cloudflare.com; frame-src 'self' www.youtube-nocookie.com player.vimeo.com streamable.com www.streamable.com; media-src 'self' data: cdn.cloudflare.com www.youtube-nocookie.com player.vimeo.com; font-src 'self' cdn.cloudflare.com cdn.jsdelivr.net fonts.gstatic.com; style-src 'self' talk.hyvor.com cdn.cloudflare.com cdn.jsdelivr.net fonts.googleapis.com; + +/*.js + Cache-Control: public, max-age=604800, must-revalidate + +/*.css + Cache-Control: public, max-age=604800, must-revalidate + +/*.svg + Cache-Control: public, max-age=604800 + +/*.png + Cache-Control: public, max-age=604800 + +/*.ico + Cache-Control: public, max-age=604800 + +/*.jpg + Cache-Control: public, max-age=604800 + +/*.jpeg + Cache-Control: public, max-age=604800 + +/*.gif + Cache-Control: public, max-age=604800 + +/*.webp + Cache-Control: public, max-age=604800 + +/*.avif + Cache-Control: public, max-age=604800 + +/*.mp4 + Cache-Control: public, max-age=604800 + +/*.webm + Cache-Control: public, max-age=604800 + +/*.mp3 + Cache-Control: public, max-age=604800 + +/*.ogg + Cache-Control: public, max-age=604800 + +/*.otf + Cache-Control: public, max-age=604800 + +/*.eot + Cache-Control: public, max-age=604800 + +/*.ttf + Cache-Control: public, max-age=604800 + +/*.woff + Cache-Control: public, max-age=604800 + +/*.woff2 + Cache-Control: public, max-age=604800 diff --git a/about/index.html b/about/index.html new file mode 100644 index 0000000..156ae8c --- /dev/null +++ b/about/index.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + About | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+

About

+

Hi. I’m Edgar, more often known as Guekka, G’k or G_ka. I like Nix(OS), Rust, C++, and a lot of other technologies.

+

My most important contribution to the software world is an automation tool called Cathedral Assets Optimizer (source) which is used by thousands of people. Its main purpose is helping the process of “porting” a mod between Skyrim Legendary Edition and Skyrim Special Edition.

+ +
+
+ + + diff --git a/abridge.css b/abridge.css new file mode 100644 index 0000000..1898de1 --- /dev/null +++ b/abridge.css @@ -0,0 +1 @@ +:root{--ff:"iA Writer Quattro S",Roboto,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue","Noto Sans",Helvetica,Arial,sans-serif;--fm:ui-monospace,Menlo,Monaco,Consolas,"SF Mono","Cascadia Mono","Segoe UI Mono","DejaVu Sans Mono","Liberation Mono","Roboto Mono","Oxygen Mono","Ubuntu Monospace","Ubuntu Mono","Source Code Pro","Fira Mono","Droid Sans Mono","Courier New",Courier,monospace;color-scheme:var(--cs);--s1: .5rem;--s2: 1rem;--rc: .5rem;--br: 0.25rem;--bw: 0.0625rem;--ow: 0.1875rem;--fs: 1rem;--lh: 1.5;--lhh: 1.2;--fw: 400;--fh: 700}@media (min-width: 576px){:root{--fs: 1rem}}@media (min-width: 768px){:root{--fs: 1.04rem}}@media (min-width: 992px){:root{--fs: 1.08rem}}@media (min-width: 1200px){:root{--fs: 1.12rem}}:root:not(.switch){--cs:dark;--f1:#ccc;--f2:#ddd;--c1:#262626;--c2:#3a342e;--c3:#333;--c4:#888;--a1:#f90;--a2:#fb0;--a3:#f90;--a4:#f90;--cg:#593;--cr:#e33;--h0:#3a342e;--h1:#ddd;--h2:#888;--h3:#e65;--h4:#e83;--h5:#eb6;--h6:#ac3;--h7:#8db;--h8:#6ae;--h9:#d6e;--ha:160%}:root.switch{--cs:light;--f1:#333;--f2:#222;--c1:#fcf5e4;--c2:#e4dcc8;--c3:#ddd;--c4:#555;--a1:#c40;--a2:#e60;--a3:#f90;--a4:#c40;--cg:#373;--cr:#d33;--h0:#e4dcc8;--h1:#222;--h2:#666;--h3:#a21;--h4:#930;--h5:#a50;--h6:#350;--h7:#286;--h8:#059;--h9:#a3c;--ha:92%}*,*::before,*::after{box-sizing:border-box}html{text-rendering:optimizeLegibility;background-color:var(--c1);color:var(--f1);font-family:var(--ff);font-weight:var(--fw);font-size:var(--fs);line-height:var(--lh)}h1,h2,h3,h4,h5,h6{padding-left:0;color:var(--f2);margin:var(--s2) 0 var(--s1);font-weight:var(--fh);font-size:var(--fs);line-height:var(--lhh)}h1{font-size:2rem}h2{font-size:1.75rem}h3{font-size:1.5rem}h4{font-size:1.25rem}h5{font-size:1.125rem}header h1{margin:0}a{color:var(--a1);text-decoration:none;font-weight:500}a:hover{color:var(--a2);text-decoration:underline}a:visited{color:var(--a4)}h1 a,h2 a,main nav a,header li>a{color:var(--f2);text-decoration:none;font-weight:var(--fh)}h1 a:visited,h2 a:visited,main nav a:visited,header li>a:visited{color:var(--f2)}h1 a:hover,h2 a:hover,main nav a:hover,header li>a:hover{color:var(--a3);text-decoration:none}article{padding-bottom:.2rem}abbr[title]{border-bottom:var(--bw) dotted;text-decoration:none;cursor:help}mark{background-color:var(--c4);color:var(--c1);vertical-align:baseline;padding:.1rem .4rem}blockquote{margin-left:0;padding:.5rem 0 .5rem 1.5rem;border-left:.25rem solid var(--c3)}blockquote>:last-child{margin-bottom:0}small{font-size:.875rem}.footnote-definition sup,.footnote-definition p{display:inline}sub,sup{font-size:.75em;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}details summary{cursor:pointer}address,blockquote,dl,figure,form,ol,p,pre,table,ul{margin:.7rem 0;color:var(--f1);font-style:normal;font-weight:var(--fw);font-size:var(--fs)}ul,ol{padding-right:0;padding-left:var(--s2)}li{margin-bottom:.2rem}ins{color:var(--cg);text-decoration:none}del{color:var(--cr)}main{display:flex}main article,main div{flex:1 1 0;min-width:0}body{width:100%;margin:0}header,main,footer{width:100%;margin-right:auto;margin-left:auto;padding:var(--s1)}@media (min-width: 1200px){header,main,footer{min-width:1200px;max-width:70%}}header,main{padding-top:0;margin-top:0;padding-bottom:0;margin-bottom:0}header hr,main hr{margin:.1rem 0}footer{line-height:var(--lhh)}footer hr,footer p{margin:.2rem 0}header>nav>div{padding-top:var(--s2)}footer>div{padding-top:var(--s1)}header>nav,header>nav>div:nth-child(2){display:flex;flex-direction:column;flex-wrap:wrap;justify-content:space-between;align-items:center}header>nav ul{margin:0;display:flex;flex-wrap:wrap;justify-content:center;align-items:center}header>nav>div:nth-child(2){margin-left:auto;justify-content:center}header nav{margin:var(--s1) auto 0;flex-direction:column}header nav div:nth-child(2){margin:auto}nav{align-items:center;justify-content:center;display:flex}nav li{display:inline-block;margin:0 var(--s2) 0 0}.dropdown{display:inline-block;position:relative;z-index:1;font-weight:var(--fh);font-size:var(--fs)}.dropdown-content{display:none;position:absolute;cursor:pointer;text-align:center;right:-1rem;z-index:1;font-weight:var(--fh);font-size:var(--fs);background:var(--c2)}.dropdown-content a,.dropdown-content span{margin:0 var(--s1);display:block;text-decoration:none}.dropdown:hover .dropdown-content{display:block}article nav div:last-child{text-align:right}footer nav a{margin:.2rem}footer nav i{margin-bottom:.2rem}main nav{margin-top:var(--s2)}main nav a,main nav span{margin:.2rem}.on,.on:visited{font-weight:var(--fh);border:.1rem solid var(--c4);border-radius:var(--br);padding:.1rem var(--s1)}.on:hover{border-color:var(--a3)}.on:hover .svgh{background:var(--a3);opacity:1}.outp{padding:0 .26rem .2rem}.off{color:var(--c4);font-weight:var(--fh);border:.1rem solid var(--c3);border-radius:var(--br)}.off .svgh{background:var(--c3);opacity:1}.on{font-weight:var(--fh);border:.1rem solid var(--c4);border-radius:var(--br)}.mode:hover,.cnav{color:var(--a1)}@media (min-width: 768px){header nav,header>nav>div:nth-child(2){flex-direction:row;margin:0 0 0 auto}header>nav>div{padding-top:var(--s1)}}.yvi{position:absolute;top:0;left:0}.yv{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}img,video,svg{max-width:100%;height:auto}embed,iframe,object{max-width:100%}iframe{border-style:none;width:100%;height:100%;border:0;overflow:hidden}table{border-collapse:collapse;width:100%;text-indent:0}table caption{margin-bottom:.5rem}tr{border-bottom:var(--bw) solid var(--c3)}td,th{padding:var(--s1)}th{text-align:left}tbody tr:nth-child(even){background-color:var(--c2)}thead tr{border-top:var(--bw) solid var(--c3);background-color:var(--c2)}pre,code,kbd,samp,tt,var{border-radius:var(--br);background:var(--c2);font-family:var(--fm);overflow-x:auto;line-height:initial;font-size:.8rem;padding:.3rem .2rem}pre{position:relative;padding:2rem .5rem .3rem;display:block;overflow-x:auto;-ms-overflow-style:scrollbar;white-space:pre}pre>code{display:block;background:rgba(0,0,0,0)}kbd{background-color:var(--f2);color:var(--c1);vertical-align:baseline;font-size:1rem;padding:.2rem}pre code[data-lang]::before{content:attr(data-lang);padding:.3rem;display:block;background-color:var(--c3);color:var(--h1);width:100%;position:absolute;top:0;left:0;padding-left:1rem;text-transform:uppercase}code table{font-size:.8rem;margin:0;color:var(--h1)}code table mark{display:block;color:unset;padding:0;background-color:var(--h0);filter:brightness(var(--ha))}code td,code th,code tr{padding:0;border-bottom:none}code tbody td:first-child{text-align:center;user-select:none;min-width:60px}code tbody tr:nth-child(even),code thead tr{background-color:unset}.cc{cursor:pointer;z-index:9;position:absolute;top:.2rem;right:.5rem}.cc:hover{background:var(--a3);opacity:1}hr{box-sizing:content-box;height:0;overflow:visible;border:none;border-top:1px solid var(--f1)}header hr,footer hr{border-top:1px solid var(--c4)}figure{display:block;margin:0;padding:0;overflow-x:auto}figure figcaption{padding:var(--s1) 0;color:var(--c4)}button,input,select,textarea{margin:0;padding:.2rem var(--s1);max-width:100%;background:var(--c2);border:0;border-radius:.25rem;font:inherit;line-height:var(--fs);color:var(--f1)}button.del{color:var(--cr)}button,[type=button i],[type=submit i],[type=reset i]{display:inline-block;text-align:center;white-space:nowrap;color:var(--f1);border:0;cursor:pointer;transition:opacity .25s}button:hover,[type=button i]:hover,[type=submit i]:hover,[type=reset i]:hover{opacity:.75}button[disabled],[type=button i][disabled],[type=submit i][disabled],[type=reset i][disabled]{opacity:.5}fieldset{padding:.5rem .75rem;border:var(--bw) solid var(--c3);border-radius:.25rem}legend{padding:0 .25rem}label{cursor:pointer;display:block;margin-bottom:.25rem}[type=color i]{min-height:2.125rem}select:not([multiple]):not([size]){padding-right:1.5rem;background-repeat:no-repeat;background-position:right .5rem center;-moz-appearance:none;-webkit-appearance:none;appearance:none}textarea{width:100%;resize:vertical}textarea:not([rows]){height:8rem}.topout{position:sticky;bottom:1px;padding:20px;place-self:end;margin-top:110vh;pointer-events:none}.topleft{margin-left:calc(100% - 80px)}.top{pointer-events:all;padding:9px;border-radius:9px;font-weight:700;color:var(--a1);background:var(--c2)}.top:hover{text-decoration:none;color:var(--c2);background:var(--a1)}.top:hover .svgh{background:var(--c2);opacity:1}div:empty{display:none}.stork-close-button{display:none}.stork-title p{color:var(--a1);font-weight:var(--fh)}#suggestions{z-index:9;background:var(--c1);border:2px solid var(--c3);position:static;left:0;width:100%;margin-top:var(--s1);max-height:500px;overflow:auto}#suggestions a,#results a{display:block;text-decoration:none;padding:var(--s1);margin:0 var(--s1)}#suggestions a:hover,#suggestions a:focus,#results a:hover,#results a:focus{background:var(--c2)}#suggestions span,#results span{line-height:1.5;display:block}#suggestions span:first-child,#results span:first-child{font-weight:var(--fh)}#suggestions span:nth-child(2),#results span:nth-child(2){color:var(--f1)}.results{display:block;position:relative;width:100%}.searchd{display:flex;position:relative;align-items:center;white-space:nowrap}.searchd>input{max-width:100%;flex-grow:1;padding-right:2rem}.searchd>button{position:absolute;right:.5rem}@media (min-width: 768px){.searchd>input{width:15rem;flex-grow:0}#suggestions{position:absolute;right:0;left:unset;width:500px}}.sticky{position:sticky;top:var(--s2)}.block{max-width:30rem;margin:var(--s2) auto}.blockdiv{border-radius:var(--br);border-top:5px solid var(--a1);background-color:var(--c2);margin-top:var(--s2);padding:.2rem 0 var(--s2) var(--s2);max-height:100vh;overflow:auto;overflow-wrap:break-word}.blockdiv a{color:var(--f1)}.blockdiv a:hover{color:var(--a2)}.blockdiv ol{margin:0}.blockdiv .scur{font-weight:var(--fh);color:var(--a1)}.sblock{width:15rem;max-width:15rem;margin-left:var(--s1);display:none}.sblock details:not([open])+.hidden_li{height:0;visibility:hidden;overflow:hidden}.sblock summary{margin-left:-1em;margin-bottom:.2rem;color:var(--c4)}.sblock ol,.sblock ul{font-size:1em}.desc{display:none}@media (min-width: 768px){.sblock,.desc{display:unset}.block{display:none}}.img-swap-div .img-main{display:block}.img-swap-div .img-swap{display:none}.img-swap-div:hover .img-swap{display:block}.img-swap-div:hover .img-main{display:none}[style*="--c:"],section>section{flex:var(--c, 1);margin:var(--s1);color:var(--f2);padding:var(--s1);text-align:center}section{display:flex;flex-flow:row wrap}section article{padding:20px 30px;min-width:340px}section article div{text-align:center}section article h1,section article h2,section article h3{text-align:center}.adjust{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='none' stroke-width='1' fill='%23000' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C6 0 0 6 0 12s5 12 12 12 12-5 12-12S19 0 12 0Zm0 4c5 0 8 3 8 8s-3 8-8 8V4Z'/%3E%3C/svg%3E");background:var(--f2)}.angl{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='3' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='m16 4-8 8 8 8'/%3E%3C/svg%3E");background:var(--f2)}.angll{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='3' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='m11 4-8 8 8 8m9-16-8 8 8 8'/%3E%3C/svg%3E");background:var(--f2)}.angr{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='3' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='m8 4 8 8-8 8'/%3E%3C/svg%3E");background:var(--f2)}.angrr{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='3' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='m4 4 8 8-8 8m9-16 8 8-8 8'/%3E%3C/svg%3E");background:var(--f2)}.angu{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='3' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='m4 16 8-8 8 8'/%3E%3C/svg%3E");background:var(--f2)}.world{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M1 12a11 11 90 0 0 22 0 11 11 90 0 0-22 0m1-4h20M2 16h20M11 1a21 21 90 0 0 0 22m2-22a21 21 90 0 1 0 22'/%3E%3C/svg%3E");background:var(--f2)}.copy{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M11 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1ZM7 9H3a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-4'/%3E%3C/svg%3E");background:var(--f2)}.copy.yes{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");background:var(--cg)}.copy.err{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M1 12a1 1 0 0 0 22 0 1 1 0 0 0-22 0m11-7v9m0 5v-2'/%3E%3C/svg%3E");background:var(--cr)}.search{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23000' stroke-width='3' fill='none' viewBox='0 0 24 24'%3E%3Ccircle cx='9.5' cy='9.5' r='8'/%3E%3Cpath d='m23 23-9-9'/%3E%3C/svg%3E");background:var(--f2)}.github{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23888' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M9 19c-5 1.5-5-2.5-7-3m14 6v-3.9a3.4 3.4 0 0 0-1-2.6c3.2-.3 6.5-1.5 6.5-7A5.4 5.4 0 0 0 20 4.8 5 5 0 0 0 20 1s-1.3-.3-4 1.5a13.4 13.4 0 0 0-7 0C6.3.6 5 1 5 1a5 5 0 0 0 0 3.8 5.4 5.4 0 0 0-1.5 3.7c0 5.5 3.3 6.7 6.4 7a3.4 3.4 0 0 0-.9 2.6V22'/%3E%3C/svg%3E")}.github-sponsor{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23c49' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M20 4c-5-3-8 2-8 4 0-2-3-7-8-4-4 2-6 10 8 18 14-8 12-16 8-18z'/%3E%3C/svg%3E")}.gitlab{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23e62' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M22.6 14.4 12 22 1.3 14.4a.8.8 0 0 1-.3-1l1.3-3.7 2.4-7.5a.4.4 0 0 1 .1-.2.4.4 0 0 1 .6 0 .4.4 0 0 1 .1.2L8 9.7h8l2.5-7.5a.4.4 0 0 1 .1-.2.4.4 0 0 1 .6 0 .4.4 0 0 1 0 .2l2.5 7.5 1.3 3.8a.8.8 0 0 1-.3.9z'/%3E%3C/svg%3E")}.kofi{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath stroke='%23888' stroke-width='1.5' fill='%23fff' d='M2 5h15c8 0 8 10 0 10-1 0-1 0-1 1v2q0 1-1 1H2q-1 0-1-1V6q0-1 1-1m14 4v2c0 1 0 1 1 1 4 0 4-4 0-4-1 0-1 0-1 1'/%3E%3Cpath fill='%23f55' d='M9 16C2 11 5 6 9 9c4-3 7 2 0 7' /%3E%3C/svg%3E")}.rss{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23e94' stroke-width='2' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16'/%3E%3Ccircle cx='5' cy='19' r='1'/%3E%3C/svg%3E")}.x{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke='%23f00' stroke-width='3' fill='none' viewBox='0 0 24 24'%3E%3Cpath d='M21 3 3 21M3 3l18 18'/%3E%3C/svg%3E")}.svg{width:1.8rem;height:1.8rem;display:inline-block;text-align:center;vertical-align:middle}.svgs{width:var(--fs);height:var(--fs);min-width:24px;min-height:24px;display:inline-block;text-align:center;vertical-align:middle}.fa-a:hover{color:var(--a3);opacity:1}.sum,.sum p{margin:.2rem 0}.s150{font-size:1.5em}.s140{font-size:1.4em}.s130{font-size:1.3em}.s120{font-size:1.2em}.s110{font-size:1.1em}.s95{font-size:.95em}.s90{font-size:.9em}.s85{font-size:.85em}.s80{font-size:.8em}.s75{font-size:.75em}.s70{font-size:.7em}.hpad{padding:0 var(--s1)}.rpad{padding-right:var(--s1)}.tpad{padding-top:var(--s1)}.b{font-weight:var(--fh)}.c{text-align:center}.z-code{color:var(--h1);background-color:var(--h0)}.z-comment{color:var(--h2);font-style:italic}.z-variable{color:var(--h1)}.z-string{color:var(--h6)}.z-constant.z-numeric{color:var(--h4)}.z-constant.z-character.z-escape{color:var(--h7)}.z-constant.z-language{color:var(--h4)}.z-constant.z-other{color:var(--h4)}.z-keyword{color:var(--h8)}.z-keyword.z-operator{color:var(--h9)}.z-punctuation.z-separator,.z-punctuation.z-terminator{color:var(--h1)}.z-punctuation.z-section{color:var(--h1)}.z-punctuation.z-accessor{color:var(--h4)}.z-punctuation.z-definition.z-annotation{color:var(--h1)}.z-storage{color:var(--h8)}.z-storage.z-type{color:var(--h8)}.z-entity.z-name.z-function{color:var(--h5)}.z-entity.z-name{color:var(--h5)}.z-variable.z-parameter{color:var(--h4)}.z-variable.z-language{color:var(--h5);font-style:italic}.z-entity.z-name.z-tag{color:var(--h8)}.z-punctuation.z-definition.z-tag.z-end,.z-punctuation.z-definition.z-tag.z-begin,.z-punctuation.z-definition.z-tag{color:var(--h8)}.z-entity.z-other.z-attribute-name{color:var(--h5)}.z-variable.z-function,.z-variable.z-annotation{color:var(--h5)}.z-support.z-function,.z-support.z-macro{color:var(--h3)}.z-support.z-type,.z-support.z-class{color:var(--h8);font-style:italic}.z-support.z-type.z-property-name{color:var(--h8)}.z-key.z-json{color:var(--h4)} \ No newline at end of file diff --git a/android-chrome-192x192.png b/android-chrome-192x192.png new file mode 100644 index 0000000..a65e389 Binary files /dev/null and b/android-chrome-192x192.png differ diff --git a/android-chrome-512x512.png b/android-chrome-512x512.png new file mode 100644 index 0000000..4598101 Binary files /dev/null and b/android-chrome-512x512.png differ diff --git a/apple-touch-icon.png b/apple-touch-icon.png new file mode 100644 index 0000000..5cba871 Binary files /dev/null and b/apple-touch-icon.png differ diff --git a/archive/index.html b/archive/index.html new file mode 100644 index 0000000..937beac --- /dev/null +++ b/archive/index.html @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Archive | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+

2023

+

NixOS as a server, part 2: Flake, tailscale -

+

NixOS as a server, part 1: Impermanence -

+
+
+ + + diff --git a/banner.png b/banner.png new file mode 100644 index 0000000..b80b8e9 Binary files /dev/null and b/banner.png differ diff --git a/browserconfig.xml b/browserconfig.xml new file mode 100644 index 0000000..b3930d0 --- /dev/null +++ b/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/categories/index.html b/categories/index.html new file mode 100644 index 0000000..a638941 --- /dev/null +++ b/categories/index.html @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Categories | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+

1 Categories

+

[Projects]2

+
+

Projects

+

NixOS as a server, part 2: Flake, tailscale -

+

NixOS as a server, part 1: Impermanence -

+
+
+ + + diff --git a/categories/projects/atom.xml b/categories/projects/atom.xml new file mode 100644 index 0000000..062f50c --- /dev/null +++ b/categories/projects/atom.xml @@ -0,0 +1,786 @@ + + + Guekka's blog - Projects + C++, Nix, Linux, Self-hosting, and more. + + + Zola + 2023-05-17T00:00:00+00:00 + https://guekka.github.io/categories/projects/atom.xml + + NixOS as a server, part 2: Flake, tailscale + 2023-05-17T00:00:00+00:00 + 2023-05-17T00:00:00+00:00 + + + + + Unknown + + + + + + https://guekka.github.io/nixos-server-2/ + + <p>In the <a rel="noopener" target="_blank" href="https://guekka.github.io/nixos-server-1/">previous part</a>, we configured our NixOS server to use impermanence. I have made a few changes since, most notably moving to a proper VM in Proxmox.</p> +<p>The following instructions might lack some details, but you can follow <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/commits/2-tailscale">the GitHub repo</a> to see the full code.</p> +<h1 id="moving-to-flakes">Moving to flakes</h1> +<blockquote> +<p>If you already know about flakes, you can safely ignore this part.</p> +</blockquote> +<p>Have you heard about Nix flakes? If you have been in the Nix ecosystem for more than a few days, most likely. They’re the shiny new way to write Nix code, still experimental but used everywhere. +Their main advantage over traditional Nix is <em>purity</em>, mainly with their defined <code>inputs</code> and <code>outputs</code>. </p> +<p>Remember when I told you Nix was reproducible? It was a lie. Let me explain myself: when writing Nix code, we always have some kind of input. For example, <code>nixpkgs</code> will be required almost all the time. There are two ways to obtain it.</p> +<ul> +<li>fetch it: <code>import builtins.fetchTarball &quot;https://github.com/nixos/nixpkgs/archive/nixos-22.11.tar.gz&quot;;</code></li> +<li>or more commonly, use <em>channels</em>: <code>import &lt;nixpkgs&gt; {}</code></li> +</ul> +<p>This second way uses a globally-defined configuration, which can change externally to our Nix files. We thus lose complete reproducibility. Instead, flakes allow us to avoid channels by specifying inputs alongside Nix configuration, as well as blocking some actions that could hinder reproducibility.</p> +<p>For a more in depth introduction, have a look at <a rel="noopener" target="_blank" href="https://nixos.wiki/wiki/Flakes#See_also">the wiki</a>.</p> +<p>Now, why do we want to migrate to flakes? We do not have external requirements, do we? +Well, yes, we do. Apart from the obvious <code>nixpkgs</code> dependency, which is configured system-wide, the impermanence module is being imported:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">impermanence</span> <span class="z-invalid z-illegal">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">fetchTarball</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://github.com/Nix-community/impermanence/archive/master.tar.gz<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This <code>fetchTarball</code> call is bad, by the way, as we do not specify the expected hash. We could be a victim of a man-in-the-middle attack and not notice it.</p> +<p>Now that I intend to add more modules, and possibly use the <code>unstable</code> channel, it is better to migrate. Let’s see what our entry point would look like:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># what is consumed (previously provided by channels and fetchTarball)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">inputs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixpkgs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:NixOS/nixpkgs/nixos-22.11<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># (1)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">impermanence</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:Nix-community/impermanence<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># what will be produced (i.e. the build)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">outputs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span>@<span class="z-variable z-parameter z-function z-3 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (2)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixosConfigurations</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (3)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">server</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosSystem</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (4)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">packages</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">legacyPackages</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">x86_64-linux</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># (5)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">specialArgs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">inputs</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># forward inputs to modules</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">modules</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">./configuration.Nix</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>That’s a lot to understand at once. Let’s study it one line at a time. +Firstly, we have to understand this file is simply describing <code>outputs</code> as a function taking <code>inputs</code>. Like in mathematics, we create the same output given the same input: a <em>pure</em> function, would say functional programmers.</p> +<p><code>(1)</code> is defining an input: we simply give it an url. That line can be translated as *Grab the <code>nixos-22.11</code> branch from the GitHub repo <code>nixpkgs</code> owned by <code>NixOS</code>.</p> +<p><code>(2)</code> is defining the <code>outputs</code> function. Most complicated things are defined using functions in Nix. It takes a <em>named attribute set</em> argument as an input. So this syntax:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span>@<span class="z-variable z-parameter z-function z-3 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span> +</span></code></pre> +<p>is the same as:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-function z-4 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">inputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixpkgs</span> +</span></code></pre> +<p>In both cases, we’re accessing the <code>nixpkgs</code> property of the <code>inputs</code> set.</p> +<p>But in the first case, we don’t have to repeat <code>inputs.</code> everywhere. In JS, you would call that <em>destructuring</em>: it is just making inner elements easier to access. If you have troubles understanding the Nix syntax, I personally like <a rel="noopener" target="_blank" href="https://fasterthanli.me/series/building-a-rust-service-with-Nix/part-9">FasterThanLime article</a>.</p> +<p><code>(3)</code>: NixOS configuration have to be placed specifically in the <code>nixosConfigurations</code> set.</p> +<p><code>(4)</code> is the place where we actually define the system. We call the <code>nixosSystem</code> function and pass it some arguments. Yes, the whole system is an <code>output</code> too!</p> +<p><code>(5)</code>: we give the packages instance to our system. In our case, we are passing the default packages, but we might want to modify them before. We also have to specify our architecture (<code>x86_64</code>).</p> +<p>That’s pretty much it. With that <code>flake.Nix</code> in <code>/etc/nixos</code>, <code>nixos-rebuild</code> will work as before. However, if you’re using git, beware that your files all need to be under version control or Nix will not see them.</p> +<h1 id="secrets-with-sops">Secrets with Sops</h1> +<p>In order to set up Tailscale, we will use a pre-auth key. This allows us to connect to our server without interaction. However, we must hide this key, or other people could join our Tailscale network, which could obviously have dangerous consequences.</p> +<p>There are 2 well-known solutions : agenix and sops-nix. I’ve chosen sops for no particular reason. +The first step will be to add it to our flake. See, we already get a use for it!</p> +<h2 id="importing-sops-nix">Importing <code>sops-nix</code></h2> +<p>Let’s change our <code>inputs</code>:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">inputs</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops-nix</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:mic92/sops-nix<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">inputs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">nixpkgs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">follows</span> <span class="z-keyword z-operator z-bind z-nix">=</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>nixpkgs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<h3 id="follows"><code>Follows</code></h3> +<p>What’s up with this <code>follows</code>? <code>sops-nix</code> already depends on <code>nixpkgs</code>, but it might use a different revision than ours. Making it use our own has several advantages:</p> +<ul> +<li>improve consistency</li> +<li>reduce the number of evaluations required</li> +</ul> +<p>And how do we know if a package has inputs that need to be redirected? That’s the neat thing, we don’t. Either we have to look at the upstream <code>flake.nix</code>, or we can call <code>nix flake info</code> and get a graph like so:</p> +<pre class="z-code"><code><span class="z-text z-plain">Resolved URL: git+file:///etc/nixos +</span><span class="z-text z-plain">Locked URL: git+file:///etc/nixos +</span><span class="z-text z-plain">Path: /Nix/store/4b14z6ki7av3kid69sp5vgf50wzd3a73-source +</span><span class="z-text z-plain">Last modified: 2023-04-17 14:04:13 +</span><span class="z-text z-plain">Inputs: +</span><span class="z-text z-plain">├───impermanence: github:Nix-community/impermanence/6138e +</span><span class="z-text z-plain">├───nixpkgs: github:NixOS/nixpkgs/39fa0 +</span><span class="z-text z-plain">└───sops-Nix: github:mic92/sops-nix/de651 +</span><span class="z-text z-plain"> ├───nixpkgs follows input &#39;nixpkgs&#39; +</span><span class="z-text z-plain"> └───nixpkgs-stable: github:NixOS/nixpkgs/1040c +</span></code></pre> +<p>We can notice <code>sops-nix</code> also has a <code>nixpkgs-stable</code> input, that we might as well redirect.</p> +<h2 id="generating-a-key">Generating a key</h2> +<p><code>sops-nix</code> works by encrypting our secrets with private keys. +We thus need to provide it with the keys we will use. We can generate an <code>age</code> key, or get one from our <code>SSH</code> host key. +Each secrets group can have different allowed keys, so that one user cannot access another’s secrets. +I will use the SSH host key for my server:</p> +<pre class="z-code"><code><span class="z-text z-plain">$ nix-shell -p ssh-to-age --run &#39;cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age&#39; +</span><span class="z-text z-plain">age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh +</span></code></pre> +<p>We now have to write <code>.sops.yaml</code> file in order to configure which keys can access which secrets.</p> +<pre data-lang="yaml" class="language-yaml z-code"><code class="language-yaml" data-lang="yaml"><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">keys</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-meta z-property z-yaml"><span class="z-keyword z-control z-property z-anchor z-yaml"><span class="z-punctuation z-definition z-anchor z-yaml">&amp;</span></span><span class="z-entity z-name z-other z-anchor z-yaml">horus</span></span> <span class="z-string z-unquoted z-plain z-out z-yaml">age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh</span> +</span><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">creation_rules</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">path_regex</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">hosts/horus/secrets.yaml$</span> +</span><span class="z-source z-yaml"> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">key_groups</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">age</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-keyword z-control z-flow z-alias z-yaml"><span class="z-punctuation z-definition z-alias z-yaml">*</span></span><span class="z-variable z-other z-alias z-yaml">horus</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">path_regex</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">hosts/common/secrets.yaml$</span> +</span><span class="z-source z-yaml"> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">key_groups</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">age</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-keyword z-control z-flow z-alias z-yaml"><span class="z-punctuation z-definition z-alias z-yaml">*</span></span><span class="z-variable z-other z-alias z-yaml">horus</span> +</span></code></pre> +<p>That’s it for decryption. However, we need to write secrets too. For that, we can get the corresponding private key:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nix-shell</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> ssh-to-age<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>run</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key | install -D -m 400 /dev/stdin ~/.config/sops/age/keys.txt<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span></code></pre> +<p>That <code>install</code> bit is here to create the directory if it doesn’t exist and set the right permissions.</p> +<blockquote> +<p>Isn’t this insecure? The key is not password-locked.</p> +</blockquote> +<p>Indeed, if someone has access to our user account, they can read that key and decrypt the secrets. However, we can probably assume our user already has access to the local secrets, so it doesn’t matter much. Our goal is to be able to put these secrets on a public GitHub, not to protect them locally.</p> +<h2 id="configuring-sops-nix">Configuring <code>sops-nix</code></h2> +<p>Our last step is to configure <code>sops</code>. +We’re going to get fancy here, as I’m <del>stealing</del> borrowing a module from Misterio’s config. In the future, this will often happen, as his config happens to be a great resource. Let’s have a look at <code>sops.nix</code>:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">sops-nix</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">lib</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">config</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">isEd25519</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-function z-4 z-nix">k</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">k</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">type</span> <span class="z-keyword z-operator z-nix">==</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>ed25519<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">getKeyPath</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-function z-4 z-nix">k</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">k</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">path</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">keys</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">filter</span> <span class="z-variable z-parameter z-name z-nix">isEd25519</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">openssh</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">hostKeys</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">in</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">sops-nix</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sops</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">age</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">sshKeyPaths</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">map</span> <span class="z-variable z-parameter z-name z-nix">getKeyPath</span> <span class="z-variable z-parameter z-name z-nix">keys</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>This looks complicated, but it is not. First, we are declaring some functions in the <code>let</code> block.</p> +<ul> +<li><code>isEd25519</code> simply tells if an SSH key uses <code>ed25519</code></li> +<li><code>getKeyPath</code> gets the path of an SSH key</li> +<li><code>keys</code> is the list of <code>ed25519</code> keys, taken from <code>openssh</code></li> +</ul> +<p>Then we import <code>sops</code>. Finally, we give it the keys we collected earlier. This avoids hardcoding keys, which is great!</p> +<p>We can now import this module in our config:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">imports</span> <span class="z-invalid z-illegal">=</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">impermanence</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModule</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">./hardware-configuration.Nix</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">../../modules/sops.nix</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p><code>sops-nix</code> is now ready to use. Do not forget to rebuild the config.</p> +<h2 id="our-first-secret">Our first secret</h2> +<p>Let’s write a secret:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> hosts/horus</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nix-shell</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> sops<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>run</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>sops hosts/horus/secrets.yaml<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span></code></pre> +<p>An editor should open. We can now write secrets, using yaml. Once we’re done, we can save the file. Example content:</p> +<pre data-lang="yaml" class="language-yaml z-code"><code class="language-yaml" data-lang="yaml"><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">tailscale_key</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">e2b6595884993e001da58d2995af65df489582a702e3a2f3</span> +</span></code></pre> +<p>We now have to tell <code>sops</code> this secret exists. So we declare it somewhere in our configuration:</p> +<pre class="z-code"><code><span class="z-text z-plain">sops.secrets.tailscale_key = { +</span><span class="z-text z-plain"> sopsFile = ./secrets.yaml; +</span><span class="z-text z-plain">}; +</span></code></pre> +<p>And that’s all! To use it, we simply have to use <code>config.sops.secrets.tailscale_key.path</code> where we need it. Beware that this will not give you the secret, but a path to a file containing the raw secret, for security reasons. Otherwise, the secret would be in the Nix store, and thus accessible to any user on the system.</p> +<h2 id="note-adding-a-new-host">Note: adding a new host</h2> +<p>If you ever need to add a new host, you will need to update your secrets with <code>sops updatekeys your_secret</code>. This command has to be on a system with already authorized keys.</p> +<h1 id="tailscale">Tailscale</h1> +<p>We can finally get to a real feature, setting up Tailscale. +For those of you who haven’t heard of it, Tailscale is a private meshed network, allowing you to connect to your machines privately and securely through Wireguard, a VPN protocol, without exposing them to the world. +This means being able to close port 22, while still being able to SSH into your computer.</p> +<p>Furthermore, Tailscale offers some additional features, such as a fancy file sending tool or hole punching, which allows you to connect to your computer even if it is behind a NAT. I won’t go into details here, but you can read more about it on <a rel="noopener" target="_blank" href="https://tailscale.com/">their website</a>.</p> +<p>I’ve chosen to write a full-fledged NixOS module for Tailscale, as it is a service that needs to be configured and started. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!</p> +<h2 id="boilerplate-for-nixos-modules">Boilerplate for NixOS modules</h2> +<p>We’re going to write a module, so we need to create a directory for it:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> modules/nixos</span> +</span></code></pre> +<p>Inside, we’ll need a <code>default.nix</code> file:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale-autoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">import</span> <span class="z-string z-unquoted z-path z-nix">./tailscale-autoconnect.nix</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>By convention, this file is automatically imported when you import a directory. Then, in our <code>flake.nix</code>, we can import our module:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">outputs</span> <span class="z-invalid z-illegal">=</span> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixosModules</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">import</span> <span class="z-string z-unquoted z-path z-nix">./modules/nixos</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>As before, the <code>nixosModules</code> attribute has a special meaning.</p> +<p>Finally, we have to import the module we’re writing in our configuration:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">imports</span> <span class="z-invalid z-illegal">=</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">outputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale-autoconnect</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<h2 id="writing-the-module">Writing the module</h2> +<p>We’re going to write a module to start Tailscale and connect to it automatically. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!</p> +<p>First, we need to create a <code>tailscale-autoconnect.nix</code> file in our <code>modules/nixos</code> directory. We’ll start with the boilerplate:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">config</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">lib</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">pkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-invalid z-illegal z-reserved z-nix">with</span> <span class="z-variable z-parameter z-function z-maybe z-nix">lib</span><span class="z-invalid z-illegal">;</span> <span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">cfg</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-keyword z-other z-nix">in</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">options</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscaleAutoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkEnableOption</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscaleAutoconnect<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">config</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkIf</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">enable</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"><span class="z-invalid z-illegal">}</span> +</span></code></pre> +<p>This is the basic structure of a module. We declare an option, and then we use it to conditionally change the configuration. So:</p> +<ul> +<li>What we write in <code>options</code> is the option declaration</li> +<li>What we write in <code>config</code> is the consequence of the option being enabled, the configuration change</li> +</ul> +<p>Let’s declare all the options first.</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">options</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkEnableOption</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscaleAutoconnect<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">authkeyFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The authkey to use for authentication with Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">loginServer</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The login server to use for authentication with Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">advertiseExitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">bool</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Whether to advertise this node as an exit node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The exit node to use for this node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">bool</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Whether to allow LAN access to this node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This looks like a lot of code, but we’re simply declaring options. We need to give them a type, and we can also give a default value and a description. +Now, the actually useful code:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">config</span> <span class="z-invalid z-illegal">=</span> <span class="z-variable z-parameter z-name z-nix">mkIf</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">enable</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertions</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">authkeyFile</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>authkeyFile must be set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-nix">-&gt;</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>exitNodeAllowLanAccess must be false if exitNode is not set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span> <span class="z-keyword z-operator z-nix">-&gt;</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">==</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span><span class="z-entity z-other z-attribute-name z-multipart z-nix">d</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>advertiseExitNode must be false if exitNode is set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">systemd</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale-autoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Automatic connection to Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># make sure tailscale is running before trying to connect to tailscale</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">after</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>network-pre.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wants</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>network-pre.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wantedBy</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>multi-user.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">serviceConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">Type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>oneshot<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">script</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-keyword z-other z-nix">with</span> <span class="z-variable z-parameter z-name z-nix">pkgs</span>; <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # wait for tailscaled to settle +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> sleep 2 +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # check if we are already authenticated to tailscale +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> status=&quot;$(<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale status -json | <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">jq</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/jq -r .BackendState)&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # if status is not null, then we are already authenticated +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;tailscale status: $status&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> if [ &quot;$status&quot; != &quot;NeedsLogin&quot; ]; then +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> exit 0 +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> fi +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # otherwise authenticate with tailscale +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # timeout after 10 seconds to avoid hanging the boot process +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">coreutils</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/timeout 10 <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale up \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--login-server=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> --authkey=$(cat &quot;<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">authkeyFile</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>&quot;) +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # we have to proceed in two steps because some options are only available +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # after authentication +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">coreutils</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/timeout 10 <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale up \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--login-server=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--advertise-exit-node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--exit-node=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNodeAllowLanAccess</span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--exit-node-allow-lan-access<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">networking</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">firewall</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">trustedInterfaces</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale0<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">allowedUDPPorts</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">port</span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">useRoutingFeatures</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-keyword z-other z-nix">if</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span> <span class="z-keyword z-other z-nix">th</span><span class="z-keyword z-other z-nix">en</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>server<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-keyword z-other z-nix">el</span><span class="z-keyword z-other z-nix">se</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>client<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>First, the assertions. They’re here to make sure that the user doesn’t make any mistake when configuring the module. For example, a user cannot both advertise an exit node and set an exit node. +Then, the service. We’re using systemd to run a script that will connect to Tailscale. The <code>after</code>, <code>wants</code> and <code>wantedBy</code> options make the script run after the network is up and after Tailscale daemon is started. The <code>Type</code> option is here to make sure that the script is run only once. The script itself is a bit long, but it’s just a bunch of bash commands. It’s pretty straightforward. First, we wait for the Tailscale daemon to settle. Then, we check if we’re already authenticated. If we are, we exit. Otherwise, we authenticate. Finally, we connect to Tailscale. We have to do it in two steps because some options are only available after authentication.</p> +<p>At the end, we configure the firewall to allow Tailscale traffic, and we enable the Tailscale service.</p> +<p>Now, an example of how to use this module:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">outputs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">...</span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">outputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale-autoconnect</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscaleAutoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">authkeyFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sops</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">secrets</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale_key</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">path</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">loginServer</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://login.tailscale.com<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>some-node-id<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">secrets</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale_key</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sopsFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-unquoted z-path z-nix">./secrets.yaml</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">environment</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">persistence</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">directories</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/var/lib/tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>The module is imported and configured. We also use the <code>sops</code> secret we created earlier. Finally, we persist the Tailscale state, so that we don’t have to authenticate again after a reboot. This is especially important if the authkey can expire.</p> +<hr /> +<p>That’s all for this post. Thanks for reading! If you have any question, feel free to ask in the comments. The final code can be found <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/tree/2-tailscale">here</a>.</p> +<!-- +# Our first service : a simple file server + +Our first service will be a basic web server. For that, we will use nginx. `nginx` is, obviously, a web server. However, it is often also used as a reverse proxy, forwarding the requests it gets to the internal services. `nginx.Nix`: +```nix +{ + services.nginx = { + enable = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + clientMaxBodySize = "300m"; + }; + networking.firewall.allowedTCPPorts = [ 80 443 ]; +} +``` +`web-server.Nix`: +```nix +{ + services.nginx.virtualHosts."e1.oze.li" = { + addSSL = true; + enableACME = true; + root = "/var/www/files"; + }; + + environment.persistence = { + "/persist".directories = [ "/var/www/files" ]; + }; +} +``` +We are enabling the `nginx` service. For now, it only serves `e1.oze.li`, our web server. You can notice the `addSSL` parameter, together with `enableACME`: thanks to them, we are getting a HTTPS certificate for free, provided by LetsEncrypt. We need to accept its terms. `acme.Nix`: +```nix + # Enable acme for usage with nginx vhosts + security.acme = { + defaults.email = "some@email.com"; + acceptTerms = true; + }; + + environment.persistence = { + "/persist".directories = [ "/var/lib/acme" ]; + }; +} +``` +That's all! That is so simple and straightforward. I couldn't imagine myself using only Docker now. +--> + + + + + NixOS as a server, part 1: Impermanence + 2023-02-20T00:00:00+00:00 + 2023-02-20T00:00:00+00:00 + + + + + Unknown + + + + + + https://guekka.github.io/nixos-server-1/ + + <p>A few months ago, I woke up with the idea of hosting my own services. I went through a lot of tries. LXC, Debian, Alpine, (rootless or not) Docker, podman, portainer…</p> +<p>But no solution felt perfect. Until I decided to have a try at hosting using NixOS.</p> +<p>I’m going to assume you know about NixOS and have some prior experience. However, for a small summary: NixOS is a Linux distribution revolving around the Nix package manager. Its main advantage is having a reproducible environment through a declarative configuration. This means that you can copy an entire computer configuration easily: if it works somewhere, it will work anywhere.</p> +<p>My main focus point is reproducibility, so that’s why we’ll start with configuring <em>impermanence</em>.</p> +<h2 id="what-s-impermanence">What’s impermanence?</h2> +<p>Originally, a philosophic concept. But in our case, impermanence means erasing the <code>/</code> drive at each reboot. You read that right, erasing <em>almost</em> everything at each reboot. This part stands on the shoulders of those who did it before me:</p> +<ul> +<li><a rel="noopener" target="_blank" href="https://grahamc.com/blog/erase-your-darlings">Erase your darlings: immutable infrastructure for mutable systems - Graham Christensen</a></li> +<li><a rel="noopener" target="_blank" href="https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/">NixOS ❄: tmpfs as root</a></li> +<li><a rel="noopener" target="_blank" href="https://mt-caret.github.io/blog/posts/2020-06-29-optin-state.html#fn6">Encypted Btrfs Root with Opt-in State on NixOS</a></li> +<li><a rel="noopener" target="_blank" href="https://xeiaso.net/blog/paranoid-nixos-2021-07-18">Paranoid NixOS Setup - Xe Iaso</a></li> +<li><a rel="noopener" target="_blank" href="https://github.com/nix-community/impermanence">nix-community/impermanence: NixOS module</a></li> +</ul> +<p>The goal is the following: over years, configuration files accumulate. Sometimes editing <code>/etc</code> is required, because of a bug or an obscure configuration. NixOS allows us to avoid this manual file editing, but it does not <em>force</em> us to do so. We can still have a lot of important state, breaking the reproducibility promise.</p> +<p>So what can we do instead? Erase everything, at each reboot. This way, we’ll be sure the only source of truth is our configuration.</p> +<h2 id="installing-the-system">Installing the system</h2> +<p>I’m currently using a <a rel="noopener" target="_blank" href="https://github.com/quickemu-project/quickemu">quickemu</a> VM. This is not a recommenced setup and is only done for testing. Configuration file:</p> +<pre data-lang="conf" class="language-conf z-code"><code class="language-conf" data-lang="conf"><span class="z-source z-genconfig"><span class="z-meta z-comment z-genconfig"><span class="z-comment z-line z-number-sign z-genconfig">#!/usr/bin/quickemu --vm +</span></span></span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">guest_os</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;linux&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">disk_img</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;nixos-22.11-minimal/disk.qcow2&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">iso</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;nixos-22.11-minimal/latest-nixos-minimal-x86_64-linux.iso&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">disk_size</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;50G&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">ram</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;4G&quot;</span> +</span></code></pre> +<p>Let’s first format it:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">DISK</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell">/dev/vda</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mklabel gpt</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart ESP fat32 1MiB 1GiB</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> set 1 boot on</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkfs.vfat</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>1</span> +</span></code></pre> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart Swap linux-swap 1GiB 9GiB</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkswap</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>L</span> Swap <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>2</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">swapon</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>2</span> +</span></code></pre> +<blockquote> +<p>Using swap in 2023!?</p> +</blockquote> +<p><a rel="noopener" target="_blank" href="https://chrisdown.name/2018/01/02/in-defence-of-swap.html">Yes</a>.</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart primary 9GiB 100<span class="z-meta z-group z-expansion z-job z-shell"><span class="z-punctuation z-definition z-variable z-job z-shell">%</span></span></span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkfs.btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>L</span> Butter <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3</span> +</span></code></pre> +<p>While the <code>impermanence</code> module recommends using <code>tmpfs</code> for <code>/</code>, I chose to use <code>btrfs</code>: I do not have RAM to waste. Furthermore, this will allow us to use a nice script we’ll see later on.</p> +<p>Let’s create <code>btrfs</code> subvolumes:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/root</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/home</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/nix</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/persist</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/log</span> +</span></code></pre> +<p>And now, the crucial part:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume snapshot<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>r</span> /mnt/root /mnt/root-blank</span> +</span></code></pre> +<p>We just took a snapshot of that empty volume. We will restore it at each reboot. +We can now mount the subvolumes and let <code>nixos-generate-config</code> do its job</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=root,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/home</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=home,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/home</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/nix</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=nix,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/nix</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/persist</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=persist,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/persist</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> /mnt/var/log</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=log,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/var/log</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/boot</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>1 /mnt/boot</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nixos-generate-config</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>root</span> /mnt</span> +</span></code></pre> +<p>Lastly, we only have to edit the generated configuration files at <code>/mnt/etc/nixos</code>.</p> +<p>My final configuration is available <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/tree/1-impermanence">here</a>. You can follow all the steps by looking at the <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/commits/1-impermanence">commits</a>.</p> +<h2 id="configuring-the-system">Configuring the system</h2> +<ul> +<li>Checking that we have the correct mount options in <code>/mnt/etc/nixos/hardware-configuration.nix</code>.</li> +</ul> +<p>I’ve added <code>&quot;compress=zstd&quot; &quot;noatime&quot;</code> to all filesystems. We also need to add <code>neededForBoot</code> to <code>/var/log</code> and <code>/persist</code>.</p> +<ul> +<li>Replacing default values in <code>configuration.nix</code></li> +</ul> +<p>I’ve enabled <code>networkmanager</code>, removed most suggested options and enabled <code>system.copySystemConfiguration</code>.</p> +<p>This last option copies the current configuration to <code>/run/current_system/configuration.nix</code>. You should not rely on it: keep your configuration in a git repository. But it can serve as some kind of last chance.</p> +<ul> +<li>Declaring a user, including ssh</li> +</ul> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">mutableUsers</span> <span class="z-invalid z-illegal">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">user</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">isNormalUser</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">extraGroups</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>wheel<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">openssh</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">authorizedKeys</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">keys</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICWVNch9BcjkMqS/Xwep+GN4HwqyRIjr3Cuw7mHpqsKr nixos<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># passwordFile needs to be in a volume marked with `neededForBoot = true`</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">passwordFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist/passwords/user<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>Here we have completely disabled imperative user modification. This does not matter much, as imperative changes would be erased anyway at start. +We thus need to provide a password. We’re using <code>passwordFile</code> for that: a path to a file containing the hashed password.</p> +<p>Here’s how to generate that file: <code>sudo mkpasswd -m sha-512 &quot;hunter2&quot; &gt; /mnt/persist/passwords/user</code>.</p> +<p>The SSH key was generated using `ssh-keygen -t ed25519 -C “nixos”.</p> +<ul> +<li>Enabling openSSH +We’re going to use Xe’s configuration:</li> +</ul> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">openssh</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">passwordAuthentication</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">allowSFTP</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># Don&#39;t set this if you need sftp</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">challengeResponseAuthentication</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">extraConfig</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowTcpForwarding yes +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> X11Forwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowAgentForwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowStreamLocalForwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AuthenticationMethods publickey +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This reduces attack surface, for example by disabling stream-local forwarding and disabling password authentification.</p> +<hr /> +<p>This will be enough for now. Let’s install the system before going to the next step: <code>sudo nixos-install --root /mnt &amp;&amp; sudo reboot</code>. You should be able to connect by SSH using the previously defined key, or login using the password you defined in <code>/persist/passwords/user</code>.</p> +<h2 id="configuring-impermanence">Configuring impermanence</h2> +<p>We’ve created our volumes, we’ve configured the system… But I promised we would reset our system at each reboot. Let’s do that now! +We’re going to use the following script, credit of mt-caret. Do not forget to replace <code>vda3</code> with your data partition.</p> +<p><strong>16/07/23 update</strong>: it was brought to my attention that <a rel="noopener" target="_blank" href="https://discourse.nixos.org/t/what-does-impermanence-add-over-built-in-functionality/27939/16">postDeviceCommands can cause data loss</a>. +While I did not experience any issue, I have updated the script to use a safer alternative.</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">boot</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">initrd</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">supportedFilesystems</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>btrfs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">systemd</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">restore-root</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Rollback btrfs rootfs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wantedBy</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>initrd.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">requires</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>dev-vda3<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">after</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>dev-vda3<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># for luks</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>systemd-cryptsetup@<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">networking</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">hostName</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">before</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>sysroot.mount<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">unitConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">DefaultDependencies</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>no<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">serviceConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">Type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>oneshot<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">script</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> mkdir -p /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # We first mount the btrfs root to /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # so we can manipulate btrfs subvolumes. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> mount -o subvol=/ /dev/vda3 /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # While we&#39;re tempted to just delete /root and create +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # a new snapshot from /root-blank, /root is already +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # populated at this point with a number of subvolumes, +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # which makes `btrfs subvolume delete` fail. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # So, we remove them first. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # /root contains subvolumes: +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # - /root/var/lib/portables +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # - /root/var/lib/machines +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # I suspect these are related to systemd-nspawn, but +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # since I don&#39;t use it I&#39;m not 100% sure. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # Anyhow, deleting these subvolumes hasn&#39;t resulted +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # in any issues so far, except for fairly +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # benign-looking errors from systemd-tmpfiles. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume list -o /mnt/root | +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> cut -f9 -d&#39; &#39; | +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> while read subvolume; do +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;deleting /$subvolume subvolume...&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume delete &quot;/mnt/$subvolume&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> done &amp;&amp; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;deleting /root subvolume...&quot; &amp;&amp; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume delete /mnt/root +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;restoring blank /root subvolume...&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume snapshot /mnt/root-blank /mnt/root +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # Once we&#39;re done rolling back to a blank snapshot, +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # we can unmount /mnt and continue on the boot process. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> umount /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>We can then specify the files we want to keep.</p> +<p>But which files do we want to keep? Let’s find out. Thanks to another useful script of mt-caret, we can list the differences between our current <code>/</code> and the blank state:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell">!/usr/bin/env bash</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> fs-diff.sh</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-support z-function z-set z-shell">set</span></span><span class="z-meta z-function-call z-arguments z-shell"> -euo pipefail</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">OLD_TRANSID</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-meta z-group z-expansion z-command z-parens z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> btrfs subvolume find-new /mnt/root-blank 9999999</span><span class="z-punctuation z-section z-parens z-end z-shell">)</span></span></span> +</span><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">OLD_TRANSID</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-expansion z-parameter z-begin z-shell">{</span></span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-variable z-other z-readwrite z-shell">OLD_TRANSID<span class="z-keyword z-operator z-expansion z-shell">#</span></span></span><span class="z-meta z-group z-expansion z-parameter z-shell">transid marker was </span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-section z-expansion z-parameter z-end z-shell">}</span></span></span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> btrfs subvolume find-new <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>/mnt/root<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">OLD_TRANSID</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sed</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&#39;</span>$d<span class="z-punctuation z-definition z-string z-end z-shell">&#39;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">cut</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>f17-</span><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>d</span><span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&#39;</span> <span class="z-punctuation z-definition z-string z-end z-shell">&#39;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sort</span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">uniq</span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-loop z-while z-shell">while</span> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-read z-shell">read</span></span><span class="z-meta z-function-call z-arguments z-shell"> path</span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-loop z-do z-shell">do</span> +</span><span class="z-source z-shell z-bash"> <span class="z-variable z-other z-readwrite z-assignment z-shell">path</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>/<span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-if z-shell">if</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell">-</span>L</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-conditional z-then z-shell">then</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-colon z-shell">:</span></span> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> The path is a symbolic link, so is probably handled by NixOS already</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-elseif z-shell">elif</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell">-</span>d</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-conditional z-then z-shell">then</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-colon z-shell">:</span></span> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> The path is a directory, ignore</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-else z-shell">else</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-echo z-shell">echo</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-end z-shell">fi</span> +</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-loop z-end z-shell">done</span> +</span></code></pre> +<p>Used like this:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /mnt</span> <span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mount<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=/ /dev/vda3 /mnt</span> <span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">./fs-diff.sh</span></span> +</span></code></pre> +<p>Here’s the result of mine:</p> +<pre class="z-code"><code><span class="z-text z-plain">/etc/.clean +</span><span class="z-text z-plain">/etc/group +</span><span class="z-text z-plain">/etc/machine-id +</span><span class="z-text z-plain">/etc/nixos/configuration.nix +</span><span class="z-text z-plain">/etc/nixos/hardware-configuration.nix +</span><span class="z-text z-plain">/etc/passwd +</span><span class="z-text z-plain">/etc/resolv.conf +</span><span class="z-text z-plain">/etc/shadow +</span><span class="z-text z-plain">/etc/ssh/authorized_keys.d/user +</span><span class="z-text z-plain">/etc/ssh/ssh_host_ed25519_key +</span><span class="z-text z-plain">/etc/ssh/ssh_host_ed25519_key.pub +</span><span class="z-text z-plain">/etc/ssh/ssh_host_rsa_key +</span><span class="z-text z-plain">/etc/ssh/ssh_host_rsa_key.pub +</span><span class="z-text z-plain">/etc/subgid +</span><span class="z-text z-plain">/etc/subuid +</span><span class="z-text z-plain">/etc/sudoers +</span><span class="z-text z-plain">/etc/.updated +</span><span class="z-text z-plain">/root/.nix-channels +</span><span class="z-text z-plain">/root/.nix-defexpr/channels +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s8.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/NetworkManager-intern.conf +</span><span class="z-text z-plain">/var/lib/NetworkManager/secret_key +</span><span class="z-text z-plain">/var/lib/NetworkManager/timestamps +</span><span class="z-text z-plain">/var/lib/nixos/auto-subuid-map +</span><span class="z-text z-plain">/var/lib/nixos/declarative-groups +</span><span class="z-text z-plain">/var/lib/nixos/declarative-users +</span><span class="z-text z-plain">/var/lib/nixos/gid-map +</span><span class="z-text z-plain">/var/lib/nixos/uid-map +</span><span class="z-text z-plain">/var/lib/systemd/catalog/database +</span><span class="z-text z-plain">/var/lib/systemd/random-seed +</span><span class="z-text z-plain">/var/.updated +</span></code></pre> +<p>That’s not too bad!</p> +<p>Out of these, there’s almost nothing I want to preserve.</p> +<p>Let’s make use of the <code>impermanence</code> module. We need to download it:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">impermanence</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">fetchTarball</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://github.com/nix-community/impermanence/archive/master.tar.gz<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">in</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"><span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">impermanence</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/nixos.nix<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-unquoted z-path z-nix">./hardware-configuration.nix</span> <span class="z-punctuation z-definition z-list z-nix">]</span> +</span><span class="z-source z-nix"><span class="z-keyword z-operator z-nix">//</span> <span class="z-variable z-parameter z-name z-nix">the</span> <span class="z-variable z-parameter z-name z-nix">whole</span> <span class="z-variable z-parameter z-name z-nix">configuration</span> +</span><span class="z-source z-nix"><span class="z-invalid z-illegal">}</span> +</span></code></pre> +<p>And now, we can just tell it the files and directories that we want:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># configure impermanence</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">environment</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">persistence</span><span class="z-keyword z-operator z-nix">.</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">directories</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/nixos<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">files</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/machine-id<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_ed25519_key<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_ed25519_key.pub<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_rsa_key<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_rsa_key.pub<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-invalid z-illegal">}</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">security</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sudo</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">extraConfig</span> <span class="z-invalid z-illegal">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # rollback results in sudo lectures after each reboot +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> Defaults lecture = never +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>What an ergonomic interface.</p> +<blockquote> +<p>Wait, did you just say Nix was ergonomic?</p> +</blockquote> +<p>Well, yes. Sometimes.</p> +<hr /> +<p>I have not saved my network manager configuration, but you may need to.</p> +<p>When new files are set to be preserved, <strong>it is necessary to copy them manually to <code>/persist</code></strong>:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> nixos-rebuild boot</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /persist/etc</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>r</span> <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/nixos</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/machine-id</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /persist/etc/ssh</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_ed25519_key</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_ed25519_key.pub</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_rsa_key</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_rsa_key.pub</span> +</span></code></pre> +<p>Now, if we reboot and list files again:</p> +<pre class="z-code"><code><span class="z-text z-plain">/etc/.clean +</span><span class="z-text z-plain">/etc/group +</span><span class="z-text z-plain">/etc/passwd +</span><span class="z-text z-plain">/etc/resolv.conf +</span><span class="z-text z-plain">/etc/shadow +</span><span class="z-text z-plain">/etc/ssh/authorized_keys.d/user +</span><span class="z-text z-plain">/etc/subgid +</span><span class="z-text z-plain">/etc/subuid +</span><span class="z-text z-plain">/etc/sudoers +</span><span class="z-text z-plain">/etc/.updated +</span><span class="z-text z-plain">/root/.nix-channels +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/NetworkManager-intern.conf +</span><span class="z-text z-plain">/var/lib/NetworkManager/secret_key +</span><span class="z-text z-plain">/var/lib/NetworkManager/timestamps +</span><span class="z-text z-plain">/var/lib/nixos/auto-subuid-map +</span><span class="z-text z-plain">/var/lib/nixos/declarative-groups +</span><span class="z-text z-plain">/var/lib/nixos/declarative-users +</span><span class="z-text z-plain">/var/lib/nixos/gid-map +</span><span class="z-text z-plain">/var/lib/nixos/uid-map +</span><span class="z-text z-plain">/var/lib/systemd/catalog/database +</span><span class="z-text z-plain">/var/lib/systemd/random-seed +</span><span class="z-text z-plain">/var/.updated +</span></code></pre> +<p>Success! The files we persisted are no longer showing up.</p> +<h3 id="what-about-our-home-directory">What about our home directory?</h3> +<p>It is possible to setup the impermanence module for our home directory. However, I did not want to go through <code>home-manager</code> installation. Furthermore, a home directory is meant to be stateful.</p> +<p>In our case, we are creating a server, so it would still make sense to configure it. If you are interested, have a look at <a rel="noopener" target="_blank" href="https://elis.nu/blog/2020/06/nixos-tmpfs-as-home/">tmpfs at home</a>.</p> +<h2 id="next-steps">Next steps</h2> +<p>In the next part, we will make our server more secure by making it only available through Tailscale. We will also setup our first service.</p> +<hr /> +<p>I hope you’ve enjoyed this article! Thanks for reading to the end!</p> + + + + diff --git a/categories/projects/index.html b/categories/projects/index.html new file mode 100644 index 0000000..bf709fa --- /dev/null +++ b/categories/projects/index.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Projects category | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+

Projects

+

2023

+

NixOS as a server, part 2: Flake, tailscale -

+

NixOS as a server, part 1: Impermanence -

+
+
+ + + diff --git a/elasticlunr.min.js b/elasticlunr.min.js new file mode 100644 index 0000000..79dad65 --- /dev/null +++ b/elasticlunr.min.js @@ -0,0 +1,10 @@ +/** + * elasticlunr - http://weixsong.github.io + * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.6 + * + * Copyright (C) 2017 Oliver Nightingale + * Copyright (C) 2017 Wei Song + * MIT Licensed + * @license + */ +!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o \ No newline at end of file diff --git a/fonts/KaTeX_AMS-Regular.woff2 b/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 0000000..0acaaff Binary files /dev/null and b/fonts/KaTeX_AMS-Regular.woff2 differ diff --git a/fonts/KaTeX_Caligraphic-Bold.woff2 b/fonts/KaTeX_Caligraphic-Bold.woff2 new file mode 100644 index 0000000..f390922 Binary files /dev/null and b/fonts/KaTeX_Caligraphic-Bold.woff2 differ diff --git a/fonts/KaTeX_Caligraphic-Regular.woff2 b/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 0000000..75344a1 Binary files /dev/null and b/fonts/KaTeX_Caligraphic-Regular.woff2 differ diff --git a/fonts/KaTeX_Fraktur-Bold.woff2 b/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 0000000..395f28b Binary files /dev/null and b/fonts/KaTeX_Fraktur-Bold.woff2 differ diff --git a/fonts/KaTeX_Fraktur-Regular.woff2 b/fonts/KaTeX_Fraktur-Regular.woff2 new file mode 100644 index 0000000..735f694 Binary files /dev/null and b/fonts/KaTeX_Fraktur-Regular.woff2 differ diff --git a/fonts/KaTeX_Main-Bold.woff2 b/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 0000000..ab2ad21 Binary files /dev/null and b/fonts/KaTeX_Main-Bold.woff2 differ diff --git a/fonts/KaTeX_Main-BoldItalic.woff2 b/fonts/KaTeX_Main-BoldItalic.woff2 new file mode 100644 index 0000000..5931794 Binary files /dev/null and b/fonts/KaTeX_Main-BoldItalic.woff2 differ diff --git a/fonts/KaTeX_Main-Italic.woff2 b/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 0000000..b50920e Binary files /dev/null and b/fonts/KaTeX_Main-Italic.woff2 differ diff --git a/fonts/KaTeX_Main-Regular.woff2 b/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 0000000..eb24a7b Binary files /dev/null and b/fonts/KaTeX_Main-Regular.woff2 differ diff --git a/fonts/KaTeX_Math-BoldItalic.woff2 b/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 0000000..2965702 Binary files /dev/null and b/fonts/KaTeX_Math-BoldItalic.woff2 differ diff --git a/fonts/KaTeX_Math-Italic.woff2 b/fonts/KaTeX_Math-Italic.woff2 new file mode 100644 index 0000000..215c143 Binary files /dev/null and b/fonts/KaTeX_Math-Italic.woff2 differ diff --git a/fonts/KaTeX_SansSerif-Bold.woff2 b/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 0000000..cfaa3bd Binary files /dev/null and b/fonts/KaTeX_SansSerif-Bold.woff2 differ diff --git a/fonts/KaTeX_SansSerif-Italic.woff2 b/fonts/KaTeX_SansSerif-Italic.woff2 new file mode 100644 index 0000000..349c06d Binary files /dev/null and b/fonts/KaTeX_SansSerif-Italic.woff2 differ diff --git a/fonts/KaTeX_SansSerif-Regular.woff2 b/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 0000000..a90eea8 Binary files /dev/null and b/fonts/KaTeX_SansSerif-Regular.woff2 differ diff --git a/fonts/KaTeX_Script-Regular.woff2 b/fonts/KaTeX_Script-Regular.woff2 new file mode 100644 index 0000000..b3048fc Binary files /dev/null and b/fonts/KaTeX_Script-Regular.woff2 differ diff --git a/fonts/KaTeX_Size1-Regular.woff2 b/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 0000000..c5a8462 Binary files /dev/null and b/fonts/KaTeX_Size1-Regular.woff2 differ diff --git a/fonts/KaTeX_Size2-Regular.woff2 b/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 0000000..e1bccfe Binary files /dev/null and b/fonts/KaTeX_Size2-Regular.woff2 differ diff --git a/fonts/KaTeX_Size3-Regular.woff2 b/fonts/KaTeX_Size3-Regular.woff2 new file mode 100644 index 0000000..249a286 Binary files /dev/null and b/fonts/KaTeX_Size3-Regular.woff2 differ diff --git a/fonts/KaTeX_Size4-Regular.woff2 b/fonts/KaTeX_Size4-Regular.woff2 new file mode 100644 index 0000000..680c130 Binary files /dev/null and b/fonts/KaTeX_Size4-Regular.woff2 differ diff --git a/fonts/KaTeX_Typewriter-Regular.woff2 b/fonts/KaTeX_Typewriter-Regular.woff2 new file mode 100644 index 0000000..771f1af Binary files /dev/null and b/fonts/KaTeX_Typewriter-Regular.woff2 differ diff --git a/fonts/Roboto-Bold.woff2 b/fonts/Roboto-Bold.woff2 new file mode 100644 index 0000000..771fbec Binary files /dev/null and b/fonts/Roboto-Bold.woff2 differ diff --git a/fonts/Roboto-Italic.woff2 b/fonts/Roboto-Italic.woff2 new file mode 100644 index 0000000..e1b7a79 Binary files /dev/null and b/fonts/Roboto-Italic.woff2 differ diff --git a/fonts/Roboto-Mono-Italic.woff2 b/fonts/Roboto-Mono-Italic.woff2 new file mode 100644 index 0000000..ece53bd Binary files /dev/null and b/fonts/Roboto-Mono-Italic.woff2 differ diff --git a/fonts/Roboto-Mono.woff2 b/fonts/Roboto-Mono.woff2 new file mode 100644 index 0000000..f8894ba Binary files /dev/null and b/fonts/Roboto-Mono.woff2 differ diff --git a/fonts/Roboto.woff2 b/fonts/Roboto.woff2 new file mode 100644 index 0000000..020729e Binary files /dev/null and b/fonts/Roboto.woff2 differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..016287b --- /dev/null +++ b/index.html @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Guekka's blog + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + +
+ + + +
+ + + diff --git a/js/abridge.min.js b/js/abridge.min.js new file mode 100644 index 0000000..bfb6a8b --- /dev/null +++ b/js/abridge.min.js @@ -0,0 +1 @@ +let items=document.querySelectorAll(".preStyle"),changeIcon=(items.forEach(e=>{e.rel="stylesheet"}),document.getElementById("mode")&&document.getElementById("mode").addEventListener("click",()=>{document.documentElement.classList.toggle("switch"),localStorage.setItem("theme",document.documentElement.classList.contains("switch")?"switch":"default")}),!function(){for(var e=document.getElementsByClassName("m-protected"),t=0;t{e.classList.add(t),setTimeout(()=>e.classList.remove(t),2500)}),copyCodeAndChangeIcon=async(t,e)=>{e=(e.querySelector("table")?getTableCode:getNonTableCode)(e);try{await navigator.clipboard.writeText(e),changeIcon(t,"yes")}catch(e){changeIcon(t,"err")}},getNonTableCode=e=>[...e.querySelectorAll("code")].map(e=>e.textContent).join(""),getTableCode=e=>[...e.querySelectorAll("tr")].map(e=>e.querySelector("td:last-child")?.innerText??"").join("");document.querySelectorAll("pre").forEach(e=>{let t=document.createElement("div");t.className="cc svgs svgh copy",t.innerHTML=" ",e.prepend(t),t.addEventListener("click",()=>copyCodeAndChangeIcon(t,e))}),function(){function g(e){var t=new g.Index;return t.pipeline.add(g.trimmer,g.stopWordFilter,g.stemmer),e&&e.call(t,t),t}var a,c,e,t,d,h,f,p,m,v,y,S,x,b,w,I,E,C,D,F,k,L,_,N,n;g.version="0.9.5",((lunr=g).utils={}).warn=(n=this,function(e){n.console}),g.utils.toString=function(e){return null==e?"":e.toString()},(g.EventEmitter=function(){this.events={}}).prototype.addListener=function(){var e=[].slice.call(arguments),t=e.pop();if("function"!=typeof t)throw new TypeError("last argument must be a function");e.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},g.EventEmitter.prototype.removeListener=function(e,t){this.hasHandler(e)&&-1!=(t=this.events[e].indexOf(t))&&(this.events[e].splice(t,1),0==this.events[e].length)&&delete this.events[e]},g.EventEmitter.prototype.emit=function(e){var t;this.hasHandler(e)&&(t=[].slice.call(arguments,1),this.events[e].forEach(function(e){e.apply(void 0,t)},this))},g.EventEmitter.prototype.hasHandler=function(e){return e in this.events},(g.tokenizer=function(e){var t,n;return arguments.length&&null!=e?Array.isArray(e)?(t=(t=e.filter(function(e){return null!=e})).map(function(e){return g.utils.toString(e).toLowerCase()}),n=[],t.forEach(function(e){e=e.split(g.tokenizer.seperator);n=n.concat(e)},this),n):e.toString().trim().toLowerCase().split(g.tokenizer.seperator):[]}).defaultSeperator=/[\s\-]+/,g.tokenizer.seperator=g.tokenizer.defaultSeperator,g.tokenizer.setSeperator=function(e){null!=e&&"object"==typeof e&&(g.tokenizer.seperator=e)},g.tokenizer.resetSeperator=function(){g.tokenizer.seperator=g.tokenizer.defaultSeperator},g.tokenizer.getSeperator=function(){return g.tokenizer.seperator},(g.Pipeline=function(){this._queue=[]}).registeredFunctions={},g.Pipeline.registerFunction=function(e,t){t in g.Pipeline.registeredFunctions&&g.utils.warn("Overwriting existing registered function: "+t),e.label=t,g.Pipeline.registeredFunctions[t]=e},g.Pipeline.getRegisteredFunction=function(e){return e in g.Pipeline.registeredFunctions!=1?null:g.Pipeline.registeredFunctions[e]},g.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||g.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},g.Pipeline.load=function(e){var n=new g.Pipeline;return e.forEach(function(e){var t=g.Pipeline.getRegisteredFunction(e);if(!t)throw Error("Cannot load un-registered function: "+e);n.add(t)}),n},g.Pipeline.prototype.add=function(){[].slice.call(arguments).forEach(function(e){g.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},g.Pipeline.prototype.after=function(e,t){g.Pipeline.warnIfFunctionNotRegistered(t);e=this._queue.indexOf(e);if(-1==e)throw Error("Cannot find existingFn");this._queue.splice(1+e,0,t)},g.Pipeline.prototype.before=function(e,t){g.Pipeline.warnIfFunctionNotRegistered(t);e=this._queue.indexOf(e);if(-1==e)throw Error("Cannot find existingFn");this._queue.splice(e,0,t)},g.Pipeline.prototype.remove=function(e){e=this._queue.indexOf(e);-1!=e&&this._queue.splice(e,1)},g.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,o=this._queue.length,i=0;i=n&&r-1>=o;)s[n]!==u[o]?s[n]u[o]&&o++:(t.add(s[n]),n++,o++);return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){for(var t,e=this.length

'.concat(document.getElementById("searchinput").value,"

");return o.innerHTML=i,n.insertBefore(o,n.firstChild),e.innerHTML=n.outerHTML,t.innerHTML="",document.getElementById("searchinput").value="",document.body.contains(document.closeSearch)&&(document.closeSearch.onsubmit=function(){document.querySelector("main").innerHTML=window.main}),!1}function b(e){return e=parseInt(e,16).toString(2),[0,1,2,3,4][Math.ceil(e.length/8)]}var u,r,l,c,h;document.body.contains(document.goSearch)&&(document.goSearch.onsubmit=function(){return goSearchNow()},u=document.getElementById("suggestions"),r=document.getElementById("searchinput"),document.addEventListener("keydown",function(t){if(191===t.keyCode&&"INPUT"!==document.activeElement.tagName&&"TEXTAREA"!==document.activeElement.tagName&&(t.preventDefault(),r.focus(),u.classList.remove("d-none")),27===t.keyCode){r.blur(),u.classList.add("d-none");for(var e=document.getElementById("suggestions");e.firstChild;)e.removeChild(e.firstChild)}var n=u.querySelectorAll("a");if(!u.classList.contains("d-none")&&0!==n.length){var o=[...n],i=o.indexOf(document.activeElement);let e=0;38===t.keyCode?(t.preventDefault(),n[e=0",a=n.querySelector("a"),t=n.querySelector("span:first-child"),d=n.querySelector("span:nth-child(2)"),a.href=e.ref,t.textContent=e.doc.title,d.innerHTML=function(e,t){var n=t.map(function(e){return elasticlunr.stemmer(e.toLowerCase())}),o=!1,i=0,r=[],s=e.toLowerCase().split(". ");for(p in s){var u,l=s[p].split(/[\s\n]/),a=8;for(u in l){if(0<(S=l[u]).length){for(var c in n)elasticlunr.stemmer(S).startsWith(n[c])&&(a=40,o=!0);r.push([S,a,i]),a=2}i=i+S.length+1}i+=1}if(0===r.length)return void 0!==e.length&&300"),y=S[2]+S[0].length;40===S[1]||S[0].length<12||/^[\x00-\xff]+$/.test(S[0])?v.push(e.substring(S[2],y)):(x=function(e,t){for(var n="",o=!1,i=0,r=0,s=0,u=0;u")}return v.push("…"),v.join("")}(e.doc.body,s),u.appendChild(n))});i.length>r;)u.removeChild(i[0])},!0),u.addEventListener("click",function(){for(;u.lastChild;)u.removeChild(u.lastChild);return!1},!0),document.goSearch.onsubmit=e)},"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.min.js?v=3.11.0",{scope:"/"}).then(()=>{},e=>{}),navigator.serviceWorker.ready.then(()=>{})); \ No newline at end of file diff --git a/js/abridge_nopwa.min.js b/js/abridge_nopwa.min.js new file mode 100644 index 0000000..4712490 --- /dev/null +++ b/js/abridge_nopwa.min.js @@ -0,0 +1 @@ +let items=document.querySelectorAll(".preStyle"),changeIcon=(items.forEach(e=>{e.rel="stylesheet"}),document.getElementById("mode")&&document.getElementById("mode").addEventListener("click",()=>{document.documentElement.classList.toggle("switch"),localStorage.setItem("theme",document.documentElement.classList.contains("switch")?"switch":"default")}),!function(){for(var e=document.getElementsByClassName("m-protected"),t=0;t{e.classList.add(t),setTimeout(()=>e.classList.remove(t),2500)}),copyCodeAndChangeIcon=async(t,e)=>{e=(e.querySelector("table")?getTableCode:getNonTableCode)(e);try{await navigator.clipboard.writeText(e),changeIcon(t,"yes")}catch(e){changeIcon(t,"err")}},getNonTableCode=e=>[...e.querySelectorAll("code")].map(e=>e.textContent).join(""),getTableCode=e=>[...e.querySelectorAll("tr")].map(e=>e.querySelector("td:last-child")?.innerText??"").join("");document.querySelectorAll("pre").forEach(e=>{let t=document.createElement("div");t.className="cc svgs svgh copy",t.innerHTML=" ",e.prepend(t),t.addEventListener("click",()=>copyCodeAndChangeIcon(t,e))}),function(){function g(e){var t=new g.Index;return t.pipeline.add(g.trimmer,g.stopWordFilter,g.stemmer),e&&e.call(t,t),t}var a,c,e,t,d,h,f,p,m,v,y,S,x,b,w,I,E,C,D,F,k,L,_,N,n;g.version="0.9.5",((lunr=g).utils={}).warn=(n=this,function(e){n.console}),g.utils.toString=function(e){return null==e?"":e.toString()},(g.EventEmitter=function(){this.events={}}).prototype.addListener=function(){var e=[].slice.call(arguments),t=e.pop();if("function"!=typeof t)throw new TypeError("last argument must be a function");e.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},g.EventEmitter.prototype.removeListener=function(e,t){this.hasHandler(e)&&-1!=(t=this.events[e].indexOf(t))&&(this.events[e].splice(t,1),0==this.events[e].length)&&delete this.events[e]},g.EventEmitter.prototype.emit=function(e){var t;this.hasHandler(e)&&(t=[].slice.call(arguments,1),this.events[e].forEach(function(e){e.apply(void 0,t)},this))},g.EventEmitter.prototype.hasHandler=function(e){return e in this.events},(g.tokenizer=function(e){var t,n;return arguments.length&&null!=e?Array.isArray(e)?(t=(t=e.filter(function(e){return null!=e})).map(function(e){return g.utils.toString(e).toLowerCase()}),n=[],t.forEach(function(e){e=e.split(g.tokenizer.seperator);n=n.concat(e)},this),n):e.toString().trim().toLowerCase().split(g.tokenizer.seperator):[]}).defaultSeperator=/[\s\-]+/,g.tokenizer.seperator=g.tokenizer.defaultSeperator,g.tokenizer.setSeperator=function(e){null!=e&&"object"==typeof e&&(g.tokenizer.seperator=e)},g.tokenizer.resetSeperator=function(){g.tokenizer.seperator=g.tokenizer.defaultSeperator},g.tokenizer.getSeperator=function(){return g.tokenizer.seperator},(g.Pipeline=function(){this._queue=[]}).registeredFunctions={},g.Pipeline.registerFunction=function(e,t){t in g.Pipeline.registeredFunctions&&g.utils.warn("Overwriting existing registered function: "+t),e.label=t,g.Pipeline.registeredFunctions[t]=e},g.Pipeline.getRegisteredFunction=function(e){return e in g.Pipeline.registeredFunctions!=1?null:g.Pipeline.registeredFunctions[e]},g.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||g.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},g.Pipeline.load=function(e){var n=new g.Pipeline;return e.forEach(function(e){var t=g.Pipeline.getRegisteredFunction(e);if(!t)throw Error("Cannot load un-registered function: "+e);n.add(t)}),n},g.Pipeline.prototype.add=function(){[].slice.call(arguments).forEach(function(e){g.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},g.Pipeline.prototype.after=function(e,t){g.Pipeline.warnIfFunctionNotRegistered(t);e=this._queue.indexOf(e);if(-1==e)throw Error("Cannot find existingFn");this._queue.splice(1+e,0,t)},g.Pipeline.prototype.before=function(e,t){g.Pipeline.warnIfFunctionNotRegistered(t);e=this._queue.indexOf(e);if(-1==e)throw Error("Cannot find existingFn");this._queue.splice(e,0,t)},g.Pipeline.prototype.remove=function(e){e=this._queue.indexOf(e);-1!=e&&this._queue.splice(e,1)},g.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,o=this._queue.length,i=0;i=n&&r-1>=o;)s[n]!==u[o]?s[n]u[o]&&o++:(t.add(s[n]),n++,o++);return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){for(var t,e=this.length

'.concat(document.getElementById("searchinput").value,"

");return o.innerHTML=i,n.insertBefore(o,n.firstChild),e.innerHTML=n.outerHTML,t.innerHTML="",document.getElementById("searchinput").value="",document.body.contains(document.closeSearch)&&(document.closeSearch.onsubmit=function(){document.querySelector("main").innerHTML=window.main}),!1}function b(e){return e=parseInt(e,16).toString(2),[0,1,2,3,4][Math.ceil(e.length/8)]}var u,r,l,c,h;document.body.contains(document.goSearch)&&(document.goSearch.onsubmit=function(){return goSearchNow()},u=document.getElementById("suggestions"),r=document.getElementById("searchinput"),document.addEventListener("keydown",function(t){if(191===t.keyCode&&"INPUT"!==document.activeElement.tagName&&"TEXTAREA"!==document.activeElement.tagName&&(t.preventDefault(),r.focus(),u.classList.remove("d-none")),27===t.keyCode){r.blur(),u.classList.add("d-none");for(var e=document.getElementById("suggestions");e.firstChild;)e.removeChild(e.firstChild)}var n=u.querySelectorAll("a");if(!u.classList.contains("d-none")&&0!==n.length){var o=[...n],i=o.indexOf(document.activeElement);let e=0;38===t.keyCode?(t.preventDefault(),n[e=0",a=n.querySelector("a"),t=n.querySelector("span:first-child"),d=n.querySelector("span:nth-child(2)"),a.href=e.ref,t.textContent=e.doc.title,d.innerHTML=function(e,t){var n=t.map(function(e){return elasticlunr.stemmer(e.toLowerCase())}),o=!1,i=0,r=[],s=e.toLowerCase().split(". ");for(p in s){var u,l=s[p].split(/[\s\n]/),a=8;for(u in l){if(0<(S=l[u]).length){for(var c in n)elasticlunr.stemmer(S).startsWith(n[c])&&(a=40,o=!0);r.push([S,a,i]),a=2}i=i+S.length+1}i+=1}if(0===r.length)return void 0!==e.length&&300"),y=S[2]+S[0].length;40===S[1]||S[0].length<12||/^[\x00-\xff]+$/.test(S[0])?v.push(e.substring(S[2],y)):(x=function(e,t){for(var n="",o=!1,i=0,r=0,s=0,u=0;u")}return v.push("…"),v.join("")}(e.doc.body,s),u.appendChild(n))});i.length>r;)u.removeChild(i[0])},!0),u.addEventListener("click",function(){for(;u.lastChild;)u.removeChild(u.lastChild);return!1},!0),document.goSearch.onsubmit=e)}; \ No newline at end of file diff --git a/js/abridge_nosearch.min.js b/js/abridge_nosearch.min.js new file mode 100644 index 0000000..81aa5ed --- /dev/null +++ b/js/abridge_nosearch.min.js @@ -0,0 +1 @@ +let items=document.querySelectorAll(".preStyle"),changeIcon=(items.forEach(e=>{e.rel="stylesheet"}),document.getElementById("mode")&&document.getElementById("mode").addEventListener("click",()=>{document.documentElement.classList.toggle("switch"),localStorage.setItem("theme",document.documentElement.classList.contains("switch")?"switch":"default")}),!function(){for(var e=document.getElementsByClassName("m-protected"),t=0;t{e.classList.add(t),setTimeout(()=>e.classList.remove(t),2500)}),copyCodeAndChangeIcon=async(t,e)=>{e=(e.querySelector("table")?getTableCode:getNonTableCode)(e);try{await navigator.clipboard.writeText(e),changeIcon(t,"yes")}catch(e){changeIcon(t,"err")}},getNonTableCode=e=>[...e.querySelectorAll("code")].map(e=>e.textContent).join(""),getTableCode=e=>[...e.querySelectorAll("tr")].map(e=>e.querySelector("td:last-child")?.innerText??"").join("");document.querySelectorAll("pre").forEach(e=>{let t=document.createElement("div");t.className="cc svgs svgh copy",t.innerHTML=" ",e.prepend(t),t.addEventListener("click",()=>copyCodeAndChangeIcon(t,e))}),"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.min.js?v=3.11.0",{scope:"/"}).then(()=>{},e=>{}),navigator.serviceWorker.ready.then(()=>{})); \ No newline at end of file diff --git a/js/abridge_nosearch_nopwa.min.js b/js/abridge_nosearch_nopwa.min.js new file mode 100644 index 0000000..a262b38 --- /dev/null +++ b/js/abridge_nosearch_nopwa.min.js @@ -0,0 +1 @@ +let items=document.querySelectorAll(".preStyle"),changeIcon=(items.forEach(e=>{e.rel="stylesheet"}),document.getElementById("mode")&&document.getElementById("mode").addEventListener("click",()=>{document.documentElement.classList.toggle("switch"),localStorage.setItem("theme",document.documentElement.classList.contains("switch")?"switch":"default")}),!function(){for(var e=document.getElementsByClassName("m-protected"),t=0;t{e.classList.add(t),setTimeout(()=>e.classList.remove(t),2500)}),copyCodeAndChangeIcon=async(t,e)=>{e=(e.querySelector("table")?getTableCode:getNonTableCode)(e);try{await navigator.clipboard.writeText(e),changeIcon(t,"yes")}catch(e){changeIcon(t,"err")}},getNonTableCode=e=>[...e.querySelectorAll("code")].map(e=>e.textContent).join(""),getTableCode=e=>[...e.querySelectorAll("tr")].map(e=>e.querySelector("td:last-child")?.innerText??"").join("");document.querySelectorAll("pre").forEach(e=>{let t=document.createElement("div");t.className="cc svgs svgh copy",t.innerHTML=" ",e.prepend(t),t.addEventListener("click",()=>copyCodeAndChangeIcon(t,e))}); \ No newline at end of file diff --git a/js/codecopy.js b/js/codecopy.js new file mode 100644 index 0000000..9e00c79 --- /dev/null +++ b/js/codecopy.js @@ -0,0 +1,34 @@ +const changeIcon = (copyDiv, className) => { + copyDiv.classList.add(className); + setTimeout(() => copyDiv.classList.remove(className), 2500); +}; + +const copyCodeAndChangeIcon = async (copyDiv, block) => { + const code = block.querySelector('table') ? getTableCode(block) : getNonTableCode(block); + try { + await navigator.clipboard.writeText(code); + changeIcon(copyDiv, "yes"); + } catch (error) { + changeIcon(copyDiv, "err"); + } +}; + +const getNonTableCode = (block) => { + return [...block.querySelectorAll('code')] + .map(code => code.textContent) + .join(''); +}; + +const getTableCode = (block) => { + return [...block.querySelectorAll('tr')] + .map(row => row.querySelector('td:last-child')?.innerText ?? '') + .join(''); +}; + +document.querySelectorAll("pre").forEach((block) => { + const copyDiv = document.createElement("div"); + copyDiv.className = "cc svgs svgh copy"; + copyDiv.innerHTML = " "; + block.prepend(copyDiv); + copyDiv.addEventListener("click", () => copyCodeAndChangeIcon(copyDiv, block));; +}); diff --git a/js/elasticlunr.min.js b/js/elasticlunr.min.js new file mode 100644 index 0000000..79dad65 --- /dev/null +++ b/js/elasticlunr.min.js @@ -0,0 +1,10 @@ +/** + * elasticlunr - http://weixsong.github.io + * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.6 + * + * Copyright (C) 2017 Oliver Nightingale + * Copyright (C) 2017 Wei Song + * MIT Licensed + * @license + */ +!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o0&&(a.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));var l=t.findIndex((function(t){return e.startsWith(t.left)}));if(-1===(n=r(t[l].right,e,t[l].left.length)))break;var d=e.slice(0,n+t[l].right.length),s=i.test(d)?d:e.slice(t[l].left.length,n);a.push({type:"math",data:s,rawData:d,display:t[l].display}),e=e.slice(n+t[l].right.length)}return""!==e&&a.push({type:"text",data:e}),a},l=function(e,r){var n=o(e,r.delimiters);if(1===n.length&&"text"===n[0].type)return null;for(var a=document.createDocumentFragment(),i=0;i15?"\u2026"+o.slice(n-15,n):o.slice(0,n))+l+(s+15":">","<":"<",'"':""","'":"'"},o=/[&><"']/g;var s=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(o,(function(e){return i[e]}))},hyphenate:function(e){return e.replace(a,"-$1").toLowerCase()},getBaseElem:s,isCharacterBox:function(e){var t=s(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=t?t[1]:"_relative"}},h={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:function(e){return"#"+e}},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:function(e,t){return t.push(e),t}},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:function(e){return Math.max(0,e)},cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:function(e){return Math.max(0,e)},cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:function(e){return Math.max(0,e)},cli:"-e, --max-expand ",cliProcessor:function(e){return"Infinity"===e?1/0:parseInt(e)}},globalGroup:{type:"boolean",cli:!1}};function m(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}var c=function(){function e(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},h)if(h.hasOwnProperty(t)){var r=h[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:m(r)}}var t=e.prototype;return t.reportNonstrict=function(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=l.protocolFromUrl(e.url));var t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)},e}(),u=function(){function e(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}var t=e.prototype;return t.sup=function(){return p[d[this.id]]},t.sub=function(){return p[f[this.id]]},t.fracNum=function(){return p[g[this.id]]},t.fracDen=function(){return p[v[this.id]]},t.cramp=function(){return p[b[this.id]]},t.text=function(){return p[y[this.id]]},t.isTight=function(){return this.size>=2},e}(),p=[new u(0,0,!1),new u(1,0,!0),new u(2,1,!1),new u(3,1,!0),new u(4,2,!1),new u(5,2,!0),new u(6,3,!1),new u(7,3,!0)],d=[4,5,4,5,6,7,6,7],f=[5,5,5,5,7,7,7,7],g=[2,3,4,5,6,7,6,7],v=[3,3,5,5,7,7,7,7],b=[1,1,3,3,5,5,7,7],y=[0,1,2,3,2,3,2,3],x={DISPLAY:p[0],TEXT:p[2],SCRIPT:p[4],SCRIPTSCRIPT:p[6]},w=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var k=[];function S(e){for(var t=0;t=k[t]&&e<=k[t+1])return!0;return!1}w.forEach((function(e){return e.blocks.forEach((function(e){return k.push.apply(k,e)}))}));var M=80,z={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},A=function(){function e(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t=5?0:e>=3?1:2]){var r=N[t]={cssEmPerMu:B.quad[t]/18};for(var n in B)B.hasOwnProperty(n)&&(r[n]=B[n][t])}return N[t]}(this.size)),this._fontMetrics},t.getColor=function(){return this.phantom?"transparent":this.color},e}();H.BASESIZE=6;var E=H,L={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},D={ex:!0,em:!0,mu:!0},P=function(e){return"string"!=typeof e&&(e=e.unit),e in L||e in D||"ex"===e},F=function(e,t){var r;if(e.unit in L)r=L[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},V=function(e){return+e.toFixed(4)+"em"},G=function(e){return e.filter((function(e){return e})).join(" ")},U=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},Y=function(e){var t=document.createElement(e);for(var r in t.className=G(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var a=0;a"},W=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,e,r,n),this.children=t||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return Y.call(this,"span")},t.toMarkup=function(){return X.call(this,"span")},e}(),_=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return Y.call(this,"a")},t.toMarkup=function(){return X.call(this,"a")},e}(),j=function(){function e(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e},t.toMarkup=function(){var e=""+this.alt+"=a[0]&&e<=a[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=$[this.text])}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=V(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=G(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e},t.toMarkup=function(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(n)&&(r+=l.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');var a=l.escape(this.text);return e?(t+=">",t+=a,t+=""):a},e}(),K=function(){function e(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r":""},e}(),Q=function(){function e(e){this.attributes=void 0,this.attributes=e||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e},t.toMarkup=function(){var e="","\\gt",!0),ie(oe,le,be,"\u2208","\\in",!0),ie(oe,le,be,"\ue020","\\@not"),ie(oe,le,be,"\u2282","\\subset",!0),ie(oe,le,be,"\u2283","\\supset",!0),ie(oe,le,be,"\u2286","\\subseteq",!0),ie(oe,le,be,"\u2287","\\supseteq",!0),ie(oe,he,be,"\u2288","\\nsubseteq",!0),ie(oe,he,be,"\u2289","\\nsupseteq",!0),ie(oe,le,be,"\u22a8","\\models"),ie(oe,le,be,"\u2190","\\leftarrow",!0),ie(oe,le,be,"\u2264","\\le"),ie(oe,le,be,"\u2264","\\leq",!0),ie(oe,le,be,"<","\\lt",!0),ie(oe,le,be,"\u2192","\\rightarrow",!0),ie(oe,le,be,"\u2192","\\to"),ie(oe,he,be,"\u2271","\\ngeq",!0),ie(oe,he,be,"\u2270","\\nleq",!0),ie(oe,le,ye,"\xa0","\\ "),ie(oe,le,ye,"\xa0","\\space"),ie(oe,le,ye,"\xa0","\\nobreakspace"),ie(se,le,ye,"\xa0","\\ "),ie(se,le,ye,"\xa0"," "),ie(se,le,ye,"\xa0","\\space"),ie(se,le,ye,"\xa0","\\nobreakspace"),ie(oe,le,ye,null,"\\nobreak"),ie(oe,le,ye,null,"\\allowbreak"),ie(oe,le,ve,",",","),ie(oe,le,ve,";",";"),ie(oe,he,ce,"\u22bc","\\barwedge",!0),ie(oe,he,ce,"\u22bb","\\veebar",!0),ie(oe,le,ce,"\u2299","\\odot",!0),ie(oe,le,ce,"\u2295","\\oplus",!0),ie(oe,le,ce,"\u2297","\\otimes",!0),ie(oe,le,xe,"\u2202","\\partial",!0),ie(oe,le,ce,"\u2298","\\oslash",!0),ie(oe,he,ce,"\u229a","\\circledcirc",!0),ie(oe,he,ce,"\u22a1","\\boxdot",!0),ie(oe,le,ce,"\u25b3","\\bigtriangleup"),ie(oe,le,ce,"\u25bd","\\bigtriangledown"),ie(oe,le,ce,"\u2020","\\dagger"),ie(oe,le,ce,"\u22c4","\\diamond"),ie(oe,le,ce,"\u22c6","\\star"),ie(oe,le,ce,"\u25c3","\\triangleleft"),ie(oe,le,ce,"\u25b9","\\triangleright"),ie(oe,le,ge,"{","\\{"),ie(se,le,xe,"{","\\{"),ie(se,le,xe,"{","\\textbraceleft"),ie(oe,le,ue,"}","\\}"),ie(se,le,xe,"}","\\}"),ie(se,le,xe,"}","\\textbraceright"),ie(oe,le,ge,"{","\\lbrace"),ie(oe,le,ue,"}","\\rbrace"),ie(oe,le,ge,"[","\\lbrack",!0),ie(se,le,xe,"[","\\lbrack",!0),ie(oe,le,ue,"]","\\rbrack",!0),ie(se,le,xe,"]","\\rbrack",!0),ie(oe,le,ge,"(","\\lparen",!0),ie(oe,le,ue,")","\\rparen",!0),ie(se,le,xe,"<","\\textless",!0),ie(se,le,xe,">","\\textgreater",!0),ie(oe,le,ge,"\u230a","\\lfloor",!0),ie(oe,le,ue,"\u230b","\\rfloor",!0),ie(oe,le,ge,"\u2308","\\lceil",!0),ie(oe,le,ue,"\u2309","\\rceil",!0),ie(oe,le,xe,"\\","\\backslash"),ie(oe,le,xe,"\u2223","|"),ie(oe,le,xe,"\u2223","\\vert"),ie(se,le,xe,"|","\\textbar",!0),ie(oe,le,xe,"\u2225","\\|"),ie(oe,le,xe,"\u2225","\\Vert"),ie(se,le,xe,"\u2225","\\textbardbl"),ie(se,le,xe,"~","\\textasciitilde"),ie(se,le,xe,"\\","\\textbackslash"),ie(se,le,xe,"^","\\textasciicircum"),ie(oe,le,be,"\u2191","\\uparrow",!0),ie(oe,le,be,"\u21d1","\\Uparrow",!0),ie(oe,le,be,"\u2193","\\downarrow",!0),ie(oe,le,be,"\u21d3","\\Downarrow",!0),ie(oe,le,be,"\u2195","\\updownarrow",!0),ie(oe,le,be,"\u21d5","\\Updownarrow",!0),ie(oe,le,fe,"\u2210","\\coprod"),ie(oe,le,fe,"\u22c1","\\bigvee"),ie(oe,le,fe,"\u22c0","\\bigwedge"),ie(oe,le,fe,"\u2a04","\\biguplus"),ie(oe,le,fe,"\u22c2","\\bigcap"),ie(oe,le,fe,"\u22c3","\\bigcup"),ie(oe,le,fe,"\u222b","\\int"),ie(oe,le,fe,"\u222b","\\intop"),ie(oe,le,fe,"\u222c","\\iint"),ie(oe,le,fe,"\u222d","\\iiint"),ie(oe,le,fe,"\u220f","\\prod"),ie(oe,le,fe,"\u2211","\\sum"),ie(oe,le,fe,"\u2a02","\\bigotimes"),ie(oe,le,fe,"\u2a01","\\bigoplus"),ie(oe,le,fe,"\u2a00","\\bigodot"),ie(oe,le,fe,"\u222e","\\oint"),ie(oe,le,fe,"\u222f","\\oiint"),ie(oe,le,fe,"\u2230","\\oiiint"),ie(oe,le,fe,"\u2a06","\\bigsqcup"),ie(oe,le,fe,"\u222b","\\smallint"),ie(se,le,pe,"\u2026","\\textellipsis"),ie(oe,le,pe,"\u2026","\\mathellipsis"),ie(se,le,pe,"\u2026","\\ldots",!0),ie(oe,le,pe,"\u2026","\\ldots",!0),ie(oe,le,pe,"\u22ef","\\@cdots",!0),ie(oe,le,pe,"\u22f1","\\ddots",!0),ie(oe,le,xe,"\u22ee","\\varvdots"),ie(oe,le,me,"\u02ca","\\acute"),ie(oe,le,me,"\u02cb","\\grave"),ie(oe,le,me,"\xa8","\\ddot"),ie(oe,le,me,"~","\\tilde"),ie(oe,le,me,"\u02c9","\\bar"),ie(oe,le,me,"\u02d8","\\breve"),ie(oe,le,me,"\u02c7","\\check"),ie(oe,le,me,"^","\\hat"),ie(oe,le,me,"\u20d7","\\vec"),ie(oe,le,me,"\u02d9","\\dot"),ie(oe,le,me,"\u02da","\\mathring"),ie(oe,le,de,"\ue131","\\@imath"),ie(oe,le,de,"\ue237","\\@jmath"),ie(oe,le,xe,"\u0131","\u0131"),ie(oe,le,xe,"\u0237","\u0237"),ie(se,le,xe,"\u0131","\\i",!0),ie(se,le,xe,"\u0237","\\j",!0),ie(se,le,xe,"\xdf","\\ss",!0),ie(se,le,xe,"\xe6","\\ae",!0),ie(se,le,xe,"\u0153","\\oe",!0),ie(se,le,xe,"\xf8","\\o",!0),ie(se,le,xe,"\xc6","\\AE",!0),ie(se,le,xe,"\u0152","\\OE",!0),ie(se,le,xe,"\xd8","\\O",!0),ie(se,le,me,"\u02ca","\\'"),ie(se,le,me,"\u02cb","\\`"),ie(se,le,me,"\u02c6","\\^"),ie(se,le,me,"\u02dc","\\~"),ie(se,le,me,"\u02c9","\\="),ie(se,le,me,"\u02d8","\\u"),ie(se,le,me,"\u02d9","\\."),ie(se,le,me,"\xb8","\\c"),ie(se,le,me,"\u02da","\\r"),ie(se,le,me,"\u02c7","\\v"),ie(se,le,me,"\xa8",'\\"'),ie(se,le,me,"\u02dd","\\H"),ie(se,le,me,"\u25ef","\\textcircled");var we={"--":!0,"---":!0,"``":!0,"''":!0};ie(se,le,xe,"\u2013","--",!0),ie(se,le,xe,"\u2013","\\textendash"),ie(se,le,xe,"\u2014","---",!0),ie(se,le,xe,"\u2014","\\textemdash"),ie(se,le,xe,"\u2018","`",!0),ie(se,le,xe,"\u2018","\\textquoteleft"),ie(se,le,xe,"\u2019","'",!0),ie(se,le,xe,"\u2019","\\textquoteright"),ie(se,le,xe,"\u201c","``",!0),ie(se,le,xe,"\u201c","\\textquotedblleft"),ie(se,le,xe,"\u201d","''",!0),ie(se,le,xe,"\u201d","\\textquotedblright"),ie(oe,le,xe,"\xb0","\\degree",!0),ie(se,le,xe,"\xb0","\\degree"),ie(se,le,xe,"\xb0","\\textdegree",!0),ie(oe,le,xe,"\xa3","\\pounds"),ie(oe,le,xe,"\xa3","\\mathsterling",!0),ie(se,le,xe,"\xa3","\\pounds"),ie(se,le,xe,"\xa3","\\textsterling",!0),ie(oe,he,xe,"\u2720","\\maltese"),ie(se,he,xe,"\u2720","\\maltese");for(var ke='0123456789/@."',Se=0;Set&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>n&&(n=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},Xe=function(e,t,r,n){var a=new W(e,t,r,n);return Ye(a),a},We=function(e,t,r,n){return new W(e,t,r,n)},_e=function(e){var t=new A(e);return Ye(t),t},je=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},$e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ze={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Ke={fontMap:$e,makeSymbol:Ge,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Ve(e,"Main-Bold",t).metrics?Ge(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===ae[t][e].font?Ge(e,"Main-Regular",t,r,n):Ge(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:Xe,makeSvgSpan:We,makeLineSpan:function(e,t,r){var n=Xe([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=V(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){var a=new _(e,t,r,n);return Ye(a),a},makeFragment:_e,wrapFragment:function(e,t){return e instanceof A?Xe([],[e],t):e},makeVList:function(e,t){for(var r=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,a=n,i=1;i0&&(o.push(kt(s,t)),s=[]),o.push(a[l]));s.length>0&&o.push(kt(s,t)),r?((i=kt(ft(r,t,!0))).classes=["tag"],o.push(i)):n&&o.push(n);var m=mt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=V(m.height+m.depth),m.depth&&(c.style.verticalAlign=V(-m.depth))}return m}function Mt(e){return new A(e)}var zt=function(){function e(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.getAttribute=function(e){return this.attributes[e]},t.toNode=function(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=G(this.classes));for(var r=0;r0&&(e+=' class ="'+l.escape(G(this.classes))+'"'),e+=">";for(var r=0;r"},t.toText=function(){return this.children.map((function(e){return e.toText()})).join("")},e}(),At=function(){function e(e){this.text=void 0,this.text=e}var t=e.prototype;return t.toNode=function(){return document.createTextNode(this.text)},t.toMarkup=function(){return l.escape(this.toText())},t.toText=function(){return this.text},e}(),Tt={MathNode:zt,TextNode:At,SpaceNode:function(){function e(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}var t=e.prototype;return t.toNode=function(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",V(this.width)),e},t.toMarkup=function(){return this.character?""+this.character+"":''},t.toText=function(){return this.character?this.character:" "},e}(),newDocumentFragment:Mt},Bt=function(e,t,r){return!ae[t][e]||!ae[t][e].replace||55349===e.charCodeAt(0)||we.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(e=ae[t][e].replace),new Tt.TextNode(e)},Ct=function(e){return 1===e.length?e[0]:new Tt.MathNode("mrow",e)},qt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var a=e.text;return l.contains(["\\imath","\\jmath"],a)?null:(ae[n][a]&&ae[n][a].replace&&(a=ae[n][a].replace),q(a,Ke.fontMap[r].fontName,n)?Ke.fontMap[r].variant:null)},Nt=function(e,t,r){if(1===e.length){var n=Rt(e[0],t);return r&&n instanceof zt&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var a,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),a=s}return i},It=function(e,t,r){return Ct(Nt(e,t,r))},Rt=function(e,t){if(!e)return new Tt.MathNode("mrow");if(it[e.type])return it[e.type](e,t);throw new n("Got group of unknown type: '"+e.type+"'")};function Ot(e,t,r,n,a){var i,o=Nt(e,r);i=1===o.length&&o[0]instanceof zt&&l.contains(["mrow","mtable"],o[0].type)?o[0]:new Tt.MathNode("mrow",o);var s=new Tt.MathNode("annotation",[new Tt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var h=new Tt.MathNode("semantics",[i,s]),m=new Tt.MathNode("math",[h]);m.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&m.setAttribute("display","block");var c=a?"katex":"katex-mathml";return Ke.makeSpan([c],[m])}var Ht=function(e){return new E({style:e.displayMode?x.DISPLAY:x.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Et=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Ke.makeSpan(r,[e])}return e},Lt=function(e,t,r){var n,a=Ht(r);if("mathml"===r.output)return Ot(e,t,a,r.displayMode,!0);if("html"===r.output){var i=St(e,a);n=Ke.makeSpan(["katex"],[i])}else{var o=Ot(e,t,a,r.displayMode,!1),s=St(e,a);n=Ke.makeSpan(["katex"],[o,s])}return Et(n,r)},Dt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Pt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Ft=function(e,t,r,n,a){var i,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(i=Ke.makeSpan(["stretchy",t],[],a),"fbox"===t){var s=a.color&&a.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new Q({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new Q({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new K(l,{width:"100%",height:V(o)});i=Ke.makeSvgSpan([],[h],a)}return i.height=o,i.style.height=V(o),i},Vt=function(e){var t=new Tt.MathNode("mo",[new Tt.TextNode(Dt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Gt=function(e,t){var r=function(){var r=4e5,n=e.label.substr(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){var a,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===n||"widecheck"===n?(a=420,r=2364,o=.42,i=n+"4"):(a=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][h],a=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=n+h):(r=[0,600,1033,2339,2340][h],a=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var m=new J(i),c=new K([m],{width:"100%",height:V(o),viewBox:"0 0 "+r+" "+a,preserveAspectRatio:"none"});return{span:Ke.makeSvgSpan([],[c],t),minWidth:0,height:o}}var u,p,d,f=[],g=Pt[n],v=g[0],b=g[1],y=g[2],x=y/1e3,w=v.length;if(1===w)u=["hide-tail"],p=[g[3]];else if(2===w)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(n.style.minWidth=V(a)),n};function Ut(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Yt(e){var t=Xt(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Xt(e){return e&&("atom"===e.type||re.hasOwnProperty(e.type))?e:null}var Wt=function(e,t){var r,n,a;e&&"supsub"===e.type?(r=(n=Ut(e.base,"accent")).base,e.base=r,a=function(e){if(e instanceof W)return e;throw new Error("Expected span but got "+String(e)+".")}(wt(e,t)),e.base=n):r=(n=Ut(e,"accent")).base;var i=wt(r,t.havingCrampedStyle()),o=0;if(n.isShifty&&l.isCharacterBox(r)){var s=l.getBaseElem(r);o=ee(wt(s,t.havingCrampedStyle())).skew}var h,m="\\c"===n.label,c=m?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(n.isStretchy)h=Gt(n,t),h=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+V(2*o)+")",marginLeft:V(2*o)}:void 0}]},t);else{var u,p;"\\vec"===n.label?(u=Ke.staticSvg("vec",t),p=Ke.svgData.vec[1]):((u=ee(u=Ke.makeOrd({mode:n.mode,text:n.label},t,"textord"))).italic=0,p=u.width,m&&(c+=u.depth)),h=Ke.makeSpan(["accent-body"],[u]);var d="\\textcircled"===n.label;d&&(h.classes.push("accent-full"),c=i.height);var f=o;d||(f-=p/2),h.style.left=V(f),"\\textcircled"===n.label&&(h.style.top=".2em"),h=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}var g=Ke.makeSpan(["mord","accent"],[h],t);return a?(a.children[0]=g,a.height=Math.max(g.height,a.height),a.classes[0]="mord",a):g},_t=function(e,t){var r=e.isStretchy?Vt(e.label):new Tt.MathNode("mo",[Bt(e.label,e.mode)]),n=new Tt.MathNode("mover",[Rt(e.base,t),r]);return n.setAttribute("accent","true"),n},jt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((function(e){return"\\"+e})).join("|"));ot({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var r=lt(t[0]),n=!jt.test(e.funcName),a=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:a,base:r}},htmlBuilder:Wt,mathmlBuilder:_t}),ot({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var r=t[0],n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Wt,mathmlBuilder:_t}),ot({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:a}},htmlBuilder:function(e,t){var r=wt(e.base,t),n=Gt(e,t),a="\\utilde"===e.label?.12:0,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:a},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:function(e,t){var r=Vt(e.label),n=new Tt.MathNode("munder",[Rt(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var $t=function(e){var t=new Tt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};ot({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,a=e.funcName;return{type:"xArrow",mode:n.mode,label:a,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r,n=t.style,a=t.havingStyle(n.sup()),i=Ke.wrapFragment(wt(e.body,a,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(a=t.havingStyle(n.sub()),(r=Ke.wrapFragment(wt(e.below,a,t),t)).classes.push(o+"-arrow-pad"));var s,l=Gt(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),Ke.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder:function(e,t){var r,n=Vt(e.label);if(n.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var a=$t(Rt(e.body,t));if(e.below){var i=$t(Rt(e.below,t));r=new Tt.MathNode("munderover",[n,i,a])}else r=new Tt.MathNode("mover",[n,a])}else if(e.below){var o=$t(Rt(e.below,t));r=new Tt.MathNode("munder",[n,o])}else r=$t(),r=new Tt.MathNode("mover",[n,r]);return r}});var Zt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},Kt=function(e){return"textord"===e.type&&"@"===e.text};function Jt(e,t,r){var n=Zt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var a={type:"atom",text:n,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[a],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}ot({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),n=Ke.wrapFragment(wt(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=V(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mrow",[Rt(e.label,t)]);return(r=new Tt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new Tt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),ot({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){var r=Ke.wrapFragment(wt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:function(e,t){return new Tt.MathNode("mrow",[Rt(e.fragment,t)])}}),ot({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var r=e.parser,a=Ut(t[0],"ordgroup").body,i="",o=0;o=1114111)throw new n("\\@char with invalid code point "+i);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var Qt=function(e,t){var r=ft(e.body,t.withColor(e.color),!1);return Ke.makeFragment(r)},er=function(e,t){var r=Nt(e.body,t.withColor(e.color)),n=new Tt.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};ot({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var r=e.parser,n=Ut(t[0],"color-token").color,a=t[1];return{type:"color",mode:r.mode,color:n,body:ht(a)}},htmlBuilder:Qt,mathmlBuilder:er}),ot({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,n=e.breakOnTokenText,a=Ut(t[0],"color-token").color;r.gullet.macros.set("\\current@color",a);var i=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:a,body:i}},htmlBuilder:Qt,mathmlBuilder:er}),ot({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=r[0],i=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:i,size:a&&Ut(a,"size").value}},htmlBuilder:function(e,t){var r=Ke.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=V(F(e.size,t)))),r},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",V(F(e.size,t)))),r}});var tr={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},rr=function(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},nr=function(e,t,r,n){var a=e.gullet.macros.get(r.text);null==a&&(r.noexpand=!0,a={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,a,n)};ot({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,r=e.funcName;t.consumeSpaces();var a=t.fetch();if(tr[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=tr[a.text]),Ut(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",a)}}),ot({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,a=t.gullet.popToken(),i=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new n("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new n('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new n('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new n("Expected a macro definition");l[s].push(a.text)}var h=t.gullet.consumeArg().tokens;return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(i,{tokens:h,numArgs:s,delimiters:l},r===tr[r]),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=rr(t.gullet.popToken());t.gullet.consumeSpaces();var a=function(e){var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t}(t);return nr(t,n,a,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=rr(t.gullet.popToken()),a=t.gullet.popToken(),i=t.gullet.popToken();return nr(t,n,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(a),{type:"internal",mode:t.mode}}});var ar=function(e,t,r){var n=q(ae.math[e]&&ae.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},ir=function(e,t,r,n){var a=r.havingBaseStyle(t),i=Ke.makeSpan(n.concat(a.sizingClasses(r)),[e],r),o=a.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=a.sizeMultiplier,i},or=function(e,t,r){var n=t.havingBaseStyle(r),a=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=V(a),e.height-=a,e.depth+=a},sr=function(e,t,r,n,a,i){var o=function(e,t,r,n){return Ke.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,a,n),s=ir(Ke.makeSpan(["delimsizing","size"+t],[o],n),x.TEXT,n,i);return r&&or(s,n,x.TEXT),s},lr=function(e,t,r){var n;return n="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:Ke.makeSpan(["delimsizinginner",n],[Ke.makeSpan([],[Ke.makeSymbol(e,t,r)])])}},hr=function(e,t,r){var n=T["Size4-Regular"][e.charCodeAt(0)]?T["Size4-Regular"][e.charCodeAt(0)][4]:T["Size1-Regular"][e.charCodeAt(0)][4],a=new J("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new K([a],{width:V(n),height:V(t),style:"width:"+V(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=Ke.makeSvgSpan([],[i],r);return o.height=t,o.style.height=V(t),o.style.width=V(n),{type:"elem",elem:o}},mr={type:"kern",size:-.008},cr=["|","\\lvert","\\rvert","\\vert"],ur=["\\|","\\lVert","\\rVert","\\Vert"],pr=function(e,t,r,n,a,i){var o,s,h,m;o=h=m=e,s=null;var c="Size1-Regular";"\\uparrow"===e?h=m="\u23d0":"\\Uparrow"===e?h=m="\u2016":"\\downarrow"===e?o=h="\u23d0":"\\Downarrow"===e?o=h="\u2016":"\\updownarrow"===e?(o="\\uparrow",h="\u23d0",m="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",h="\u2016",m="\\Downarrow"):l.contains(cr,e)?h="\u2223":l.contains(ur,e)?h="\u2225":"["===e||"\\lbrack"===e?(o="\u23a1",h="\u23a2",m="\u23a3",c="Size4-Regular"):"]"===e||"\\rbrack"===e?(o="\u23a4",h="\u23a5",m="\u23a6",c="Size4-Regular"):"\\lfloor"===e||"\u230a"===e?(h=o="\u23a2",m="\u23a3",c="Size4-Regular"):"\\lceil"===e||"\u2308"===e?(o="\u23a1",h=m="\u23a2",c="Size4-Regular"):"\\rfloor"===e||"\u230b"===e?(h=o="\u23a5",m="\u23a6",c="Size4-Regular"):"\\rceil"===e||"\u2309"===e?(o="\u23a4",h=m="\u23a5",c="Size4-Regular"):"("===e||"\\lparen"===e?(o="\u239b",h="\u239c",m="\u239d",c="Size4-Regular"):")"===e||"\\rparen"===e?(o="\u239e",h="\u239f",m="\u23a0",c="Size4-Regular"):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",m="\u23a9",h="\u23aa",c="Size4-Regular");var u=ar(o,c,a),p=u.height+u.depth,d=ar(h,c,a),f=d.height+d.depth,g=ar(m,c,a),v=g.height+g.depth,b=0,y=1;if(null!==s){var w=ar(s,c,a);b=w.height+w.depth,y=2}var k=p+v+b,S=k+Math.max(0,Math.ceil((t-k)/(y*f)))*y*f,M=n.fontMetrics().axisHeight;r&&(M*=n.sizeMultiplier);var z=S/2-M,A=[];if(A.push(lr(m,c,a)),A.push(mr),null===s){var T=S-p-v+.016;A.push(hr(h,T,n))}else{var B=(S-p-v-b)/2+.016;A.push(hr(h,B,n)),A.push(mr),A.push(lr(s,c,a)),A.push(mr),A.push(hr(h,B,n))}A.push(mr),A.push(lr(o,c,a));var C=n.havingBaseStyle(x.TEXT),q=Ke.makeVList({positionType:"bottom",positionData:z,children:A},C);return ir(Ke.makeSpan(["delimsizing","mult"],[q],C),x.TEXT,n,i)},dr=.08,fr=function(e,t,r,n,a){var i=function(e,t,r){t*=1e3;var n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,M);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,M,r)}return n}(e,n,r),o=new J(e,i),s=new K([o],{width:"400em",height:V(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Ke.makeSvgSpan(["hide-tail"],[s],a)},gr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],vr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],br=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],yr=[0,1.2,1.8,2.4,3],xr=[{type:"small",style:x.SCRIPTSCRIPT},{type:"small",style:x.SCRIPT},{type:"small",style:x.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],wr=[{type:"small",style:x.SCRIPTSCRIPT},{type:"small",style:x.SCRIPT},{type:"small",style:x.TEXT},{type:"stack"}],kr=[{type:"small",style:x.SCRIPTSCRIPT},{type:"small",style:x.SCRIPT},{type:"small",style:x.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Sr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},Mr=function(e,t,r,n){for(var a=Math.min(2,3-n.style.size);at)return r[a]}return r[r.length-1]},zr=function(e,t,r,n,a,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=l.contains(br,e)?xr:l.contains(gr,e)?kr:wr;var s=Mr(e,t,o,n);return"small"===s.type?function(e,t,r,n,a,i){var o=Ke.makeSymbol(e,"Main-Regular",a,n),s=ir(o,t,n,i);return r&&or(s,n,t),s}(e,s.style,r,n,a,i):"large"===s.type?sr(e,s.size,r,n,a,i):pr(e,t,r,n,a,i)},Ar={sqrtImage:function(e,t){var r,n,a=t.havingBaseSizing(),i=Mr("\\surd",e*a.sizeMultiplier,kr,a),o=a.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=fr("sqrtMain",l=(1+s+dr)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",n=.833/o):"large"===i.type?(m=1080*yr[i.size],h=(yr[i.size]+s)/o,l=(yr[i.size]+s+dr)/o,(r=fr("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",n=1/o):(l=e+s+dr,h=e+s,m=Math.floor(1e3*e+s)+80,(r=fr("sqrtTall",l,m,s,t)).style.minWidth="0.742em",n=1.056),r.height=h,r.style.height=V(l),{span:r,advanceWidth:n,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,i){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(gr,e)||l.contains(br,e))return sr(e,t,!1,r,a,i);if(l.contains(vr,e))return pr(e,yr[t],!1,r,a,i);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:yr,customSizedDelim:zr,leftRightDelim:function(e,t,r,n,a,i){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return zr(e,h,!0,n,a,i)}},Tr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Br=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Cr(e,t){var r=Xt(e);if(r&&l.contains(Br,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function qr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}ot({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){var r=Cr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:Tr[e.funcName].size,mclass:Tr[e.funcName].mclass,delim:r.text}},htmlBuilder:function(e,t){return"."===e.delim?Ke.makeSpan([e.mclass]):Ar.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[];"."!==e.delim&&t.push(Bt(e.delim,e.mode));var r=new Tt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=V(Ar.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),ot({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Cr(t[0],e).text,color:r}}}),ot({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=Cr(t[0],e),n=e.parser;++n.leftrightDepth;var a=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var i=Ut(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:a,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(e,t){qr(e);for(var r,n,a=ft(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l-1?"mpadded":"menclose",[Rt(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var a=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+a+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};ot({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Ut(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:n.mode,label:a,backgroundColor:i,body:o}},htmlBuilder:Nr,mathmlBuilder:Ir}),ot({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Ut(t[0],"color-token").color,o=Ut(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:a,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:Nr,mathmlBuilder:Ir}),ot({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\fbox",body:t[0]}}}),ot({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"enclose",mode:r.mode,label:n,body:a}},htmlBuilder:Nr,mathmlBuilder:Ir}),ot({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\angl",body:t[0]}}});var Rr={};function Or(e){for(var t=e.type,r=e.names,n=e.props,a=e.handler,i=e.htmlBuilder,o=e.mathmlBuilder,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:a},l=0;l1||!c)&&g.pop(),b.length0&&(y+=.25),m.push({pos:y,isDashed:e[t]})}for(w(o[0]),r=0;r0&&(M<(B+=b)&&(M=B),B=0),e.addJot&&(M+=f),z.height=S,z.depth=M,y+=S,z.pos=y,y+=M+B,h[r]=z,w(o[r+1])}var C,q,N=y/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],O=[];if(e.tags&&e.tags.some((function(e){return e})))for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=l.deflt(P.pregap,p))&&((C=Ke.makeSpan(["arraycolsep"],[])).style.width=V(W),R.push(C));var _=[];for(r=0;r0){for(var K=Ke.makeLineSpan("hline",t,c),J=Ke.makeLineSpan("hdashline",t,c),Q=[{type:"elem",elem:h,shift:0}];m.length>0;){var ee=m.pop(),te=ee.pos-N;ee.isDashed?Q.push({type:"elem",elem:J,shift:te}):Q.push({type:"elem",elem:K,shift:te})}h=Ke.makeVList({positionType:"individualShift",children:Q},t)}if(0===O.length)return Ke.makeSpan(["mord"],[h],t);var re=Ke.makeVList({positionType:"individualShift",children:O},t);return re=Ke.makeSpan(["tag"],[re],t),Ke.makeFragment([h,re])},Xr={c:"center ",l:"left ",r:"right "},Wr=function(e,t){for(var r=[],n=new Tt.MathNode("mtd",[],["mtr-glue"]),a=new Tt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var p=e.cols,d="",f=!1,g=0,v=p.length;"separator"===p[0].type&&(c+="top ",g=1),"separator"===p[p.length-1].type&&(c+="bottom ",v-=1);for(var b=g;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o="split"===e.envName,s=Gr(e.parser,{cols:a,addJot:!0,autoTag:o?void 0:Vr(e.envName),emptySingleRow:!0,colSeparationType:i,maxNumCols:o?2:void 0,leqno:e.parser.settings.leqno},"display"),l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var m="",c=0;c0&&u&&(f=1),a[p]={type:"align",align:d,pregap:f,postgap:0}}return s.colSeparationType=u?"align":"alignat",s};Or({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(e,t){var r=(Xt(t[0])?[t[0]]:Ut(t[0],"ordgroup").body).map((function(e){var t=Yt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Gr(e.parser,a,Ur(e.envName))},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler:function(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var i=e.parser;if(i.consumeSpaces(),"["===i.fetch().text){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),a.cols=[{type:"align",align:r}]}}var o=Gr(e.parser,a,Ur(e.envName)),s=Math.max.apply(Math,[0].concat(o.body.map((function(e){return e.length}))));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(e){var t=Gr(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["subarray"],props:{numArgs:1},handler:function(e,t){var r=(Xt(t[0])?[t[0]]:Ut(t[0],"ordgroup").body).map((function(e){var t=Yt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Gr(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new n("{subarray} can contain only one column");return a},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(e){var t=Gr(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Ur(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:_r,htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler:function(e){l.contains(["gather","gather*"],e.envName)&&Fr(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Vr(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Gr(e.parser,t,"display")},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:_r,htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["equation","equation*"],props:{numArgs:0},handler:function(e){Fr(e);var t={autoTag:Vr(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Gr(e.parser,t,"display")},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["CD"],props:{numArgs:0},handler:function(e){return Fr(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,i,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(u)>-1))throw new n('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var f=!0,g=c+1;g=x.SCRIPT.id?r.text():x.DISPLAY:"text"===e&&r.size===x.DISPLAY.size?r=x.TEXT:"script"===e?r=x.SCRIPT:"scriptscript"===e&&(r=x.SCRIPTSCRIPT),r},nn=function(e,t){var r,n=rn(e.size,t.style),a=n.fracNum(),i=n.fracDen();r=t.havingStyle(a);var o=wt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(u=t.fontMetrics().num2,p=c):(u=t.fontMetrics().num3,p=3*c),d=t.fontMetrics().denom2),h){var w=t.fontMetrics().axisHeight;u-o.depth-(w+.5*m)0&&(t="."===(t=e)?null:t),t};ot({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler:function(e,t){var r,n=e.parser,a=t[4],i=t[5],o=lt(t[0]),s="atom"===o.type&&"open"===o.family?sn(o.text):null,l=lt(t[1]),h="atom"===l.type&&"close"===l.family?sn(l.text):null,m=Ut(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var u="auto",p=t[3];if("ordgroup"===p.type){if(p.body.length>0){var d=Ut(p.body[0],"textord");u=on[Number(d.text)]}}else p=Ut(p,"textord"),u=on[Number(p.text)];return{type:"genfrac",mode:n.mode,numer:a,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:u}},htmlBuilder:nn,mathmlBuilder:an}),ot({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(e,t){var r=e.parser,n=(e.funcName,e.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Ut(t[0],"size").value,token:n}}}),ot({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(e,t){var r=e.parser,n=(e.funcName,t[0]),a=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Ut(t[1],"infix").size),i=t[2],o=a.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:o,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:nn,mathmlBuilder:an});var ln=function(e,t){var r,n,a=t.style;"supsub"===e.type?(r=e.sup?wt(e.sup,t.havingStyle(a.sup()),t):wt(e.sub,t.havingStyle(a.sub()),t),n=Ut(e.base,"horizBrace")):n=Ut(e,"horizBrace");var i,o=wt(n.base,t.havingBaseStyle(x.DISPLAY)),s=Gt(n,t);if(n.isOver?(i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=Ke.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Ke.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t);i=n.isOver?Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):Ke.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return Ke.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t)};ot({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:ln,mathmlBuilder:function(e,t){var r=Vt(e.label);return new Tt.MathNode(e.isOver?"mover":"munder",[Rt(e.base,t),r])}}),ot({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=t[1],a=Ut(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:a})?{type:"href",mode:r.mode,href:a,body:ht(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(e,t){var r=ft(e.body,t,!1);return Ke.makeAnchor(e.href,[],r,t)},mathmlBuilder:function(e,t){var r=It(e.body,t);return r instanceof zt||(r=new zt("mrow",[r])),r.setAttribute("href",e.href),r}}),ot({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=Ut(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var a=[],i=0;i0&&(n=F(e.totalheight,t)-r);var a=0;e.width.number>0&&(a=F(e.width,t));var i={height:V(r+n)};a>0&&(i.width=V(a)),n>0&&(i.verticalAlign=V(-n));var o=new j(e.src,e.alt,i);return o.height=r,o.depth=n,o},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=F(e.height,t),a=0;if(e.totalheight.number>0&&(a=F(e.totalheight,t)-n,r.setAttribute("valign",V(-a))),r.setAttribute("height",V(n+a)),e.width.number>0){var i=F(e.width,t);r.setAttribute("width",V(i))}return r.setAttribute("src",e.src),r}}),ot({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=Ut(t[0],"size");if(r.settings.strict){var i="m"===n[1],o="mu"===a.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+a.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:a.value}},htmlBuilder:function(e,t){return Ke.makeGlue(e.dimension,t)},mathmlBuilder:function(e,t){var r=F(e.dimension,t);return new Tt.SpaceNode(r)}}),ot({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:a}},htmlBuilder:function(e,t){var r;"clap"===e.alignment?(r=Ke.makeSpan([],[wt(e.body,t)]),r=Ke.makeSpan(["inner"],[r],t)):r=Ke.makeSpan(["inner"],[wt(e.body,t)]);var n=Ke.makeSpan(["fix"],[]),a=Ke.makeSpan([e.alignment],[r,n],t),i=Ke.makeSpan(["strut"]);return i.style.height=V(a.height+a.depth),a.depth&&(i.style.verticalAlign=V(-a.depth)),a.children.unshift(i),a=Ke.makeSpan(["thinbox"],[a],t),Ke.makeSpan(["mord","vbox"],[a],t)},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);if("rlap"!==e.alignment){var n="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}}),ot({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){var r=e.funcName,n=e.parser,a=n.mode;n.switchMode("math");var i="\\("===r?"\\)":"$",o=n.parseExpression(!1,i);return n.expect(i),n.switchMode(a),{type:"styling",mode:n.mode,style:"text",body:o}}}),ot({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){throw new n("Mismatched "+e.funcName)}});var mn=function(e,t){switch(t.style.size){case x.DISPLAY.size:return e.display;case x.TEXT.size:return e.text;case x.SCRIPT.size:return e.script;case x.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};ot({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:function(e,t){return{type:"mathchoice",mode:e.parser.mode,display:ht(t[0]),text:ht(t[1]),script:ht(t[2]),scriptscript:ht(t[3])}},htmlBuilder:function(e,t){var r=mn(e,t),n=ft(r,t,!1);return Ke.makeFragment(n)},mathmlBuilder:function(e,t){var r=mn(e,t);return It(r,t)}});var cn=function(e,t,r,n,a,i,o){e=Ke.makeSpan([],[e]);var s,h,m,c=r&&l.isCharacterBox(r);if(t){var u=wt(t,n.havingStyle(a.sup()),n);h={elem:u,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-u.depth)}}if(r){var p=wt(r,n.havingStyle(a.sub()),n);s={elem:p,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-p.height)}}if(h&&s){var d=n.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;m=Ke.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:V(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(s){var f=e.height-o;m=Ke.makeVList({positionType:"top",positionData:f,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:V(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},n)}else{if(!h)return e;var g=e.depth+o;m=Ke.makeVList({positionType:"bottom",positionData:g,children:[{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}var v=[m];if(s&&0!==i&&!c){var b=Ke.makeSpan(["mspace"],[],n);b.style.marginRight=V(i),v.unshift(b)}return Ke.makeSpan(["mop","op-limits"],v,n)},un=["\\smallint"],pn=function(e,t){var r,n,a,i=!1;"supsub"===e.type?(r=e.sup,n=e.sub,a=Ut(e.base,"op"),i=!0):a=Ut(e,"op");var o,s=t.style,h=!1;if(s.size===x.DISPLAY.size&&a.symbol&&!l.contains(un,a.name)&&(h=!0),a.symbol){var m=h?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==a.name&&"\\oiiint"!==a.name||(c=a.name.substr(1),a.name="oiint"===c?"\\iint":"\\iiint"),o=Ke.makeSymbol(a.name,m,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),c.length>0){var u=o.italic,p=Ke.staticSvg(c+"Size"+(h?"2":"1"),t);o=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:h?.08:0}]},t),a.name="\\"+c,o.classes.unshift("mop"),o.italic=u}}else if(a.body){var d=ft(a.body,t,!0);1===d.length&&d[0]instanceof Z?(o=d[0]).classes[0]="mop":o=Ke.makeSpan(["mop"],d,t)}else{for(var f=[],g=1;g0){for(var s=a.body.map((function(e){var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=ft(s,t.withFont("mathrm"),!0),h=0;h=0?s.setAttribute("height",V(a)):(s.setAttribute("height",V(a)),s.setAttribute("depth",V(-a))),s.setAttribute("voffset",V(a)),s}});var yn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];ot({type:"sizing",names:yn,props:{numArgs:0,allowedInText:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!1,r);return{type:"sizing",mode:a.mode,size:yn.indexOf(n)+1,body:i}},htmlBuilder:function(e,t){var r=t.havingSize(e.size);return bn(e.body,r,t)},mathmlBuilder:function(e,t){var r=t.havingSize(e.size),n=Nt(e.body,r),a=new Tt.MathNode("mstyle",n);return a.setAttribute("mathsize",V(r.sizeMultiplier)),a}}),ot({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=!1,i=!1,o=r[0]&&Ut(r[0],"ordgroup");if(o)for(var s="",l=0;lr.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=V(m);var p=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},t);if(e.index){var d=t.havingStyle(x.SCRIPTSCRIPT),f=wt(e.index,d,t),g=.6*(p.height-p.depth),v=Ke.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},t),b=Ke.makeSpan(["root"],[v]);return Ke.makeSpan(["mord","sqrt"],[b,p],t)}return Ke.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder:function(e,t){var r=e.body,n=e.index;return n?new Tt.MathNode("mroot",[Rt(r,t),Rt(n,t)]):new Tt.MathNode("msqrt",[Rt(r,t)])}});var xn={display:x.DISPLAY,text:x.TEXT,script:x.SCRIPT,scriptscript:x.SCRIPTSCRIPT};ot({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!0,r),o=n.slice(1,n.length-5);return{type:"styling",mode:a.mode,style:o,body:i}},htmlBuilder:function(e,t){var r=xn[e.style],n=t.havingStyle(r).withFont("");return bn(e.body,n,t)},mathmlBuilder:function(e,t){var r=xn[e.style],n=t.havingStyle(r),a=Nt(e.body,n),i=new Tt.MathNode("mstyle",a),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});var wn=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===x.DISPLAY.size||r.alwaysHandleSupSub)?pn:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===x.DISPLAY.size||r.limits)?vn:null:"accent"===r.type?l.isCharacterBox(r.base)?Wt:null:"horizBrace"===r.type&&!e.sub===r.isOver?ln:null:null};st({type:"supsub",htmlBuilder:function(e,t){var r=wn(e,t);if(r)return r(e,t);var n,a,i,o=e.base,s=e.sup,h=e.sub,m=wt(o,t),c=t.fontMetrics(),u=0,p=0,d=o&&l.isCharacterBox(o);if(s){var f=t.havingStyle(t.style.sup());n=wt(s,f,t),d||(u=m.height-f.fontMetrics().supDrop*f.sizeMultiplier/t.sizeMultiplier)}if(h){var g=t.havingStyle(t.style.sub());a=wt(h,g,t),d||(p=m.depth+g.fontMetrics().subDrop*g.sizeMultiplier/t.sizeMultiplier)}i=t.style===x.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,b=t.sizeMultiplier,y=V(.5/c.ptPerEm/b),w=null;if(a){var k=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(m instanceof Z||k)&&(w=V(-m.italic))}if(n&&a){u=Math.max(u,i,n.depth+.25*c.xHeight),p=Math.max(p,c.sub2);var S=4*c.defaultRuleThickness;if(u-n.depth-(a.height-p)0&&(u+=M,p-=M)}var z=[{type:"elem",elem:a,shift:p,marginRight:y,marginLeft:w},{type:"elem",elem:n,shift:-u,marginRight:y}];v=Ke.makeVList({positionType:"individualShift",children:z},t)}else if(a){p=Math.max(p,c.sub1,a.height-.8*c.xHeight);var A=[{type:"elem",elem:a,marginLeft:w,marginRight:y}];v=Ke.makeVList({positionType:"shift",positionData:p,children:A},t)}else{if(!n)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,n.depth+.25*c.xHeight),v=Ke.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:n,marginRight:y}]},t)}var T=yt(m,"right")||"mord";return Ke.makeSpan([T],[m,Ke.makeSpan(["msupsub"],[v])],t)},mathmlBuilder:function(e,t){var r,n=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(n=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var a,i=[Rt(e.base,t)];if(e.sub&&i.push(Rt(e.sub,t)),e.sup&&i.push(Rt(e.sup,t)),n)a=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;a=o&&"op"===o.type&&o.limits&&t.style===x.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===x.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;a=s&&"op"===s.type&&s.limits&&(t.style===x.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===x.DISPLAY)?"munder":"msub"}else{var l=e.base;a=l&&"op"===l.type&&l.limits&&(t.style===x.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===x.DISPLAY)?"mover":"msup"}return new Tt.MathNode(a,i)}}),st({type:"atom",htmlBuilder:function(e,t){return Ke.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mo",[Bt(e.text,e.mode)]);if("bin"===e.family){var n=qt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var kn={mi:"italic",mn:"normal",mtext:"normal"};st({type:"mathord",htmlBuilder:function(e,t){return Ke.makeOrd(e,t,"mathord")},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mi",[Bt(e.text,e.mode,t)]),n=qt(e,t)||"italic";return n!==kn[r.type]&&r.setAttribute("mathvariant",n),r}}),st({type:"textord",htmlBuilder:function(e,t){return Ke.makeOrd(e,t,"textord")},mathmlBuilder:function(e,t){var r,n=Bt(e.text,e.mode,t),a=qt(e,t)||"normal";return r="text"===e.mode?new Tt.MathNode("mtext",[n]):/[0-9]/.test(e.text)?new Tt.MathNode("mn",[n]):"\\prime"===e.text?new Tt.MathNode("mo",[n]):new Tt.MathNode("mi",[n]),a!==kn[r.type]&&r.setAttribute("mathvariant",a),r}});var Sn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Mn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};st({type:"spacing",htmlBuilder:function(e,t){if(Mn.hasOwnProperty(e.text)){var r=Mn[e.text].className||"";if("text"===e.mode){var a=Ke.makeOrd(e,t,"textord");return a.classes.push(r),a}return Ke.makeSpan(["mspace",r],[Ke.mathsym(e.text,e.mode,t)],t)}if(Sn.hasOwnProperty(e.text))return Ke.makeSpan(["mspace",Sn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder:function(e,t){if(!Mn.hasOwnProperty(e.text)){if(Sn.hasOwnProperty(e.text))return new Tt.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return new Tt.MathNode("mtext",[new Tt.TextNode("\xa0")])}});var zn=function(){var e=new Tt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};st({type:"tag",mathmlBuilder:function(e,t){var r=new Tt.MathNode("mtable",[new Tt.MathNode("mtr",[zn(),new Tt.MathNode("mtd",[It(e.body,t)]),zn(),new Tt.MathNode("mtd",[It(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var An={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},Tn={"\\textbf":"textbf","\\textmd":"textmd"},Bn={"\\textit":"textit","\\textup":"textup"},Cn=function(e,t){var r=e.font;return r?An[r]?t.withTextFontFamily(An[r]):Tn[r]?t.withTextFontWeight(Tn[r]):t.withTextFontShape(Bn[r]):t};ot({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"text",mode:r.mode,body:ht(a),font:n}},htmlBuilder:function(e,t){var r=Cn(e,t),n=ft(e.body,r,!0);return Ke.makeSpan(["mord","text"],n,r)},mathmlBuilder:function(e,t){var r=Cn(e,t);return It(e.body,r)}}),ot({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"underline",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=wt(e.body,t),n=Ke.makeLineSpan("underline-line",t),a=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:a},{type:"elem",elem:n},{type:"kern",size:3*a},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","underline"],[i],t)},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var n=new Tt.MathNode("munder",[Rt(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),ot({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler:function(e,t){return{type:"vcenter",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=wt(e.body,t),n=t.fontMetrics().axisHeight,a=.5*(r.height-n-(r.depth+n));return Ke.makeVList({positionType:"shift",positionData:a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:function(e,t){return new Tt.MathNode("mpadded",[Rt(e.body,t)],["vcenter"])}}),ot({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(e,t){for(var r=qn(e),n=[],a=t.havingStyle(t.style.text()),i=0;i0;)this.endGroup()},t.has=function(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)},t.get=function(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]},t.set=function(e,t,r){if(void 0===r&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t},e}(),Hn=Hr;Er("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Er("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Er("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Er("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Er("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Er("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Er("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var En={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Er("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=En[r.text])||a>=t)throw new n("Invalid base-"+t+" digit "+r.text);for(var i;null!=(i=En[e.future().text])&&i":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Er("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in Dn?t=Dn[r]:("\\not"===r.substr(0,4)||r in ae.math&&l.contains(["bin","rel"],ae.math[r].group))&&(t="\\dotsb"),t}));var Pn={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Er("\\dotso",(function(e){return e.future().text in Pn?"\\ldots\\,":"\\ldots"})),Er("\\dotsc",(function(e){var t=e.future().text;return t in Pn&&","!==t?"\\ldots\\,":"\\ldots"})),Er("\\cdots",(function(e){return e.future().text in Pn?"\\@cdots\\,":"\\@cdots"})),Er("\\dotsb","\\cdots"),Er("\\dotsm","\\cdots"),Er("\\dotsi","\\!\\cdots"),Er("\\dotsx","\\ldots\\,"),Er("\\DOTSI","\\relax"),Er("\\DOTSB","\\relax"),Er("\\DOTSX","\\relax"),Er("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Er("\\,","\\tmspace+{3mu}{.1667em}"),Er("\\thinspace","\\,"),Er("\\>","\\mskip{4mu}"),Er("\\:","\\tmspace+{4mu}{.2222em}"),Er("\\medspace","\\:"),Er("\\;","\\tmspace+{5mu}{.2777em}"),Er("\\thickspace","\\;"),Er("\\!","\\tmspace-{3mu}{.1667em}"),Er("\\negthinspace","\\!"),Er("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Er("\\negthickspace","\\tmspace-{5mu}{.277em}"),Er("\\enspace","\\kern.5em "),Er("\\enskip","\\hskip.5em\\relax"),Er("\\quad","\\hskip1em\\relax"),Er("\\qquad","\\hskip2em\\relax"),Er("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Er("\\tag@paren","\\tag@literal{({#1})}"),Er("\\tag@literal",(function(e){if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Er("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Er("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Er("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Er("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Er("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),Er("\\newline","\\\\\\relax"),Er("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Fn=V(T["Main-Regular"]["T".charCodeAt(0)][1]-.7*T["Main-Regular"]["A".charCodeAt(0)][1]);Er("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Fn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Er("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Fn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Er("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Er("\\@hspace","\\hskip #1\\relax"),Er("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Er("\\ordinarycolon",":"),Er("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Er("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Er("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Er("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Er("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Er("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Er("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Er("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Er("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Er("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Er("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Er("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Er("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Er("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Er("\u2237","\\dblcolon"),Er("\u2239","\\eqcolon"),Er("\u2254","\\coloneqq"),Er("\u2255","\\eqqcolon"),Er("\u2a74","\\Coloneqq"),Er("\\ratio","\\vcentcolon"),Er("\\coloncolon","\\dblcolon"),Er("\\colonequals","\\coloneqq"),Er("\\coloncolonequals","\\Coloneqq"),Er("\\equalscolon","\\eqqcolon"),Er("\\equalscoloncolon","\\Eqqcolon"),Er("\\colonminus","\\coloneq"),Er("\\coloncolonminus","\\Coloneq"),Er("\\minuscolon","\\eqcolon"),Er("\\minuscoloncolon","\\Eqcolon"),Er("\\coloncolonapprox","\\Colonapprox"),Er("\\coloncolonsim","\\Colonsim"),Er("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Er("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Er("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Er("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Er("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Er("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Er("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Er("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Er("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Er("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Er("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Er("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Er("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Er("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Er("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Er("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Er("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Er("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Er("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Er("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Er("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Er("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Er("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Er("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Er("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Er("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Er("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Er("\\imath","\\html@mathml{\\@imath}{\u0131}"),Er("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Er("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Er("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Er("\u27e6","\\llbracket"),Er("\u27e7","\\rrbracket"),Er("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Er("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Er("\u2983","\\lBrace"),Er("\u2984","\\rBrace"),Er("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Er("\u29b5","\\minuso"),Er("\\darr","\\downarrow"),Er("\\dArr","\\Downarrow"),Er("\\Darr","\\Downarrow"),Er("\\lang","\\langle"),Er("\\rang","\\rangle"),Er("\\uarr","\\uparrow"),Er("\\uArr","\\Uparrow"),Er("\\Uarr","\\Uparrow"),Er("\\N","\\mathbb{N}"),Er("\\R","\\mathbb{R}"),Er("\\Z","\\mathbb{Z}"),Er("\\alef","\\aleph"),Er("\\alefsym","\\aleph"),Er("\\Alpha","\\mathrm{A}"),Er("\\Beta","\\mathrm{B}"),Er("\\bull","\\bullet"),Er("\\Chi","\\mathrm{X}"),Er("\\clubs","\\clubsuit"),Er("\\cnums","\\mathbb{C}"),Er("\\Complex","\\mathbb{C}"),Er("\\Dagger","\\ddagger"),Er("\\diamonds","\\diamondsuit"),Er("\\empty","\\emptyset"),Er("\\Epsilon","\\mathrm{E}"),Er("\\Eta","\\mathrm{H}"),Er("\\exist","\\exists"),Er("\\harr","\\leftrightarrow"),Er("\\hArr","\\Leftrightarrow"),Er("\\Harr","\\Leftrightarrow"),Er("\\hearts","\\heartsuit"),Er("\\image","\\Im"),Er("\\infin","\\infty"),Er("\\Iota","\\mathrm{I}"),Er("\\isin","\\in"),Er("\\Kappa","\\mathrm{K}"),Er("\\larr","\\leftarrow"),Er("\\lArr","\\Leftarrow"),Er("\\Larr","\\Leftarrow"),Er("\\lrarr","\\leftrightarrow"),Er("\\lrArr","\\Leftrightarrow"),Er("\\Lrarr","\\Leftrightarrow"),Er("\\Mu","\\mathrm{M}"),Er("\\natnums","\\mathbb{N}"),Er("\\Nu","\\mathrm{N}"),Er("\\Omicron","\\mathrm{O}"),Er("\\plusmn","\\pm"),Er("\\rarr","\\rightarrow"),Er("\\rArr","\\Rightarrow"),Er("\\Rarr","\\Rightarrow"),Er("\\real","\\Re"),Er("\\reals","\\mathbb{R}"),Er("\\Reals","\\mathbb{R}"),Er("\\Rho","\\mathrm{P}"),Er("\\sdot","\\cdot"),Er("\\sect","\\S"),Er("\\spades","\\spadesuit"),Er("\\sub","\\subset"),Er("\\sube","\\subseteq"),Er("\\supe","\\supseteq"),Er("\\Tau","\\mathrm{T}"),Er("\\thetasym","\\vartheta"),Er("\\weierp","\\wp"),Er("\\Zeta","\\mathrm{Z}"),Er("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Er("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Er("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Er("\\bra","\\mathinner{\\langle{#1}|}"),Er("\\ket","\\mathinner{|{#1}\\rangle}"),Er("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Er("\\Bra","\\left\\langle#1\\right|"),Er("\\Ket","\\left|#1\\right\\rangle");var Vn=function(e){return function(t){var r=t.consumeArg().tokens,n=t.consumeArg().tokens,a=t.consumeArg().tokens,i=t.consumeArg().tokens,o=t.macros.get("|"),s=t.macros.get("\\|");t.macros.beginGroup();var l=function(t){return function(r){e&&(r.macros.set("|",o),a.length&&r.macros.set("\\|",s));var i=t;!t&&a.length&&("|"===r.future().text&&(r.popToken(),i=!0));return{tokens:i?a:n,numArgs:0}}};t.macros.set("|",l(!1)),a.length&&t.macros.set("\\|",l(!0));var h=t.consumeArg().tokens,m=t.expandTokens([].concat(i,h,r));return t.macros.endGroup(),{tokens:m.reverse(),numArgs:0}}};Er("\\bra@ket",Vn(!1)),Er("\\bra@set",Vn(!0)),Er("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Er("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Er("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Er("\\angln","{\\angl n}"),Er("\\blue","\\textcolor{##6495ed}{#1}"),Er("\\orange","\\textcolor{##ffa500}{#1}"),Er("\\pink","\\textcolor{##ff00af}{#1}"),Er("\\red","\\textcolor{##df0030}{#1}"),Er("\\green","\\textcolor{##28ae7b}{#1}"),Er("\\gray","\\textcolor{gray}{#1}"),Er("\\purple","\\textcolor{##9d38bd}{#1}"),Er("\\blueA","\\textcolor{##ccfaff}{#1}"),Er("\\blueB","\\textcolor{##80f6ff}{#1}"),Er("\\blueC","\\textcolor{##63d9ea}{#1}"),Er("\\blueD","\\textcolor{##11accd}{#1}"),Er("\\blueE","\\textcolor{##0c7f99}{#1}"),Er("\\tealA","\\textcolor{##94fff5}{#1}"),Er("\\tealB","\\textcolor{##26edd5}{#1}"),Er("\\tealC","\\textcolor{##01d1c1}{#1}"),Er("\\tealD","\\textcolor{##01a995}{#1}"),Er("\\tealE","\\textcolor{##208170}{#1}"),Er("\\greenA","\\textcolor{##b6ffb0}{#1}"),Er("\\greenB","\\textcolor{##8af281}{#1}"),Er("\\greenC","\\textcolor{##74cf70}{#1}"),Er("\\greenD","\\textcolor{##1fab54}{#1}"),Er("\\greenE","\\textcolor{##0d923f}{#1}"),Er("\\goldA","\\textcolor{##ffd0a9}{#1}"),Er("\\goldB","\\textcolor{##ffbb71}{#1}"),Er("\\goldC","\\textcolor{##ff9c39}{#1}"),Er("\\goldD","\\textcolor{##e07d10}{#1}"),Er("\\goldE","\\textcolor{##a75a05}{#1}"),Er("\\redA","\\textcolor{##fca9a9}{#1}"),Er("\\redB","\\textcolor{##ff8482}{#1}"),Er("\\redC","\\textcolor{##f9685d}{#1}"),Er("\\redD","\\textcolor{##e84d39}{#1}"),Er("\\redE","\\textcolor{##bc2612}{#1}"),Er("\\maroonA","\\textcolor{##ffbde0}{#1}"),Er("\\maroonB","\\textcolor{##ff92c6}{#1}"),Er("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Er("\\maroonD","\\textcolor{##ca337c}{#1}"),Er("\\maroonE","\\textcolor{##9e034e}{#1}"),Er("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Er("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Er("\\purpleC","\\textcolor{##aa87ff}{#1}"),Er("\\purpleD","\\textcolor{##7854ab}{#1}"),Er("\\purpleE","\\textcolor{##543b78}{#1}"),Er("\\mintA","\\textcolor{##f5f9e8}{#1}"),Er("\\mintB","\\textcolor{##edf2df}{#1}"),Er("\\mintC","\\textcolor{##e0e5cc}{#1}"),Er("\\grayA","\\textcolor{##f6f7f7}{#1}"),Er("\\grayB","\\textcolor{##f0f1f2}{#1}"),Er("\\grayC","\\textcolor{##e3e5e6}{#1}"),Er("\\grayD","\\textcolor{##d6d8da}{#1}"),Er("\\grayE","\\textcolor{##babec2}{#1}"),Er("\\grayF","\\textcolor{##888d93}{#1}"),Er("\\grayG","\\textcolor{##626569}{#1}"),Er("\\grayH","\\textcolor{##3b3e40}{#1}"),Er("\\grayI","\\textcolor{##21242c}{#1}"),Er("\\kaBlue","\\textcolor{##314453}{#1}"),Er("\\kaGreen","\\textcolor{##71B307}{#1}");var Gn={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},Un=function(){function e(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new On(Hn,t.macros),this.mode=r,this.stack=[]}var t=e.prototype;return t.feed=function(e){this.lexer=new Rn(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){var t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken();var a=this.consumeArg(["]"]);n=a.tokens,r=a.end}else{var i=this.consumeArg();n=i.tokens,t=i.start,r=i.end}return this.pushToken(new Dr("EOF",r.loc)),this.pushTokens(n),t.range(r,"")},t.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},t.consumeArg=function(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,i=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new n("Extra }",a)}else if("EOF"===a.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===i.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:i,end:a}},t.consumeArgs=function(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting");var i=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(i=i.slice()).length-1;s>=0;--s){var l=i[s];if("#"===l.text){if(0===s)throw new n("Incomplete placeholder at end of macro body",l);if("#"===(l=i[--s]).text)i.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new n("Not a valid argument number",l);var h;(h=i).splice.apply(h,[s,2].concat(o[+l.text-1]))}}}return this.pushTokens(i),i},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof Dr)return e.treatAsRelax&&(e.text="\\relax"),this.stack.pop()}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new Dr(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof Dr&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},t.expandMacroAsText=function(e){var t=this.expandMacro(e);return t?t.map((function(e){return e.text})).join(""):t},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var n="function"==typeof t?t(this):t;if("string"==typeof n){var a=0;if(-1!==n.indexOf("#"))for(var i=n.replace(/##/g,"");-1!==i.indexOf("#"+(a+1));)++a;for(var o=new Rn(n,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:a}}return n},t.isDefined=function(e){return this.macros.has(e)||Nn.hasOwnProperty(e)||ae.math.hasOwnProperty(e)||ae.text.hasOwnProperty(e)||Gn.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Nn.hasOwnProperty(e)&&!Nn[e].primitive},e}(),Yn=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,Xn=Object.freeze({"\u208a":"+","\u208b":"-","\u208c":"=","\u208d":"(","\u208e":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1d62":"i","\u2c7c":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209a":"p","\u1d63":"r","\u209b":"s","\u209c":"t","\u1d64":"u","\u1d65":"v","\u2093":"x","\u1d66":"\u03b2","\u1d67":"\u03b3","\u1d68":"\u03c1","\u1d69":"\u03d5","\u1d6a":"\u03c7","\u207a":"+","\u207b":"-","\u207c":"=","\u207d":"(","\u207e":")","\u2070":"0","\xb9":"1","\xb2":"2","\xb3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1d2c":"A","\u1d2e":"B","\u1d30":"D","\u1d31":"E","\u1d33":"G","\u1d34":"H","\u1d35":"I","\u1d36":"J","\u1d37":"K","\u1d38":"L","\u1d39":"M","\u1d3a":"N","\u1d3c":"O","\u1d3e":"P","\u1d3f":"R","\u1d40":"T","\u1d41":"U","\u2c7d":"V","\u1d42":"W","\u1d43":"a","\u1d47":"b","\u1d9c":"c","\u1d48":"d","\u1d49":"e","\u1da0":"f","\u1d4d":"g","\u02b0":"h","\u2071":"i","\u02b2":"j","\u1d4f":"k","\u02e1":"l","\u1d50":"m","\u207f":"n","\u1d52":"o","\u1d56":"p","\u02b3":"r","\u02e2":"s","\u1d57":"t","\u1d58":"u","\u1d5b":"v","\u02b7":"w","\u02e3":"x","\u02b8":"y","\u1dbb":"z","\u1d5d":"\u03b2","\u1d5e":"\u03b3","\u1d5f":"\u03b4","\u1d60":"\u03d5","\u1d61":"\u03c7","\u1dbf":"\u03b8"}),Wn={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},_n={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},jn=function(){function e(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Un(e,t,this.mode),this.settings=t,this.leftrightDepth=0}var t=e.prototype;return t.expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},t.consume=function(){this.nextToken=null},t.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},t.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},t.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},t.subparse=function(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new Dr("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r},t.parseExpression=function(t,r){for(var n=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==e.endOfExpression.indexOf(a.text))break;if(r&&a.text===r)break;if(t&&Nn[a.text]&&Nn[a.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&n.push(i)}return"text"===this.mode&&this.formLigatures(n),this.handleInfixNodes(n)},t.handleInfixNodes=function(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var s,l=ae[this.mode][t].group,h=Lr.range(e);if(te.hasOwnProperty(l)){var m=l;s={type:"atom",mode:this.mode,family:m,loc:h,text:t}}else s={type:l,mode:this.mode,loc:h,text:t};i=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(S(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),i={type:"textord",mode:"text",loc:Lr.range(e),text:t}}if(this.consume(),o)for(var c=0;c=we[t]&&e<=we[t+1])return 1}function C(e,t,r){if(!Me[t])throw Error("Font metrics not found for font: "+t+".");var n=e.charCodeAt(0),i=Me[t][n];if(!i&&e[0]in Ae&&(n=Ae[e[0]].charCodeAt(0),i=Me[t][n]),i||"text"!==r||B(n)&&(i=Me[t][77]),i)return{depth:i[0],height:i[1],italic:i[2],skew:i[3],width:i[4]}}function q(e){if(e instanceof b)return e;throw Error("Expected symbolNode but got "+e+".")}function e(e,t,r,n,i,a){nt[e][i]={font:t,group:r,replace:n},a&&n&&(nt[e][n]=nt[e][i])}function t(e){for(var t=e.type,r=e.names,n=e.props,i=e.handler,a=e.htmlBuilder,e=e.mathmlBuilder,o={type:t,numArgs:n.numArgs,argTypes:n.argTypes,allowedInArgument:!!n.allowedInArgument,allowedInText:!!n.allowedInText,allowedInMath:void 0===n.allowedInMath||n.allowedInMath,numOptionalArgs:n.numOptionalArgs||0,infix:!!n.infix,primitive:!!n.primitive,handler:i},s=0;s=g.length&&u||g.pop(),b.length":">","<":"<",'"':""","'":"'"},le=/[&><"']/g,Z={contains:function(e,t){return!!~e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return(""+e).replace(le,function(e){return se[e]})},hyphenate:function(e){return e.replace(oe,"-$1").toLowerCase()},getBaseElem:ne,isCharacterBox:function(e){e=ne(e);return"mathord"===e.type||"textord"===e.type||"atom"===e.type},protocolFromUrl:function(e){e=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=e?e[1]:"_relative"}},he={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:function(e){return"#"+e}},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:function(e,t){return t.push(e),t}},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:function(e){return Math.max(0,e)},cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:function(e){return Math.max(0,e)},cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:function(e){return Math.max(0,e)},cli:"-e, --max-expand ",cliProcessor:function(e){return"Infinity"===e?1/0:parseInt(e)}},globalGroup:{type:"boolean",cli:!1}},me=((o=ve.prototype).reportNonstrict=function(e,t,r){var n=this.strict;if((n="function"==typeof n?n(e,t,r):n)&&"ignore"!==n&&(!0===n||"error"===n))throw new j("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r)},o.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n||!0!==n&&"error"!==n)},o.isTrusted=function(e){return e.url&&!e.protocol&&(e.protocol=Z.protocolFromUrl(e.url)),!!("function"==typeof this.trust?this.trust(e):this.trust)},ve);(o=xe.prototype).sup=function(){return ce[ue[this.id]]},o.sub=function(){return ce[pe[this.id]]},o.fracNum=function(){return ce[de[this.id]]},o.fracDen=function(){return ce[fe[this.id]]},o.cramp=function(){return ce[ge[this.id]]},o.text=function(){return ce[ye[this.id]]};var ce=[new(s=xe)(0,0,!(o.isTight=function(){return 2<=this.size})),new s(1,0,!0),new s(2,1,!1),new s(3,1,!0),new s(4,2,!1),new s(5,2,!0),new s(6,3,!1),new s(7,3,!0)],ue=[4,5,4,5,6,7,6,7],pe=[5,5,5,5,7,7,7,7],de=[2,3,4,5,6,7,6,7],fe=[3,3,5,5,7,7,7,7],ge=[1,1,3,3,5,5,7,7],ye=[0,1,2,3,2,3,2,3],K={DISPLAY:ce[0],TEXT:ce[2],SCRIPT:ce[4],SCRIPTSCRIPT:ce[6]},be=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];function xe(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}function ve(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},he){var r;he.hasOwnProperty(t)&&(r=he[t],this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:function(e){if(e.default)return e.default;if(e=e.type,"string"!=typeof(e=Array.isArray(e)?e[0]:e))return e.enum[0];switch(e){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}(r))}}var we=[],ke=(be.forEach(function(e){return e.blocks.forEach(function(e){return we.push.apply(we,e)})}),{doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"}),Se=((o=Te.prototype).hasClass=function(e){return Z.contains(this.classes,e)},o.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t"}(s=Ie.prototype).extend=function(e){var t,r={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(t in e)e.hasOwnProperty(t)&&(r[t]=e[t]);return new Ie(r)},s.havingStyle=function(e){return this.style===e?this:this.extend({style:e,size:Be(this.textSize,e)})},s.havingCrampedStyle=function(){return this.havingStyle(this.style.cramp())},s.havingSize=function(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:Ne[e-1]})},s.havingBaseStyle=function(e){e=e||this.style.text();var t=Be(Ie.BASESIZE,e);return this.size===t&&this.textSize===Ie.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})},s.havingBaseSizing=function(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})},s.withColor=function(e){return this.extend({color:e})},s.withPhantom=function(){return this.extend({phantom:!0})},s.withFont=function(e){return this.extend({font:e})},s.withTextFontFamily=function(e){return this.extend({fontFamily:e,font:""})},s.withTextFontWeight=function(e){return this.extend({fontWeight:e,font:""})},s.withTextFontShape=function(e){return this.extend({fontShape:e,font:""})},s.sizingClasses=function(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]},s.baseSizingClasses=function(){return this.size!==Ie.BASESIZE?["sizing","reset-size"+this.size,"size"+Ie.BASESIZE]:[]},s.fontMetrics=function(){return this._fontMetrics||(this._fontMetrics=function(e){var t;if(!Ce[t=e<5?e<3?2:1:0]){var r,n=Ce[t]={cssEmPerMu:ze.quad[t]/18};for(r in ze)ze.hasOwnProperty(r)&&(n[r]=ze[r][t])}return Ce[t]}(this.size)),this._fontMetrics},s.getColor=function(){return this.phantom?"transparent":this.color},(o=Ie).BASESIZE=6;var Le=o,Pe={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},Fe={ex:!0,em:!0,mu:!0},Q=function(e){return+e.toFixed(4)+"em"},Ve=((s=et.prototype).setAttribute=function(e,t){this.attributes[e]=t},s.hasClass=function(e){return Z.contains(this.classes,e)},s.toNode=function(){return He.call(this,"span")},s.toMarkup=function(){return De.call(this,"span")},et),Ge=((o=Qe.prototype).setAttribute=function(e,t){this.attributes[e]=t},o.hasClass=function(e){return Z.contains(this.classes,e)},o.toNode=function(){return He.call(this,"a")},o.toMarkup=function(){return De.call(this,"a")},Qe),Ue=((s=Je.prototype).hasClass=function(e){return Z.contains(this.classes,e)},s.toNode=function(){var e,t=document.createElement("img");for(e in t.src=this.src,t.alt=this.alt,t.className="mord",this.style)this.style.hasOwnProperty(e)&&(t.style[e]=this.style[e]);return t},s.toMarkup=function(){var e,t=""+this.alt+""},Je),Ye={"î":"ı̂","ï":"ı̈","í":"ı́","ì":"ı̀"},b=((o=Ke.prototype).hasClass=function(e){return Z.contains(this.classes,e)},o.toNode=function(){var e,t=document.createTextNode(this.text),r=null;for(e in 0"+i)+"":i},Ke),We=((s=Ze.prototype).toNode=function(){var e,t=document.createElementNS("http://www.w3.org/2000/svg","svg");for(e in this.attributes)!{}.hasOwnProperty.call(this.attributes,e)||t.setAttribute(e,this.attributes[e]);for(var r=0;r"},Ze),Xe=((o=je.prototype).toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","path");return this.alternate?e.setAttribute("d",this.alternate):e.setAttribute("d",ke[this.pathName]),e},o.toMarkup=function(){return this.alternate?"":""},je),_e=((s=$e.prototype).toNode=function(){var e,t=document.createElementNS("http://www.w3.org/2000/svg","line");for(e in this.attributes)!{}.hasOwnProperty.call(this.attributes,e)||t.setAttribute(e,this.attributes[e]);return t},s.toMarkup=function(){var e,t=""},$e);function $e(e){this.attributes=void 0,this.attributes=e||{}}function je(e,t){this.pathName=void 0,this.alternate=void 0,this.pathName=e,this.alternate=t}function Ze(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}function Ke(e,t,r,n,i,a,o,s){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=e,this.height=t||0,this.depth=r||0,this.italic=n||0,this.skew=i||0,this.width=a||0,this.classes=o||[],this.style=s||{},this.maxFontSize=0;e=function(e){for(var t=0;t=i[0]&&e<=i[1])return r.name}return null}(this.text.charCodeAt(0));e&&this.classes.push(e+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=Ye[this.text])}function Je(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}function Qe(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,Ee.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}function et(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,Ee.call(this,e,r,n),this.children=t||[]}var tt={bin:1,close:1,inner:1,open:1,punct:1,rel:1},rt={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},nt={math:{},text:{}},p=nt,n="math",i="text",a="main",o="ams",s="accent-token",l="bin",h="close",it="inner",m="mathord",c="op-token",u="open",f="punct",g="rel",y="spacing",x="textord",at=(e(n,a,g,"≡","\\equiv",!0),e(n,a,g,"≺","\\prec",!0),e(n,a,g,"≻","\\succ",!0),e(n,a,g,"∼","\\sim",!0),e(n,a,g,"⊥","\\perp"),e(n,a,g,"⪯","\\preceq",!0),e(n,a,g,"⪰","\\succeq",!0),e(n,a,g,"≃","\\simeq",!0),e(n,a,g,"∣","\\mid",!0),e(n,a,g,"≪","\\ll",!0),e(n,a,g,"≫","\\gg",!0),e(n,a,g,"≍","\\asymp",!0),e(n,a,g,"∥","\\parallel"),e(n,a,g,"⋈","\\bowtie",!0),e(n,a,g,"⌣","\\smile",!0),e(n,a,g,"⊑","\\sqsubseteq",!0),e(n,a,g,"⊒","\\sqsupseteq",!0),e(n,a,g,"≐","\\doteq",!0),e(n,a,g,"⌢","\\frown",!0),e(n,a,g,"∋","\\ni",!0),e(n,a,g,"∝","\\propto",!0),e(n,a,g,"⊢","\\vdash",!0),e(n,a,g,"⊣","\\dashv",!0),e(n,a,g,"∋","\\owns"),e(n,a,f,".","\\ldotp"),e(n,a,f,"⋅","\\cdotp"),e(n,a,x,"#","\\#"),e(i,a,x,"#","\\#"),e(n,a,x,"&","\\&"),e(i,a,x,"&","\\&"),e(n,a,x,"ℵ","\\aleph",!0),e(n,a,x,"∀","\\forall",!0),e(n,a,x,"ℏ","\\hbar",!0),e(n,a,x,"∃","\\exists",!0),e(n,a,x,"∇","\\nabla",!0),e(n,a,x,"♭","\\flat",!0),e(n,a,x,"ℓ","\\ell",!0),e(n,a,x,"♮","\\natural",!0),e(n,a,x,"♣","\\clubsuit",!0),e(n,a,x,"℘","\\wp",!0),e(n,a,x,"♯","\\sharp",!0),e(n,a,x,"♢","\\diamondsuit",!0),e(n,a,x,"ℜ","\\Re",!0),e(n,a,x,"♡","\\heartsuit",!0),e(n,a,x,"ℑ","\\Im",!0),e(n,a,x,"♠","\\spadesuit",!0),e(n,a,x,"§","\\S",!0),e(i,a,x,"§","\\S"),e(n,a,x,"¶","\\P",!0),e(i,a,x,"¶","\\P"),e(n,a,x,"†","\\dag"),e(i,a,x,"†","\\dag"),e(i,a,x,"†","\\textdagger"),e(n,a,x,"‡","\\ddag"),e(i,a,x,"‡","\\ddag"),e(i,a,x,"‡","\\textdaggerdbl"),e(n,a,h,"⎱","\\rmoustache",!0),e(n,a,u,"⎰","\\lmoustache",!0),e(n,a,h,"⟯","\\rgroup",!0),e(n,a,u,"⟮","\\lgroup",!0),e(n,a,l,"∓","\\mp",!0),e(n,a,l,"⊖","\\ominus",!0),e(n,a,l,"⊎","\\uplus",!0),e(n,a,l,"⊓","\\sqcap",!0),e(n,a,l,"∗","\\ast"),e(n,a,l,"⊔","\\sqcup",!0),e(n,a,l,"◯","\\bigcirc",!0),e(n,a,l,"∙","\\bullet",!0),e(n,a,l,"‡","\\ddagger"),e(n,a,l,"≀","\\wr",!0),e(n,a,l,"⨿","\\amalg"),e(n,a,l,"&","\\And"),e(n,a,g,"⟵","\\longleftarrow",!0),e(n,a,g,"⇐","\\Leftarrow",!0),e(n,a,g,"⟸","\\Longleftarrow",!0),e(n,a,g,"⟶","\\longrightarrow",!0),e(n,a,g,"⇒","\\Rightarrow",!0),e(n,a,g,"⟹","\\Longrightarrow",!0),e(n,a,g,"↔","\\leftrightarrow",!0),e(n,a,g,"⟷","\\longleftrightarrow",!0),e(n,a,g,"⇔","\\Leftrightarrow",!0),e(n,a,g,"⟺","\\Longleftrightarrow",!0),e(n,a,g,"↦","\\mapsto",!0),e(n,a,g,"⟼","\\longmapsto",!0),e(n,a,g,"↗","\\nearrow",!0),e(n,a,g,"↩","\\hookleftarrow",!0),e(n,a,g,"↪","\\hookrightarrow",!0),e(n,a,g,"↘","\\searrow",!0),e(n,a,g,"↼","\\leftharpoonup",!0),e(n,a,g,"⇀","\\rightharpoonup",!0),e(n,a,g,"↙","\\swarrow",!0),e(n,a,g,"↽","\\leftharpoondown",!0),e(n,a,g,"⇁","\\rightharpoondown",!0),e(n,a,g,"↖","\\nwarrow",!0),e(n,a,g,"⇌","\\rightleftharpoons",!0),e(n,o,g,"≮","\\nless",!0),e(n,o,g,"","\\@nleqslant"),e(n,o,g,"","\\@nleqq"),e(n,o,g,"⪇","\\lneq",!0),e(n,o,g,"≨","\\lneqq",!0),e(n,o,g,"","\\@lvertneqq"),e(n,o,g,"⋦","\\lnsim",!0),e(n,o,g,"⪉","\\lnapprox",!0),e(n,o,g,"⊀","\\nprec",!0),e(n,o,g,"⋠","\\npreceq",!0),e(n,o,g,"⋨","\\precnsim",!0),e(n,o,g,"⪹","\\precnapprox",!0),e(n,o,g,"≁","\\nsim",!0),e(n,o,g,"","\\@nshortmid"),e(n,o,g,"∤","\\nmid",!0),e(n,o,g,"⊬","\\nvdash",!0),e(n,o,g,"⊭","\\nvDash",!0),e(n,o,g,"⋪","\\ntriangleleft"),e(n,o,g,"⋬","\\ntrianglelefteq",!0),e(n,o,g,"⊊","\\subsetneq",!0),e(n,o,g,"","\\@varsubsetneq"),e(n,o,g,"⫋","\\subsetneqq",!0),e(n,o,g,"","\\@varsubsetneqq"),e(n,o,g,"≯","\\ngtr",!0),e(n,o,g,"","\\@ngeqslant"),e(n,o,g,"","\\@ngeqq"),e(n,o,g,"⪈","\\gneq",!0),e(n,o,g,"≩","\\gneqq",!0),e(n,o,g,"","\\@gvertneqq"),e(n,o,g,"⋧","\\gnsim",!0),e(n,o,g,"⪊","\\gnapprox",!0),e(n,o,g,"⊁","\\nsucc",!0),e(n,o,g,"⋡","\\nsucceq",!0),e(n,o,g,"⋩","\\succnsim",!0),e(n,o,g,"⪺","\\succnapprox",!0),e(n,o,g,"≆","\\ncong",!0),e(n,o,g,"","\\@nshortparallel"),e(n,o,g,"∦","\\nparallel",!0),e(n,o,g,"⊯","\\nVDash",!0),e(n,o,g,"⋫","\\ntriangleright"),e(n,o,g,"⋭","\\ntrianglerighteq",!0),e(n,o,g,"","\\@nsupseteqq"),e(n,o,g,"⊋","\\supsetneq",!0),e(n,o,g,"","\\@varsupsetneq"),e(n,o,g,"⫌","\\supsetneqq",!0),e(n,o,g,"","\\@varsupsetneqq"),e(n,o,g,"⊮","\\nVdash",!0),e(n,o,g,"⪵","\\precneqq",!0),e(n,o,g,"⪶","\\succneqq",!0),e(n,o,g,"","\\@nsubseteqq"),e(n,o,l,"⊴","\\unlhd"),e(n,o,l,"⊵","\\unrhd"),e(n,o,g,"↚","\\nleftarrow",!0),e(n,o,g,"↛","\\nrightarrow",!0),e(n,o,g,"⇍","\\nLeftarrow",!0),e(n,o,g,"⇏","\\nRightarrow",!0),e(n,o,g,"↮","\\nleftrightarrow",!0),e(n,o,g,"⇎","\\nLeftrightarrow",!0),e(n,o,g,"△","\\vartriangle"),e(n,o,x,"ℏ","\\hslash"),e(n,o,x,"▽","\\triangledown"),e(n,o,x,"◊","\\lozenge"),e(n,o,x,"Ⓢ","\\circledS"),e(n,o,x,"®","\\circledR"),e(i,o,x,"®","\\circledR"),e(n,o,x,"∡","\\measuredangle",!0),e(n,o,x,"∄","\\nexists"),e(n,o,x,"℧","\\mho"),e(n,o,x,"Ⅎ","\\Finv",!0),e(n,o,x,"⅁","\\Game",!0),e(n,o,x,"‵","\\backprime"),e(n,o,x,"▲","\\blacktriangle"),e(n,o,x,"▼","\\blacktriangledown"),e(n,o,x,"■","\\blacksquare"),e(n,o,x,"⧫","\\blacklozenge"),e(n,o,x,"★","\\bigstar"),e(n,o,x,"∢","\\sphericalangle",!0),e(n,o,x,"∁","\\complement",!0),e(n,o,x,"ð","\\eth",!0),e(i,a,x,"ð","ð"),e(n,o,x,"╱","\\diagup"),e(n,o,x,"╲","\\diagdown"),e(n,o,x,"□","\\square"),e(n,o,x,"□","\\Box"),e(n,o,x,"◊","\\Diamond"),e(n,o,x,"¥","\\yen",!0),e(i,o,x,"¥","\\yen",!0),e(n,o,x,"✓","\\checkmark",!0),e(i,o,x,"✓","\\checkmark"),e(n,o,x,"ℶ","\\beth",!0),e(n,o,x,"ℸ","\\daleth",!0),e(n,o,x,"ℷ","\\gimel",!0),e(n,o,x,"ϝ","\\digamma",!0),e(n,o,x,"ϰ","\\varkappa"),e(n,o,u,"┌","\\@ulcorner",!0),e(n,o,h,"┐","\\@urcorner",!0),e(n,o,u,"└","\\@llcorner",!0),e(n,o,h,"┘","\\@lrcorner",!0),e(n,o,g,"≦","\\leqq",!0),e(n,o,g,"⩽","\\leqslant",!0),e(n,o,g,"⪕","\\eqslantless",!0),e(n,o,g,"≲","\\lesssim",!0),e(n,o,g,"⪅","\\lessapprox",!0),e(n,o,g,"≊","\\approxeq",!0),e(n,o,l,"⋖","\\lessdot"),e(n,o,g,"⋘","\\lll",!0),e(n,o,g,"≶","\\lessgtr",!0),e(n,o,g,"⋚","\\lesseqgtr",!0),e(n,o,g,"⪋","\\lesseqqgtr",!0),e(n,o,g,"≑","\\doteqdot"),e(n,o,g,"≓","\\risingdotseq",!0),e(n,o,g,"≒","\\fallingdotseq",!0),e(n,o,g,"∽","\\backsim",!0),e(n,o,g,"⋍","\\backsimeq",!0),e(n,o,g,"⫅","\\subseteqq",!0),e(n,o,g,"⋐","\\Subset",!0),e(n,o,g,"⊏","\\sqsubset",!0),e(n,o,g,"≼","\\preccurlyeq",!0),e(n,o,g,"⋞","\\curlyeqprec",!0),e(n,o,g,"≾","\\precsim",!0),e(n,o,g,"⪷","\\precapprox",!0),e(n,o,g,"⊲","\\vartriangleleft"),e(n,o,g,"⊴","\\trianglelefteq"),e(n,o,g,"⊨","\\vDash",!0),e(n,o,g,"⊪","\\Vvdash",!0),e(n,o,g,"⌣","\\smallsmile"),e(n,o,g,"⌢","\\smallfrown"),e(n,o,g,"≏","\\bumpeq",!0),e(n,o,g,"≎","\\Bumpeq",!0),e(n,o,g,"≧","\\geqq",!0),e(n,o,g,"⩾","\\geqslant",!0),e(n,o,g,"⪖","\\eqslantgtr",!0),e(n,o,g,"≳","\\gtrsim",!0),e(n,o,g,"⪆","\\gtrapprox",!0),e(n,o,l,"⋗","\\gtrdot"),e(n,o,g,"⋙","\\ggg",!0),e(n,o,g,"≷","\\gtrless",!0),e(n,o,g,"⋛","\\gtreqless",!0),e(n,o,g,"⪌","\\gtreqqless",!0),e(n,o,g,"≖","\\eqcirc",!0),e(n,o,g,"≗","\\circeq",!0),e(n,o,g,"≜","\\triangleq",!0),e(n,o,g,"∼","\\thicksim"),e(n,o,g,"≈","\\thickapprox"),e(n,o,g,"⫆","\\supseteqq",!0),e(n,o,g,"⋑","\\Supset",!0),e(n,o,g,"⊐","\\sqsupset",!0),e(n,o,g,"≽","\\succcurlyeq",!0),e(n,o,g,"⋟","\\curlyeqsucc",!0),e(n,o,g,"≿","\\succsim",!0),e(n,o,g,"⪸","\\succapprox",!0),e(n,o,g,"⊳","\\vartriangleright"),e(n,o,g,"⊵","\\trianglerighteq"),e(n,o,g,"⊩","\\Vdash",!0),e(n,o,g,"∣","\\shortmid"),e(n,o,g,"∥","\\shortparallel"),e(n,o,g,"≬","\\between",!0),e(n,o,g,"⋔","\\pitchfork",!0),e(n,o,g,"∝","\\varpropto"),e(n,o,g,"◀","\\blacktriangleleft"),e(n,o,g,"∴","\\therefore",!0),e(n,o,g,"∍","\\backepsilon"),e(n,o,g,"▶","\\blacktriangleright"),e(n,o,g,"∵","\\because",!0),e(n,o,g,"⋘","\\llless"),e(n,o,g,"⋙","\\gggtr"),e(n,o,l,"⊲","\\lhd"),e(n,o,l,"⊳","\\rhd"),e(n,o,g,"≂","\\eqsim",!0),e(n,a,g,"⋈","\\Join"),e(n,o,g,"≑","\\Doteq",!0),e(n,o,l,"∔","\\dotplus",!0),e(n,o,l,"∖","\\smallsetminus"),e(n,o,l,"⋒","\\Cap",!0),e(n,o,l,"⋓","\\Cup",!0),e(n,o,l,"⩞","\\doublebarwedge",!0),e(n,o,l,"⊟","\\boxminus",!0),e(n,o,l,"⊞","\\boxplus",!0),e(n,o,l,"⋇","\\divideontimes",!0),e(n,o,l,"⋉","\\ltimes",!0),e(n,o,l,"⋊","\\rtimes",!0),e(n,o,l,"⋋","\\leftthreetimes",!0),e(n,o,l,"⋌","\\rightthreetimes",!0),e(n,o,l,"⋏","\\curlywedge",!0),e(n,o,l,"⋎","\\curlyvee",!0),e(n,o,l,"⊝","\\circleddash",!0),e(n,o,l,"⊛","\\circledast",!0),e(n,o,l,"⋅","\\centerdot"),e(n,o,l,"⊺","\\intercal",!0),e(n,o,l,"⋒","\\doublecap"),e(n,o,l,"⋓","\\doublecup"),e(n,o,l,"⊠","\\boxtimes",!0),e(n,o,g,"⇢","\\dashrightarrow",!0),e(n,o,g,"⇠","\\dashleftarrow",!0),e(n,o,g,"⇇","\\leftleftarrows",!0),e(n,o,g,"⇆","\\leftrightarrows",!0),e(n,o,g,"⇚","\\Lleftarrow",!0),e(n,o,g,"↞","\\twoheadleftarrow",!0),e(n,o,g,"↢","\\leftarrowtail",!0),e(n,o,g,"↫","\\looparrowleft",!0),e(n,o,g,"⇋","\\leftrightharpoons",!0),e(n,o,g,"↶","\\curvearrowleft",!0),e(n,o,g,"↺","\\circlearrowleft",!0),e(n,o,g,"↰","\\Lsh",!0),e(n,o,g,"⇈","\\upuparrows",!0),e(n,o,g,"↿","\\upharpoonleft",!0),e(n,o,g,"⇃","\\downharpoonleft",!0),e(n,a,g,"⊶","\\origof",!0),e(n,a,g,"⊷","\\imageof",!0),e(n,o,g,"⊸","\\multimap",!0),e(n,o,g,"↭","\\leftrightsquigarrow",!0),e(n,o,g,"⇉","\\rightrightarrows",!0),e(n,o,g,"⇄","\\rightleftarrows",!0),e(n,o,g,"↠","\\twoheadrightarrow",!0),e(n,o,g,"↣","\\rightarrowtail",!0),e(n,o,g,"↬","\\looparrowright",!0),e(n,o,g,"↷","\\curvearrowright",!0),e(n,o,g,"↻","\\circlearrowright",!0),e(n,o,g,"↱","\\Rsh",!0),e(n,o,g,"⇊","\\downdownarrows",!0),e(n,o,g,"↾","\\upharpoonright",!0),e(n,o,g,"⇂","\\downharpoonright",!0),e(n,o,g,"⇝","\\rightsquigarrow",!0),e(n,o,g,"⇝","\\leadsto"),e(n,o,g,"⇛","\\Rrightarrow",!0),e(n,o,g,"↾","\\restriction"),e(n,a,x,"‘","`"),e(n,a,x,"$","\\$"),e(i,a,x,"$","\\$"),e(i,a,x,"$","\\textdollar"),e(n,a,x,"%","\\%"),e(i,a,x,"%","\\%"),e(n,a,x,"_","\\_"),e(i,a,x,"_","\\_"),e(i,a,x,"_","\\textunderscore"),e(n,a,x,"∠","\\angle",!0),e(n,a,x,"∞","\\infty",!0),e(n,a,x,"′","\\prime"),e(n,a,x,"△","\\triangle"),e(n,a,x,"Γ","\\Gamma",!0),e(n,a,x,"Δ","\\Delta",!0),e(n,a,x,"Θ","\\Theta",!0),e(n,a,x,"Λ","\\Lambda",!0),e(n,a,x,"Ξ","\\Xi",!0),e(n,a,x,"Π","\\Pi",!0),e(n,a,x,"Σ","\\Sigma",!0),e(n,a,x,"Υ","\\Upsilon",!0),e(n,a,x,"Φ","\\Phi",!0),e(n,a,x,"Ψ","\\Psi",!0),e(n,a,x,"Ω","\\Omega",!0),e(n,a,x,"A","Α"),e(n,a,x,"B","Β"),e(n,a,x,"E","Ε"),e(n,a,x,"Z","Ζ"),e(n,a,x,"H","Η"),e(n,a,x,"I","Ι"),e(n,a,x,"K","Κ"),e(n,a,x,"M","Μ"),e(n,a,x,"N","Ν"),e(n,a,x,"O","Ο"),e(n,a,x,"P","Ρ"),e(n,a,x,"T","Τ"),e(n,a,x,"X","Χ"),e(n,a,x,"¬","\\neg",!0),e(n,a,x,"¬","\\lnot"),e(n,a,x,"⊤","\\top"),e(n,a,x,"⊥","\\bot"),e(n,a,x,"∅","\\emptyset"),e(n,o,x,"∅","\\varnothing"),e(n,a,m,"α","\\alpha",!0),e(n,a,m,"β","\\beta",!0),e(n,a,m,"γ","\\gamma",!0),e(n,a,m,"δ","\\delta",!0),e(n,a,m,"ϵ","\\epsilon",!0),e(n,a,m,"ζ","\\zeta",!0),e(n,a,m,"η","\\eta",!0),e(n,a,m,"θ","\\theta",!0),e(n,a,m,"ι","\\iota",!0),e(n,a,m,"κ","\\kappa",!0),e(n,a,m,"λ","\\lambda",!0),e(n,a,m,"μ","\\mu",!0),e(n,a,m,"ν","\\nu",!0),e(n,a,m,"ξ","\\xi",!0),e(n,a,m,"ο","\\omicron",!0),e(n,a,m,"π","\\pi",!0),e(n,a,m,"ρ","\\rho",!0),e(n,a,m,"σ","\\sigma",!0),e(n,a,m,"τ","\\tau",!0),e(n,a,m,"υ","\\upsilon",!0),e(n,a,m,"ϕ","\\phi",!0),e(n,a,m,"χ","\\chi",!0),e(n,a,m,"ψ","\\psi",!0),e(n,a,m,"ω","\\omega",!0),e(n,a,m,"ε","\\varepsilon",!0),e(n,a,m,"ϑ","\\vartheta",!0),e(n,a,m,"ϖ","\\varpi",!0),e(n,a,m,"ϱ","\\varrho",!0),e(n,a,m,"ς","\\varsigma",!0),e(n,a,m,"φ","\\varphi",!0),e(n,a,l,"∗","*",!0),e(n,a,l,"+","+"),e(n,a,l,"−","-",!0),e(n,a,l,"⋅","\\cdot",!0),e(n,a,l,"∘","\\circ",!0),e(n,a,l,"÷","\\div",!0),e(n,a,l,"±","\\pm",!0),e(n,a,l,"×","\\times",!0),e(n,a,l,"∩","\\cap",!0),e(n,a,l,"∪","\\cup",!0),e(n,a,l,"∖","\\setminus",!0),e(n,a,l,"∧","\\land"),e(n,a,l,"∨","\\lor"),e(n,a,l,"∧","\\wedge",!0),e(n,a,l,"∨","\\vee",!0),e(n,a,x,"√","\\surd"),e(n,a,u,"⟨","\\langle",!0),e(n,a,u,"∣","\\lvert"),e(n,a,u,"∥","\\lVert"),e(n,a,h,"?","?"),e(n,a,h,"!","!"),e(n,a,h,"⟩","\\rangle",!0),e(n,a,h,"∣","\\rvert"),e(n,a,h,"∥","\\rVert"),e(n,a,g,"=","="),e(n,a,g,":",":"),e(n,a,g,"≈","\\approx",!0),e(n,a,g,"≅","\\cong",!0),e(n,a,g,"≥","\\ge"),e(n,a,g,"≥","\\geq",!0),e(n,a,g,"←","\\gets"),e(n,a,g,">","\\gt",!0),e(n,a,g,"∈","\\in",!0),e(n,a,g,"","\\@not"),e(n,a,g,"⊂","\\subset",!0),e(n,a,g,"⊃","\\supset",!0),e(n,a,g,"⊆","\\subseteq",!0),e(n,a,g,"⊇","\\supseteq",!0),e(n,o,g,"⊈","\\nsubseteq",!0),e(n,o,g,"⊉","\\nsupseteq",!0),e(n,a,g,"⊨","\\models"),e(n,a,g,"←","\\leftarrow",!0),e(n,a,g,"≤","\\le"),e(n,a,g,"≤","\\leq",!0),e(n,a,g,"<","\\lt",!0),e(n,a,g,"→","\\rightarrow",!0),e(n,a,g,"→","\\to"),e(n,o,g,"≱","\\ngeq",!0),e(n,o,g,"≰","\\nleq",!0),e(n,a,y," ","\\ "),e(n,a,y," ","\\space"),e(n,a,y," ","\\nobreakspace"),e(i,a,y," ","\\ "),e(i,a,y," "," "),e(i,a,y," ","\\space"),e(i,a,y," ","\\nobreakspace"),e(n,a,y,null,"\\nobreak"),e(n,a,y,null,"\\allowbreak"),e(n,a,f,",",","),e(n,a,f,";",";"),e(n,o,l,"⊼","\\barwedge",!0),e(n,o,l,"⊻","\\veebar",!0),e(n,a,l,"⊙","\\odot",!0),e(n,a,l,"⊕","\\oplus",!0),e(n,a,l,"⊗","\\otimes",!0),e(n,a,x,"∂","\\partial",!0),e(n,a,l,"⊘","\\oslash",!0),e(n,o,l,"⊚","\\circledcirc",!0),e(n,o,l,"⊡","\\boxdot",!0),e(n,a,l,"△","\\bigtriangleup"),e(n,a,l,"▽","\\bigtriangledown"),e(n,a,l,"†","\\dagger"),e(n,a,l,"⋄","\\diamond"),e(n,a,l,"⋆","\\star"),e(n,a,l,"◃","\\triangleleft"),e(n,a,l,"▹","\\triangleright"),e(n,a,u,"{","\\{"),e(i,a,x,"{","\\{"),e(i,a,x,"{","\\textbraceleft"),e(n,a,h,"}","\\}"),e(i,a,x,"}","\\}"),e(i,a,x,"}","\\textbraceright"),e(n,a,u,"{","\\lbrace"),e(n,a,h,"}","\\rbrace"),e(n,a,u,"[","\\lbrack",!0),e(i,a,x,"[","\\lbrack",!0),e(n,a,h,"]","\\rbrack",!0),e(i,a,x,"]","\\rbrack",!0),e(n,a,u,"(","\\lparen",!0),e(n,a,h,")","\\rparen",!0),e(i,a,x,"<","\\textless",!0),e(i,a,x,">","\\textgreater",!0),e(n,a,u,"⌊","\\lfloor",!0),e(n,a,h,"⌋","\\rfloor",!0),e(n,a,u,"⌈","\\lceil",!0),e(n,a,h,"⌉","\\rceil",!0),e(n,a,x,"\\","\\backslash"),e(n,a,x,"∣","|"),e(n,a,x,"∣","\\vert"),e(i,a,x,"|","\\textbar",!0),e(n,a,x,"∥","\\|"),e(n,a,x,"∥","\\Vert"),e(i,a,x,"∥","\\textbardbl"),e(i,a,x,"~","\\textasciitilde"),e(i,a,x,"\\","\\textbackslash"),e(i,a,x,"^","\\textasciicircum"),e(n,a,g,"↑","\\uparrow",!0),e(n,a,g,"⇑","\\Uparrow",!0),e(n,a,g,"↓","\\downarrow",!0),e(n,a,g,"⇓","\\Downarrow",!0),e(n,a,g,"↕","\\updownarrow",!0),e(n,a,g,"⇕","\\Updownarrow",!0),e(n,a,c,"∐","\\coprod"),e(n,a,c,"⋁","\\bigvee"),e(n,a,c,"⋀","\\bigwedge"),e(n,a,c,"⨄","\\biguplus"),e(n,a,c,"⋂","\\bigcap"),e(n,a,c,"⋃","\\bigcup"),e(n,a,c,"∫","\\int"),e(n,a,c,"∫","\\intop"),e(n,a,c,"∬","\\iint"),e(n,a,c,"∭","\\iiint"),e(n,a,c,"∏","\\prod"),e(n,a,c,"∑","\\sum"),e(n,a,c,"⨂","\\bigotimes"),e(n,a,c,"⨁","\\bigoplus"),e(n,a,c,"⨀","\\bigodot"),e(n,a,c,"∮","\\oint"),e(n,a,c,"∯","\\oiint"),e(n,a,c,"∰","\\oiiint"),e(n,a,c,"⨆","\\bigsqcup"),e(n,a,c,"∫","\\smallint"),e(i,a,it,"…","\\textellipsis"),e(n,a,it,"…","\\mathellipsis"),e(i,a,it,"…","\\ldots",!0),e(n,a,it,"…","\\ldots",!0),e(n,a,it,"⋯","\\@cdots",!0),e(n,a,it,"⋱","\\ddots",!0),e(n,a,x,"⋮","\\varvdots"),e(n,a,s,"ˊ","\\acute"),e(n,a,s,"ˋ","\\grave"),e(n,a,s,"¨","\\ddot"),e(n,a,s,"~","\\tilde"),e(n,a,s,"ˉ","\\bar"),e(n,a,s,"˘","\\breve"),e(n,a,s,"ˇ","\\check"),e(n,a,s,"^","\\hat"),e(n,a,s,"⃗","\\vec"),e(n,a,s,"˙","\\dot"),e(n,a,s,"˚","\\mathring"),e(n,a,m,"","\\@imath"),e(n,a,m,"","\\@jmath"),e(n,a,x,"ı","ı"),e(n,a,x,"ȷ","ȷ"),e(i,a,x,"ı","\\i",!0),e(i,a,x,"ȷ","\\j",!0),e(i,a,x,"ß","\\ss",!0),e(i,a,x,"æ","\\ae",!0),e(i,a,x,"œ","\\oe",!0),e(i,a,x,"ø","\\o",!0),e(i,a,x,"Æ","\\AE",!0),e(i,a,x,"Œ","\\OE",!0),e(i,a,x,"Ø","\\O",!0),e(i,a,s,"ˊ","\\'"),e(i,a,s,"ˋ","\\`"),e(i,a,s,"ˆ","\\^"),e(i,a,s,"˜","\\~"),e(i,a,s,"ˉ","\\="),e(i,a,s,"˘","\\u"),e(i,a,s,"˙","\\."),e(i,a,s,"¸","\\c"),e(i,a,s,"˚","\\r"),e(i,a,s,"ˇ","\\v"),e(i,a,s,"¨",'\\"'),e(i,a,s,"˝","\\H"),e(i,a,s,"◯","\\textcircled"),{"--":!0,"---":!0,"``":!0,"''":!0});e(i,a,x,"–","--",!0),e(i,a,x,"–","\\textendash"),e(i,a,x,"—","---",!0),e(i,a,x,"—","\\textemdash"),e(i,a,x,"‘","`",!0),e(i,a,x,"‘","\\textquoteleft"),e(i,a,x,"’","'",!0),e(i,a,x,"’","\\textquoteright"),e(i,a,x,"“","``",!0),e(i,a,x,"“","\\textquotedblleft"),e(i,a,x,"”","''",!0),e(i,a,x,"”","\\textquotedblright"),e(n,a,x,"°","\\degree",!0),e(i,a,x,"°","\\degree"),e(i,a,x,"°","\\textdegree",!0),e(n,a,x,"£","\\pounds"),e(n,a,x,"£","\\mathsterling",!0),e(i,a,x,"£","\\pounds"),e(i,a,x,"£","\\textsterling",!0),e(n,o,x,"✠","\\maltese"),e(i,o,x,"✠","\\maltese");for(var ot='0123456789/@."',st=0;st<14;st++){var lt=ot[0|st]||"";e(n,a,x,lt,lt)}for(var ht='0123456789!@*()-=+";:?/.,',mt=0;mt<25;mt++){var ct=ht[0|mt]||"";e(i,a,x,ct,ct)}for(var ut="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",pt=0;pt<52;pt++){var dt=ut[0|pt]||"";e(n,a,m,dt,dt),e(i,a,x,dt,dt)}e(n,o,x,"C","ℂ"),e(i,o,x,"C","ℂ"),e(n,o,x,"H","ℍ"),e(i,o,x,"H","ℍ"),e(n,o,x,"N","ℕ"),e(i,o,x,"N","ℕ"),e(n,o,x,"P","ℙ"),e(i,o,x,"P","ℙ"),e(n,o,x,"Q","ℚ"),e(i,o,x,"Q","ℚ"),e(n,o,x,"R","ℝ"),e(i,o,x,"R","ℝ"),e(n,o,x,"Z","ℤ"),e(i,o,x,"Z","ℤ"),e(n,a,m,"h","ℎ"),e(i,a,m,"h","ℎ");for(var v="",w=0;w<52;w++){var k=ut[0|w]||"";e(n,a,m,k,v=String.fromCharCode(55349,56320+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56372+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56424+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56580+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56736+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56788+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56840+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56944+w)),e(i,a,x,k,v),w<26&&(e(n,a,m,k,v=String.fromCharCode(55349,56632+w)),e(i,a,x,k,v),e(n,a,m,k,v=String.fromCharCode(55349,56476+w)),e(i,a,x,k,v))}e(n,a,m,"k",v="𝕜"),e(i,a,x,"k",v);for(var ft=0;ft<10;ft++){var gt=ft.toString();e(n,a,m,gt,v=String.fromCharCode(55349,57294+ft)),e(i,a,x,gt,v),e(n,a,m,gt,v=String.fromCharCode(55349,57314+ft)),e(i,a,x,gt,v),e(n,a,m,gt,v=String.fromCharCode(55349,57324+ft)),e(i,a,x,gt,v),e(n,a,m,gt,v=String.fromCharCode(55349,57334+ft)),e(i,a,x,gt,v)}for(var yt=0;yt<3;yt++){var bt="ÐÞþ"[0|yt]||"";e(n,a,m,bt,bt),e(i,a,x,bt,bt)}function xt(e,t,r){return{value:e=p[r][e]&&p[r][e].replace?p[r][e].replace:e,metrics:C(e,t,r)}}function vt(e,t,r,n,i){var a=(t=xt(e,t,r)).metrics;return e=t.value,r=a?(t=a.italic,("text"===r||n&&"mathit"===n.font)&&(t=0),new b(e,a.height,a.depth,t,a.skew,a.width,i)):new b(e,0,0,0,0,0,i),n&&(r.maxFontSize=n.sizeMultiplier,n.style.isTight()&&r.classes.push("mtight"),t=n.getColor())&&(r.style.color=t),r}function wt(e){for(var t=0,r=0,n=0,i=0;it&&(t=a.height),a.depth>r&&(r=a.depth),a.maxFontSize>n&&(n=a.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n}function S(e,t,r,n){return e=new Ve(e,t,r,n),wt(e),e}function kt(e,t,r,n){return new Ve(e,t,r,n)}function St(e){return e=new Se(e),wt(e),e}function Mt(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")}function zt(e){return"ordgroup"===e.type&&1===e.body.length?e.body[0]:e}function M(e){return"ordgroup"===e.type?e.body:[e]}function ee(e,t,r,n){void 0===n&&(n=[null,null]);for(var i,a,o=[],s=0;s"},u.toText=function(){return this.children.map(function(e){return e.toText()}).join("")},Qt),Zt=((h=Jt.prototype).toNode=function(){return document.createTextNode(this.text)},h.toMarkup=function(){return Z.escape(this.toText())},h.toText=function(){return this.text},Jt),z={MathNode:jt,TextNode:Zt,SpaceNode:((g=Kt.prototype).toNode=function(){var e;return this.character?document.createTextNode(this.character):((e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace")).setAttribute("width",Q(this.width)),e)},g.toMarkup=function(){return this.character?""+this.character+"":''},g.toText=function(){return this.character||" "},Kt),newDocumentFragment:O},A=function(e,t,r){var n;if(1===e.length)return n=T(e[0],t),r&&n instanceof jt&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n];for(var i,a=[],o=0;o but got "+e+".")}(re(e,t)),e.base=r):s=(r=d(e,"accent")).base;var r,n,e=re(s,t.havingCrampedStyle()),i=0;r.isShifty&&Z.isCharacterBox(s)&&(s=Z.getBaseElem(s),i=q(re(s,t.havingCrampedStyle())).skew);var a,o,s="\\c"===r.label,l=s?e.height+e.depth:Math.min(e.height,t.fontMetrics().xHeight),h=r.isStretchy?(h=r0(r,t),te.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:e},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:0"!==e&&"\\gt"!==e&&"⟩"!==e||(e="\\rangle"),c=Z.contains(E0,e)?D0:Z.contains(R0,e)?P0:L0;var o,s,l,h,m,c=x0(e,t,c,n);return"small"===c.type?(o=e,s=c.style,l=r,h=n,m=a,o=te.makeSymbol(o,"Main-Regular",i,h),o=u0(o,s,h,m),l&&p0(o,h,s),o):"large"===c.type?d0(e,c.size,r,n,i,a):y0(e,t,r,n,i,a)}function w0(e,t){var r,n,i,a,o,s,l,h,m=te.wrapFragment(re(e.body,t),t),c=e.label.substr(1),u=t.sizeMultiplier,p=0,d=Z.isCharacterBox(e.body);return"sout"==c?((r=te.makeSpan(["stretchy","sout"])).height=t.fontMetrics().defaultRuleThickness/u,p=-.5*t.fontMetrics().xHeight):"phase"==c?(n=J({number:.6,unit:"pt"},t),o=J({number:.35,unit:"ex"},t),u/=t.havingBaseSizing().sizeMultiplier,i=m.height+m.depth+n+o,m.style.paddingLeft=Q(i/2+n),u=new We([new Xe("phase","M400000 "+(u=Math.floor(1e3*i*u))+" H0 L"+u/2+" 0 l65 45 L145 "+(u-80)+" H400000z")],{width:"400em",height:Q(u/1e3),viewBox:"0 0 400000 "+u,preserveAspectRatio:"xMinYMin slice"}),(r=te.makeSvgSpan(["hide-tail"],[u],t)).style.height=Q(i),p=m.depth+n+o):(/cancel/.test(c)?d||m.classes.push("cancel-pad"):"angl"==c?m.classes.push("anglpad"):m.classes.push("boxpad"),n=i=u=0,i=/box/.test(c)?(n=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),u=t.fontMetrics().fboxsep+("colorbox"==c?0:n)):"angl"==c?(u=4*(n=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness)),Math.max(0,.25-m.depth)):u=d?.2:0,o=c,u=u,h=i,s=t,a=(a=m).height+a.depth+u+h,/fbox|color|angl/.test(o)?(l=te.makeSpan(["stretchy",o],[],s),"fbox"===o&&(u=s.color&&s.getColor())&&(l.style.borderColor=u)):(h=[],/^[bx]cancel$/.test(o)&&h.push(new _e({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(o)&&h.push(new _e({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"})),u=new We(h,{width:"100%",height:Q(a)}),l=te.makeSvgSpan([],[u],s)),l.height=a,l.style.height=Q(a),r=l,/fbox|boxed|fcolorbox/.test(c)?(r.style.borderStyle="solid",r.style.borderWidth=Q(n)):"angl"==c&&.049!==n&&(r.style.borderTopWidth=Q(n),r.style.borderRightWidth=Q(n)),p=m.depth+i,e.backgroundColor&&(r.style.backgroundColor=e.backgroundColor,e.borderColor)&&(r.style.borderColor=e.borderColor)),h=e.backgroundColor?te.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:p},{type:"elem",elem:m,shift:0}]},t):te.makeVList({positionType:"individualShift",children:[{type:"elem",elem:m,shift:0},{type:"elem",elem:r,shift:p,wrapperClasses:/cancel|phase/.test(c)?["svg-align"]:[]}]},t),/cancel/.test(c)&&(h.height=m.height,h.depth=m.depth),/cancel/.test(c)&&!d?te.makeSpan(["mord","cancel-lap"],[h],t):te.makeSpan(["mord"],[h],t)}function k0(e,t){var r=new z.MathNode(~e.label.indexOf("colorbox")?"mpadded":"menclose",[T(e.body,t)]);switch(e.label){case"\\cancel":r.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":r.setAttribute("notation","downdiagonalstrike");break;case"\\phase":r.setAttribute("notation","phasorangle");break;case"\\sout":r.setAttribute("notation","horizontalstrike");break;case"\\fbox":r.setAttribute("notation","box");break;case"\\angl":r.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":var n=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm;r.setAttribute("width","+"+2*n+"pt"),r.setAttribute("height","+"+2*n+"pt"),r.setAttribute("lspace",n+"pt"),r.setAttribute("voffset",n+"pt"),"\\fcolorbox"===e.label&&(n=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),r.setAttribute("style","border: "+n+"em solid "+e.borderColor));break;case"\\xcancel":r.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&r.setAttribute("mathbackground",e.backgroundColor),r}var S0=function(e){return new Le({style:e.displayMode?K.DISPLAY:K.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},M0=function(e,t){var r;return t.displayMode&&(r=["katex-display"],t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=te.makeSpan(r,[e])),e},z0={widehat:"^",widecheck:"ˇ",widetilde:"~",utilde:"~",overleftarrow:"←",underleftarrow:"←",xleftarrow:"←",overrightarrow:"→",underrightarrow:"→",xrightarrow:"→",underbrace:"⏟",overbrace:"⏞",overgroup:"⏠",undergroup:"⏡",overleftrightarrow:"↔",underleftrightarrow:"↔",xleftrightarrow:"↔",Overrightarrow:"⇒",xRightarrow:"⇒",overleftharpoon:"↼",xleftharpoonup:"↼",overrightharpoon:"⇀",xrightharpoonup:"⇀",xLeftarrow:"⇐",xLeftrightarrow:"⇔",xhookleftarrow:"↩",xhookrightarrow:"↪",xmapsto:"↦",xrightharpoondown:"⇁",xleftharpoondown:"↽",xrightleftharpoons:"⇌",xleftrightharpoons:"⇋",xtwoheadleftarrow:"↞",xtwoheadrightarrow:"↠",xlongequal:"=",xtofrom:"⇄",xrightleftarrows:"⇄",xrightequilibrium:"⇌",xleftequilibrium:"⇋","\\cdrightarrow":"→","\\cdleftarrow":"←","\\cdlongequal":"="},A0={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},T0=RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(function(e){return"\\"+e}).join("|")),B0=(t({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var t=zt(t[0]),r=!T0.test(e.funcName),n=!r||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:r,isShifty:n,base:t}},htmlBuilder:n0,mathmlBuilder:i0}),t({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var t=t[0],r=e.parser.mode;return"math"===r&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),r="text"),{type:"accent",mode:r,label:e.funcName,isStretchy:!1,isShifty:!0,base:t}},htmlBuilder:n0,mathmlBuilder:i0}),t({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,e=e.funcName,t=t[0];return{type:"accentUnder",mode:r.mode,label:e,base:t}},htmlBuilder:function(e,t){var r=re(e.base,t),n=r0(e,t),e="\\utilde"===e.label?.12:0,n=te.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:e},{type:"elem",elem:r}]},t);return te.makeSpan(["mord","accentunder"],[n],t)},mathmlBuilder:function(e,t){var r=t0(e.label),e=new z.MathNode("munder",[T(e.base,t),r]);return e.setAttribute("accentunder","true"),e}}),t({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,e=e.funcName;return{type:"xArrow",mode:n.mode,label:e,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r=t.style,n=t.havingStyle(r.sup()),i=te.wrapFragment(re(e.body,n,t),t),a="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(a+"-arrow-pad"),e.below&&(n=t.havingStyle(r.sub()),(o=te.wrapFragment(re(e.below,n,t),t)).classes.push(a+"-arrow-pad"));var o,r=r0(e,t),n=-t.fontMetrics().axisHeight+.5*r.height,a=-t.fontMetrics().axisHeight-.5*r.height-.111;return i.depth<=.25&&"\\xleftequilibrium"!==e.label||(a-=i.depth),(o=o?(e=-t.fontMetrics().axisHeight+o.height+.5*r.height+.111,te.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:a},{type:"elem",elem:r,shift:n},{type:"elem",elem:o,shift:e}]},t)):te.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:a},{type:"elem",elem:r,shift:n}]},t)).children[0].children[0].children[1].classes.push("svg-align"),te.makeSpan(["mrel","x-arrow"],[o],t)},mathmlBuilder:function(e,t){var r,n,i,a=t0(e.label);return a.setAttribute("minsize","x"==(e.label[0]||"")?"1.75em":"3.0em"),n=e.body?(r=a0(T(e.body,t)),e.below?(i=a0(T(e.below,t)),new z.MathNode("munderover",[a,i,r])):new z.MathNode("mover",[a,r])):e.below?(i=a0(T(e.below,t)),new z.MathNode("munder",[a,i])):(n=a0(),new z.MathNode("mover",[a,n]))}}),{">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"}),C0=(t({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,e=e.funcName;return{type:"cdlabel",mode:r.mode,side:e.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),r=te.wrapFragment(re(e.label,r,t),t);return r.classes.push("cd-label-"+e.side),r.style.bottom=Q(.8-r.depth),r.height=0,r.depth=0,r},mathmlBuilder:function(e,t){t=new z.MathNode("mrow",[T(e.label,t)]);return(t=new z.MathNode("mpadded",[t])).setAttribute("width","0"),"left"===e.side&&t.setAttribute("lspace","-1width"),t.setAttribute("voffset","0.7em"),(t=new z.MathNode("mstyle",[t])).setAttribute("displaystyle","false"),t.setAttribute("scriptlevel","1"),t}}),t({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){e=te.wrapFragment(re(e.fragment,t),t);return e.classes.push("cd-vert-arrow"),e},mathmlBuilder:function(e,t){return new z.MathNode("mrow",[T(e.fragment,t)])}}),t({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var e=e.parser,r=d(t[0],"ordgroup").body,n="",i=0;i>10),56320+(1023&t)):String.fromCharCode(t),{type:"textord",mode:e.mode,text:t}}}),t({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var e=e.parser,r=d(t[0],"color-token").color,t=t[1];return{type:"color",mode:e.mode,color:r,body:M(t)}},htmlBuilder:s0,mathmlBuilder:l0}),t({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,e=e.breakOnTokenText,t=d(t[0],"color-token").color,e=(r.gullet.macros.set("\\current@color",t),r.parseExpression(!0,e));return{type:"color",mode:r.mode,color:t,body:e}},htmlBuilder:s0,mathmlBuilder:l0}),t({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var e=e.parser,r=r[0],n=!e.settings.displayMode||!e.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:e.mode,newLine:n,size:r&&d(r,"size").value}},htmlBuilder:function(e,t){var r=te.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size)&&(r.style.marginTop=Q(J(e.size,t))),r},mathmlBuilder:function(e,t){var r=new z.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size)&&r.setAttribute("height",Q(J(e.size,t))),r}}),{"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"}),q0=(t({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,e=e.funcName,r=(t.consumeSpaces(),t.fetch());if(C0[r.text])return"\\global"!==e&&"\\\\globallong"!==e||(r.text=C0[r.text]),d(t.parseFunction(),"internal");throw new j("Invalid token after macro prefix",r)}}),t({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,e=e.funcName,r=t.gullet.popToken(),n=r.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new j("Expected a control sequence",r);for(var i,a=0,o=[[]];"{"!==t.gullet.future().text;)if("#"===(r=t.gullet.popToken()).text){if("{"===t.gullet.future().text){i=t.gullet.future(),o[a].push("{");break}if(r=t.gullet.popToken(),!/^[1-9]$/.test(r.text))throw new j('Invalid argument number "'+r.text+'"');if(parseInt(r.text)!==a+1)throw new j('Argument number "'+r.text+'" out of order');a++,o.push([])}else{if("EOF"===r.text)throw new j("Expected a macro definition");o[a].push(r.text)}var s=t.gullet.consumeArg().tokens;return i&&s.unshift(i),"\\edef"!==e&&"\\xdef"!==e||(s=t.gullet.expandTokens(s)).reverse(),t.gullet.macros.set(n,{tokens:s,numArgs:a,delimiters:o},e===C0[e]),{type:"internal",mode:t.mode}}}),t({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t,r,n=e.parser,e=e.funcName,i=h0(n.gullet.popToken());n.gullet.consumeSpaces(),r="="===(r=(t=n).gullet.popToken()).text&&" "===(r=t.gullet.popToken()).text?t.gullet.popToken():r;return m0(n,i,r,"\\\\globallet"===e),{type:"internal",mode:n.mode}}}),t({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,e=e.funcName,r=h0(t.gullet.popToken()),n=t.gullet.popToken(),i=t.gullet.popToken();return m0(t,r,i,"\\\\globalfuture"===e),t.gullet.pushToken(i),t.gullet.pushToken(n),{type:"internal",mode:t.mode}}}),{type:"kern",size:-.008}),N0=["|","\\lvert","\\rvert","\\vert"],I0=["\\|","\\lVert","\\rVert","\\Vert"],R0=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","\\surd"],O0=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱"],E0=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],H0=[0,1.2,1.8,2.4,3],D0=[{type:"small",style:K.SCRIPTSCRIPT},{type:"small",style:K.SCRIPT},{type:"small",style:K.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],L0=[{type:"small",style:K.SCRIPTSCRIPT},{type:"small",style:K.SCRIPT},{type:"small",style:K.TEXT},{type:"stack"}],P0=[{type:"small",style:K.SCRIPTSCRIPT},{type:"small",style:K.SCRIPT},{type:"small",style:K.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],F0={sqrtImage:function(e,t){var r,n=t.havingBaseSizing(),i=x0("\\surd",e*n.sizeMultiplier,P0,n),n=n.sizeMultiplier,a=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),o=0,s=0,l=0,i="small"===i.type?(e<1?n=1:e<1.4&&(n=.7),s=(1+a)/n,(r=b0("sqrtMain",o=(1.08+a)/n,l=1080+1e3*a,a,t)).style.minWidth="0.853em",.833/n):"large"===i.type?(l=1080*H0[i.size],s=(H0[i.size]+a)/n,o=(H0[i.size]+a+.08)/n,(r=b0("sqrtSize"+i.size,o,l,a,t)).style.minWidth="1.02em",1/n):((r=b0("sqrtTall",o=(s=e+a)+.08,l=80+Math.floor(1e3*e+a),a,t)).style.minWidth="0.742em",1.056);return r.height=s,r.style.height=Q(o),{span:r,advanceWidth:i,ruleWidth:(t.fontMetrics().sqrtRuleThickness+a)*n}},sizedDelim:function(e,t,r,n,i){if("<"===e||"\\lt"===e||"⟨"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"⟩"!==e||(e="\\rangle"),Z.contains(R0,e)||Z.contains(E0,e))return d0(e,t,!1,r,n,i);if(Z.contains(O0,e))return y0(e,H0[t],!1,r,n,i);throw new j("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:H0,customSizedDelim:v0,leftRightDelim:function(e,t,r,n,i,a){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,t=Math.max(t-o,r+o);return v0(e,Math.max(t/500*901,2*t-s),!0,n,i,a)}},V0={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},G0=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","<",">","\\langle","⟨","\\rangle","⟩","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."],U0=(t({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){t=L(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:V0[e.funcName].size,mclass:V0[e.funcName].mclass,delim:t.text}},htmlBuilder:function(e,t){return"."===e.delim?te.makeSpan([e.mclass]):F0.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[],t=("."!==e.delim&&t.push(Bt(e.delim,e.mode)),new z.MathNode("mo",t)),e=("mopen"===e.mclass||"mclose"===e.mclass?t.setAttribute("fence","true"):t.setAttribute("fence","false"),t.setAttribute("stretchy","true"),Q(F0.sizeToMaxHeight[e.size]));return t.setAttribute("minsize",e),t.setAttribute("maxsize",e),t}}),t({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new j("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:L(t[0],e).text,color:r}}}),t({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var t=L(t[0],e),e=e.parser,r=(++e.leftrightDepth,e.parseExpression(!1)),n=(--e.leftrightDepth,e.expect("\\right",!1),d(e.parseFunction(),"leftright-right"));return{type:"leftright",mode:e.mode,body:r,left:t.text,right:n.delim,rightColor:n.color}},htmlBuilder:function(e,t){P(e);for(var r,n=ee(e.body,t,!0,["mopen","mclose"]),i=0,a=0,o=!1,s=0;sf){for(var q=void 0,N=((0AV".indexOf(c))throw new j('Expected one of "<>AV=|." after @',l[m]);for(var p=0;p<2;p++){for(var d=!0,f=m+1;fr.height+r.depth+i&&(i=(i+s-r.height-r.depth)/2),a.height-r.height-i-o),i=(r.style.paddingLeft=Q(n),te.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+s)},{type:"elem",elem:a},{type:"kern",size:o}]},t));return e.index?(n=t.havingStyle(K.SCRIPTSCRIPT),r=re(e.index,n,t),s=.6*(i.height-i.depth),a=te.makeVList({positionType:"shift",positionData:-s,children:[{type:"elem",elem:r}]},t),o=te.makeSpan(["root"],[a]),te.makeSpan(["mord","sqrt"],[o,i],t)):te.makeSpan(["mord","sqrt"],[i],t)},mathmlBuilder:function(e,t){var r=e.body,e=e.index;return e?new z.MathNode("mroot",[T(r,t),T(e,t)]):new z.MathNode("msqrt",[T(r,t)])}}),{display:K.DISPLAY,text:K.TEXT,script:K.SCRIPT,scriptscript:K.SCRIPTSCRIPT}),zr=(t({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,e=e.parser,r=e.parseExpression(!0,r),n=n.slice(1,n.length-5);return{type:"styling",mode:e.mode,style:n,body:r}},htmlBuilder:function(e,t){var r=Mr[e.style],r=t.havingStyle(r).withFont("");return _(e.body,r,t)},mathmlBuilder:function(e,t){var r=Mr[e.style],t=t.havingStyle(r),r=A(e.body,t),t=new z.MathNode("mstyle",r),r={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return t.setAttribute("scriptlevel",r[0]),t.setAttribute("displaystyle",r[1]),t}}),N({type:"supsub",htmlBuilder:function(e,t){r=t;var r=(o=(a=e).base)?"op"===o.type?o.limits&&(r.style.size===K.DISPLAY.size||o.alwaysHandleSupSub)?mr:null:"operatorname"===o.type?o.alwaysHandleSupSub&&(r.style.size===K.DISPLAY.size||o.limits)?ur:null:"accent"===o.type?Z.isCharacterBox(o.base)?n0:null:"horizBrace"===o.type&&!a.sub===o.isOver?or:null:null;if(r)return r(e,t);var n,i,a=e.base,o=e.sup,r=e.sub,s=re(a,t),l=t.fontMetrics(),h=0,m=0,a=a&&Z.isCharacterBox(a),c=(o&&(c=t.havingStyle(t.style.sup()),n=re(o,c,t),a||(h=s.height-c.fontMetrics().supDrop*c.sizeMultiplier/t.sizeMultiplier)),r&&(o=t.havingStyle(t.style.sub()),i=re(r,o,t),a||(m=s.depth+o.fontMetrics().subDrop*o.sizeMultiplier/t.sizeMultiplier)),t.style===K.DISPLAY?l.sup1:t.style.cramped?l.sup3:l.sup2),r=t.sizeMultiplier,a=Q(.5/l.ptPerEm/r),o=null;if(i&&(r=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name),s instanceof b||r)&&(o=Q(-s.italic)),n&&i){h=Math.max(h,c,n.depth+.25*l.xHeight),m=Math.max(m,l.sub2);e=4*l.defaultRuleThickness;h-n.depth-(i.height-m)":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"}),Ur=(r("\\dots",function(e){var t="\\dotso",e=e.expandAfterFuture().text;return e in Gr?t=Gr[e]:("\\not"==e.substr(0,4)||e in p.math&&Z.contains(["bin","rel"],p.math[e].group))&&(t="\\dotsb"),t}),{")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0}),s=(r("\\dotso",function(e){return e.future().text in Ur?"\\ldots\\,":"\\ldots"}),r("\\dotsc",function(e){e=e.future().text;return e in Ur&&","!==e?"\\ldots\\,":"\\ldots"}),r("\\cdots",function(e){return e.future().text in Ur?"\\@cdots\\,":"\\@cdots"}),r("\\dotsb","\\cdots"),r("\\dotsm","\\cdots"),r("\\dotsi","\\!\\cdots"),r("\\dotsx","\\ldots\\,"),r("\\DOTSI","\\relax"),r("\\DOTSB","\\relax"),r("\\DOTSX","\\relax"),r("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),r("\\,","\\tmspace+{3mu}{.1667em}"),r("\\thinspace","\\,"),r("\\>","\\mskip{4mu}"),r("\\:","\\tmspace+{4mu}{.2222em}"),r("\\medspace","\\:"),r("\\;","\\tmspace+{5mu}{.2777em}"),r("\\thickspace","\\;"),r("\\!","\\tmspace-{3mu}{.1667em}"),r("\\negthinspace","\\!"),r("\\negmedspace","\\tmspace-{4mu}{.2222em}"),r("\\negthickspace","\\tmspace-{5mu}{.277em}"),r("\\enspace","\\kern.5em "),r("\\enskip","\\hskip.5em\\relax"),r("\\quad","\\hskip1em\\relax"),r("\\qquad","\\hskip2em\\relax"),r("\\tag","\\@ifstar\\tag@literal\\tag@paren"),r("\\tag@paren","\\tag@literal{({#1})}"),r("\\tag@literal",function(e){if(e.macros.get("\\df@tag"))throw new j("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"}),r("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),r("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),r("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),r("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),r("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),r("\\newline","\\\\\\relax"),r("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}"),Q(Me["Main-Regular"][84][1]-.7*Me["Main-Regular"][65][1])),Yr=(r("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+s+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),r("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+s+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),r("\\hspace","\\@ifstar\\@hspacer\\@hspace"),r("\\@hspace","\\hskip #1\\relax"),r("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),r("\\ordinarycolon",":"),r("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),r("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),r("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),r("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),r("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),r("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),r("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),r("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),r("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),r("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),r("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),r("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),r("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),r("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),r("∷","\\dblcolon"),r("∹","\\eqcolon"),r("≔","\\coloneqq"),r("≕","\\eqqcolon"),r("⩴","\\Coloneqq"),r("\\ratio","\\vcentcolon"),r("\\coloncolon","\\dblcolon"),r("\\colonequals","\\coloneqq"),r("\\coloncolonequals","\\Coloneqq"),r("\\equalscolon","\\eqqcolon"),r("\\equalscoloncolon","\\Eqqcolon"),r("\\colonminus","\\coloneq"),r("\\coloncolonminus","\\Coloneq"),r("\\minuscolon","\\eqcolon"),r("\\minuscoloncolon","\\Eqcolon"),r("\\coloncolonapprox","\\Colonapprox"),r("\\coloncolonsim","\\Colonsim"),r("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),r("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),r("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),r("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),r("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`∌}}"),r("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),r("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),r("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),r("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),r("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),r("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),r("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),r("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),r("\\gvertneqq","\\html@mathml{\\@gvertneqq}{≩}"),r("\\lvertneqq","\\html@mathml{\\@lvertneqq}{≨}"),r("\\ngeqq","\\html@mathml{\\@ngeqq}{≱}"),r("\\ngeqslant","\\html@mathml{\\@ngeqslant}{≱}"),r("\\nleqq","\\html@mathml{\\@nleqq}{≰}"),r("\\nleqslant","\\html@mathml{\\@nleqslant}{≰}"),r("\\nshortmid","\\html@mathml{\\@nshortmid}{∤}"),r("\\nshortparallel","\\html@mathml{\\@nshortparallel}{∦}"),r("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{⊈}"),r("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{⊉}"),r("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{⊊}"),r("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{⫋}"),r("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{⊋}"),r("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{⫌}"),r("\\imath","\\html@mathml{\\@imath}{ı}"),r("\\jmath","\\html@mathml{\\@jmath}{ȷ}"),r("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`⟦}}"),r("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`⟧}}"),r("⟦","\\llbracket"),r("⟧","\\rrbracket"),r("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`⦃}}"),r("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`⦄}}"),r("⦃","\\lBrace"),r("⦄","\\rBrace"),r("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`⦵}}"),r("⦵","\\minuso"),r("\\darr","\\downarrow"),r("\\dArr","\\Downarrow"),r("\\Darr","\\Downarrow"),r("\\lang","\\langle"),r("\\rang","\\rangle"),r("\\uarr","\\uparrow"),r("\\uArr","\\Uparrow"),r("\\Uarr","\\Uparrow"),r("\\N","\\mathbb{N}"),r("\\R","\\mathbb{R}"),r("\\Z","\\mathbb{Z}"),r("\\alef","\\aleph"),r("\\alefsym","\\aleph"),r("\\Alpha","\\mathrm{A}"),r("\\Beta","\\mathrm{B}"),r("\\bull","\\bullet"),r("\\Chi","\\mathrm{X}"),r("\\clubs","\\clubsuit"),r("\\cnums","\\mathbb{C}"),r("\\Complex","\\mathbb{C}"),r("\\Dagger","\\ddagger"),r("\\diamonds","\\diamondsuit"),r("\\empty","\\emptyset"),r("\\Epsilon","\\mathrm{E}"),r("\\Eta","\\mathrm{H}"),r("\\exist","\\exists"),r("\\harr","\\leftrightarrow"),r("\\hArr","\\Leftrightarrow"),r("\\Harr","\\Leftrightarrow"),r("\\hearts","\\heartsuit"),r("\\image","\\Im"),r("\\infin","\\infty"),r("\\Iota","\\mathrm{I}"),r("\\isin","\\in"),r("\\Kappa","\\mathrm{K}"),r("\\larr","\\leftarrow"),r("\\lArr","\\Leftarrow"),r("\\Larr","\\Leftarrow"),r("\\lrarr","\\leftrightarrow"),r("\\lrArr","\\Leftrightarrow"),r("\\Lrarr","\\Leftrightarrow"),r("\\Mu","\\mathrm{M}"),r("\\natnums","\\mathbb{N}"),r("\\Nu","\\mathrm{N}"),r("\\Omicron","\\mathrm{O}"),r("\\plusmn","\\pm"),r("\\rarr","\\rightarrow"),r("\\rArr","\\Rightarrow"),r("\\Rarr","\\Rightarrow"),r("\\real","\\Re"),r("\\reals","\\mathbb{R}"),r("\\Reals","\\mathbb{R}"),r("\\Rho","\\mathrm{P}"),r("\\sdot","\\cdot"),r("\\sect","\\S"),r("\\spades","\\spadesuit"),r("\\sub","\\subset"),r("\\sube","\\subseteq"),r("\\supe","\\supseteq"),r("\\Tau","\\mathrm{T}"),r("\\thetasym","\\vartheta"),r("\\weierp","\\wp"),r("\\Zeta","\\mathrm{Z}"),r("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),r("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),r("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),r("\\bra","\\mathinner{\\langle{#1}|}"),r("\\ket","\\mathinner{|{#1}\\rangle}"),r("\\braket","\\mathinner{\\langle{#1}\\rangle}"),r("\\Bra","\\left\\langle#1\\right|"),r("\\Ket","\\left|#1\\right\\rangle"),r("\\bra@ket",Fr(!1)),r("\\bra@set",Fr(!0)),r("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),r("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),r("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),r("\\angln","{\\angl n}"),r("\\blue","\\textcolor{##6495ed}{#1}"),r("\\orange","\\textcolor{##ffa500}{#1}"),r("\\pink","\\textcolor{##ff00af}{#1}"),r("\\red","\\textcolor{##df0030}{#1}"),r("\\green","\\textcolor{##28ae7b}{#1}"),r("\\gray","\\textcolor{gray}{#1}"),r("\\purple","\\textcolor{##9d38bd}{#1}"),r("\\blueA","\\textcolor{##ccfaff}{#1}"),r("\\blueB","\\textcolor{##80f6ff}{#1}"),r("\\blueC","\\textcolor{##63d9ea}{#1}"),r("\\blueD","\\textcolor{##11accd}{#1}"),r("\\blueE","\\textcolor{##0c7f99}{#1}"),r("\\tealA","\\textcolor{##94fff5}{#1}"),r("\\tealB","\\textcolor{##26edd5}{#1}"),r("\\tealC","\\textcolor{##01d1c1}{#1}"),r("\\tealD","\\textcolor{##01a995}{#1}"),r("\\tealE","\\textcolor{##208170}{#1}"),r("\\greenA","\\textcolor{##b6ffb0}{#1}"),r("\\greenB","\\textcolor{##8af281}{#1}"),r("\\greenC","\\textcolor{##74cf70}{#1}"),r("\\greenD","\\textcolor{##1fab54}{#1}"),r("\\greenE","\\textcolor{##0d923f}{#1}"),r("\\goldA","\\textcolor{##ffd0a9}{#1}"),r("\\goldB","\\textcolor{##ffbb71}{#1}"),r("\\goldC","\\textcolor{##ff9c39}{#1}"),r("\\goldD","\\textcolor{##e07d10}{#1}"),r("\\goldE","\\textcolor{##a75a05}{#1}"),r("\\redA","\\textcolor{##fca9a9}{#1}"),r("\\redB","\\textcolor{##ff8482}{#1}"),r("\\redC","\\textcolor{##f9685d}{#1}"),r("\\redD","\\textcolor{##e84d39}{#1}"),r("\\redE","\\textcolor{##bc2612}{#1}"),r("\\maroonA","\\textcolor{##ffbde0}{#1}"),r("\\maroonB","\\textcolor{##ff92c6}{#1}"),r("\\maroonC","\\textcolor{##ed5fa6}{#1}"),r("\\maroonD","\\textcolor{##ca337c}{#1}"),r("\\maroonE","\\textcolor{##9e034e}{#1}"),r("\\purpleA","\\textcolor{##ddd7ff}{#1}"),r("\\purpleB","\\textcolor{##c6b9fc}{#1}"),r("\\purpleC","\\textcolor{##aa87ff}{#1}"),r("\\purpleD","\\textcolor{##7854ab}{#1}"),r("\\purpleE","\\textcolor{##543b78}{#1}"),r("\\mintA","\\textcolor{##f5f9e8}{#1}"),r("\\mintB","\\textcolor{##edf2df}{#1}"),r("\\mintC","\\textcolor{##e0e5cc}{#1}"),r("\\grayA","\\textcolor{##f6f7f7}{#1}"),r("\\grayB","\\textcolor{##f0f1f2}{#1}"),r("\\grayC","\\textcolor{##e3e5e6}{#1}"),r("\\grayD","\\textcolor{##d6d8da}{#1}"),r("\\grayE","\\textcolor{##babec2}{#1}"),r("\\grayF","\\textcolor{##888d93}{#1}"),r("\\grayG","\\textcolor{##626569}{#1}"),r("\\grayH","\\textcolor{##3b3e40}{#1}"),r("\\grayI","\\textcolor{##21242c}{#1}"),r("\\kaBlue","\\textcolor{##314453}{#1}"),r("\\kaGreen","\\textcolor{##71B307}{#1}"),{"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0}),Wr=((o=Jr.prototype).feed=function(e){this.lexer=new Or(e,this.settings)},o.switchMode=function(e){this.mode=e},o.beginGroup=function(){this.macros.beginGroup()},o.endGroup=function(){this.macros.endGroup()},o.endGroups=function(){this.macros.endGroups()},o.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},o.popToken=function(){return this.future(),this.stack.pop()},o.pushToken=function(e){this.stack.push(e)},o.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},o.scanArgument=function(e){if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;var t=this.popToken(),e=this.consumeArg(["]"]),r=e.tokens,n=e.end}else{e=this.consumeArg();r=e.tokens,t=e.start,n=e.end}return this.pushToken(new X0("EOF",n.loc)),this.pushTokens(r),t.range(n,"")},o.consumeSpaces=function(){for(;" "===this.future().text;)this.stack.pop()},o.consumeArg=function(e){var t=[],r=e&&0this.settings.maxExpand)throw new j("Too many expansions: infinite loop or need to increase maxExpand setting");var i=n.tokens,a=this.consumeArgs(n.numArgs,n.delimiters);if(n.numArgs)for(var o=(i=i.slice()).length-1;0<=o;--o){var s=i[o];if("#"===s.text){if(0===o)throw new j("Incomplete placeholder at end of macro body",s);if("#"===(s=i[--o]).text)i.splice(o+1,1);else{if(!/^[1-9]$/.test(s.text))throw new j("Not a valid argument number",s);i.splice.apply(i,[o,2].concat(a[+s.text-1]))}}}return this.pushTokens(i),i},o.expandAfterFuture=function(){return this.expandOnce(),this.future()},o.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof X0)return e.treatAsRelax&&(e.text="\\relax"),this.stack.pop()}throw Error()},o.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new X0(e)]):void 0},o.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof X0&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},o.expandMacroAsText=function(e){e=this.expandMacro(e);return e&&e.map(function(e){return e.text}).join("")},o._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){e=this.lexer.catcodes[e];if(null!=e&&13!==e)return}e="function"==typeof t?t(this):t;if("string"!=typeof e)return e;var r=0;if(~e.indexOf("#"))for(var n=e.replace(/##/g,"");~n.indexOf("#"+(r+1));)++r;for(var i=new Or(e,this.settings),a=[],o=i.lex();"EOF"!==o.text;)a.push(o),o=i.lex();return a.reverse(),{tokens:a,numArgs:r}},o.isDefined=function(e){return this.macros.has(e)||Ir.hasOwnProperty(e)||p.math.hasOwnProperty(e)||p.text.hasOwnProperty(e)||Yr.hasOwnProperty(e)},o.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Ir.hasOwnProperty(e)&&!Ir[e].primitive},Jr),Xr=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,_r=Object.freeze({"₊":"+","₋":"-","₌":"=","₍":"(","₎":")","₀":"0","₁":"1","₂":"2","₃":"3","₄":"4","₅":"5","₆":"6","₇":"7","₈":"8","₉":"9","ₐ":"a","ₑ":"e","ₕ":"h","ᵢ":"i","ⱼ":"j","ₖ":"k","ₗ":"l","ₘ":"m","ₙ":"n","ₒ":"o","ₚ":"p","ᵣ":"r","ₛ":"s","ₜ":"t","ᵤ":"u","ᵥ":"v","ₓ":"x","ᵦ":"β","ᵧ":"γ","ᵨ":"ρ","ᵩ":"ϕ","ᵪ":"χ","⁺":"+","⁻":"-","⁼":"=","⁽":"(","⁾":")","⁰":"0","¹":"1","²":"2","³":"3","⁴":"4","⁵":"5","⁶":"6","⁷":"7","⁸":"8","⁹":"9","ᴬ":"A","ᴮ":"B","ᴰ":"D","ᴱ":"E","ᴳ":"G","ᴴ":"H","ᴵ":"I","ᴶ":"J","ᴷ":"K","ᴸ":"L","ᴹ":"M","ᴺ":"N","ᴼ":"O","ᴾ":"P","ᴿ":"R","ᵀ":"T","ᵁ":"U","ⱽ":"V","ᵂ":"W","ᵃ":"a","ᵇ":"b","ᶜ":"c","ᵈ":"d","ᵉ":"e","ᶠ":"f","ᵍ":"g","ʰ":"h","ⁱ":"i","ʲ":"j","ᵏ":"k","ˡ":"l","ᵐ":"m","ⁿ":"n","ᵒ":"o","ᵖ":"p","ʳ":"r","ˢ":"s","ᵗ":"t","ᵘ":"u","ᵛ":"v","ʷ":"w","ˣ":"x","ʸ":"y","ᶻ":"z","ᵝ":"β","ᵞ":"γ","ᵟ":"δ","ᵠ":"ϕ","ᵡ":"χ","ᶿ":"θ"}),$r={"́":{text:"\\'",math:"\\acute"},"̀":{text:"\\`",math:"\\grave"},"̈":{text:'\\"',math:"\\ddot"},"̃":{text:"\\~",math:"\\tilde"},"̄":{text:"\\=",math:"\\bar"},"̆":{text:"\\u",math:"\\breve"},"̌":{text:"\\v",math:"\\check"},"̂":{text:"\\^",math:"\\hat"},"̇":{text:"\\.",math:"\\dot"},"̊":{text:"\\r",math:"\\mathring"},"̋":{text:"\\H"},"̧":{text:"\\c"}},jr={"á":"á","à":"à","ä":"ä","ǟ":"ǟ","ã":"ã","ā":"ā","ă":"ă","ắ":"ắ","ằ":"ằ","ẵ":"ẵ","ǎ":"ǎ","â":"â","ấ":"ấ","ầ":"ầ","ẫ":"ẫ","ȧ":"ȧ","ǡ":"ǡ","å":"å","ǻ":"ǻ","ḃ":"ḃ","ć":"ć","ḉ":"ḉ","č":"č","ĉ":"ĉ","ċ":"ċ","ç":"ç","ď":"ď","ḋ":"ḋ","ḑ":"ḑ","é":"é","è":"è","ë":"ë","ẽ":"ẽ","ē":"ē","ḗ":"ḗ","ḕ":"ḕ","ĕ":"ĕ","ḝ":"ḝ","ě":"ě","ê":"ê","ế":"ế","ề":"ề","ễ":"ễ","ė":"ė","ȩ":"ȩ","ḟ":"ḟ","ǵ":"ǵ","ḡ":"ḡ","ğ":"ğ","ǧ":"ǧ","ĝ":"ĝ","ġ":"ġ","ģ":"ģ","ḧ":"ḧ","ȟ":"ȟ","ĥ":"ĥ","ḣ":"ḣ","ḩ":"ḩ","í":"í","ì":"ì","ï":"ï","ḯ":"ḯ","ĩ":"ĩ","ī":"ī","ĭ":"ĭ","ǐ":"ǐ","î":"î","ǰ":"ǰ","ĵ":"ĵ","ḱ":"ḱ","ǩ":"ǩ","ķ":"ķ","ĺ":"ĺ","ľ":"ľ","ļ":"ļ","ḿ":"ḿ","ṁ":"ṁ","ń":"ń","ǹ":"ǹ","ñ":"ñ","ň":"ň","ṅ":"ṅ","ņ":"ņ","ó":"ó","ò":"ò","ö":"ö","ȫ":"ȫ","õ":"õ","ṍ":"ṍ","ṏ":"ṏ","ȭ":"ȭ","ō":"ō","ṓ":"ṓ","ṑ":"ṑ","ŏ":"ŏ","ǒ":"ǒ","ô":"ô","ố":"ố","ồ":"ồ","ỗ":"ỗ","ȯ":"ȯ","ȱ":"ȱ","ő":"ő","ṕ":"ṕ","ṗ":"ṗ","ŕ":"ŕ","ř":"ř","ṙ":"ṙ","ŗ":"ŗ","ś":"ś","ṥ":"ṥ","š":"š","ṧ":"ṧ","ŝ":"ŝ","ṡ":"ṡ","ş":"ş","ẗ":"ẗ","ť":"ť","ṫ":"ṫ","ţ":"ţ","ú":"ú","ù":"ù","ü":"ü","ǘ":"ǘ","ǜ":"ǜ","ǖ":"ǖ","ǚ":"ǚ","ũ":"ũ","ṹ":"ṹ","ū":"ū","ṻ":"ṻ","ŭ":"ŭ","ǔ":"ǔ","û":"û","ů":"ů","ű":"ű","ṽ":"ṽ","ẃ":"ẃ","ẁ":"ẁ","ẅ":"ẅ","ŵ":"ŵ","ẇ":"ẇ","ẘ":"ẘ","ẍ":"ẍ","ẋ":"ẋ","ý":"ý","ỳ":"ỳ","ÿ":"ÿ","ỹ":"ỹ","ȳ":"ȳ","ŷ":"ŷ","ẏ":"ẏ","ẙ":"ẙ","ź":"ź","ž":"ž","ẑ":"ẑ","ż":"ż","Á":"Á","À":"À","Ä":"Ä","Ǟ":"Ǟ","Ã":"Ã","Ā":"Ā","Ă":"Ă","Ắ":"Ắ","Ằ":"Ằ","Ẵ":"Ẵ","Ǎ":"Ǎ","Â":"Â","Ấ":"Ấ","Ầ":"Ầ","Ẫ":"Ẫ","Ȧ":"Ȧ","Ǡ":"Ǡ","Å":"Å","Ǻ":"Ǻ","Ḃ":"Ḃ","Ć":"Ć","Ḉ":"Ḉ","Č":"Č","Ĉ":"Ĉ","Ċ":"Ċ","Ç":"Ç","Ď":"Ď","Ḋ":"Ḋ","Ḑ":"Ḑ","É":"É","È":"È","Ë":"Ë","Ẽ":"Ẽ","Ē":"Ē","Ḗ":"Ḗ","Ḕ":"Ḕ","Ĕ":"Ĕ","Ḝ":"Ḝ","Ě":"Ě","Ê":"Ê","Ế":"Ế","Ề":"Ề","Ễ":"Ễ","Ė":"Ė","Ȩ":"Ȩ","Ḟ":"Ḟ","Ǵ":"Ǵ","Ḡ":"Ḡ","Ğ":"Ğ","Ǧ":"Ǧ","Ĝ":"Ĝ","Ġ":"Ġ","Ģ":"Ģ","Ḧ":"Ḧ","Ȟ":"Ȟ","Ĥ":"Ĥ","Ḣ":"Ḣ","Ḩ":"Ḩ","Í":"Í","Ì":"Ì","Ï":"Ï","Ḯ":"Ḯ","Ĩ":"Ĩ","Ī":"Ī","Ĭ":"Ĭ","Ǐ":"Ǐ","Î":"Î","İ":"İ","Ĵ":"Ĵ","Ḱ":"Ḱ","Ǩ":"Ǩ","Ķ":"Ķ","Ĺ":"Ĺ","Ľ":"Ľ","Ļ":"Ļ","Ḿ":"Ḿ","Ṁ":"Ṁ","Ń":"Ń","Ǹ":"Ǹ","Ñ":"Ñ","Ň":"Ň","Ṅ":"Ṅ","Ņ":"Ņ","Ó":"Ó","Ò":"Ò","Ö":"Ö","Ȫ":"Ȫ","Õ":"Õ","Ṍ":"Ṍ","Ṏ":"Ṏ","Ȭ":"Ȭ","Ō":"Ō","Ṓ":"Ṓ","Ṑ":"Ṑ","Ŏ":"Ŏ","Ǒ":"Ǒ","Ô":"Ô","Ố":"Ố","Ồ":"Ồ","Ỗ":"Ỗ","Ȯ":"Ȯ","Ȱ":"Ȱ","Ő":"Ő","Ṕ":"Ṕ","Ṗ":"Ṗ","Ŕ":"Ŕ","Ř":"Ř","Ṙ":"Ṙ","Ŗ":"Ŗ","Ś":"Ś","Ṥ":"Ṥ","Š":"Š","Ṧ":"Ṧ","Ŝ":"Ŝ","Ṡ":"Ṡ","Ş":"Ş","Ť":"Ť","Ṫ":"Ṫ","Ţ":"Ţ","Ú":"Ú","Ù":"Ù","Ü":"Ü","Ǘ":"Ǘ","Ǜ":"Ǜ","Ǖ":"Ǖ","Ǚ":"Ǚ","Ũ":"Ũ","Ṹ":"Ṹ","Ū":"Ū","Ṻ":"Ṻ","Ŭ":"Ŭ","Ǔ":"Ǔ","Û":"Û","Ů":"Ů","Ű":"Ű","Ṽ":"Ṽ","Ẃ":"Ẃ","Ẁ":"Ẁ","Ẅ":"Ẅ","Ŵ":"Ŵ","Ẇ":"Ẇ","Ẍ":"Ẍ","Ẋ":"Ẋ","Ý":"Ý","Ỳ":"Ỳ","Ÿ":"Ÿ","Ỹ":"Ỹ","Ȳ":"Ȳ","Ŷ":"Ŷ","Ẏ":"Ẏ","Ź":"Ź","Ž":"Ž","Ẑ":"Ẑ","Ż":"Ż","ά":"ά","ὰ":"ὰ","ᾱ":"ᾱ","ᾰ":"ᾰ","έ":"έ","ὲ":"ὲ","ή":"ή","ὴ":"ὴ","ί":"ί","ὶ":"ὶ","ϊ":"ϊ","ΐ":"ΐ","ῒ":"ῒ","ῑ":"ῑ","ῐ":"ῐ","ό":"ό","ὸ":"ὸ","ύ":"ύ","ὺ":"ὺ","ϋ":"ϋ","ΰ":"ΰ","ῢ":"ῢ","ῡ":"ῡ","ῠ":"ῠ","ώ":"ώ","ὼ":"ὼ","Ύ":"Ύ","Ὺ":"Ὺ","Ϋ":"Ϋ","Ῡ":"Ῡ","Ῠ":"Ῠ","Ώ":"Ώ","Ὼ":"Ὼ"},Zr=((f=Kr.prototype).expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new j("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},f.consume=function(){this.nextToken=null},f.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},f.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},f.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},f.subparse=function(e){var t=this.nextToken,e=(this.consume(),this.gullet.pushToken(new X0("}")),this.gullet.pushTokens(e),this.parseExpression(!1));return this.expect("}"),this.nextToken=t,e},f.parseExpression=function(e,t){for(var r=[];;){"math"===this.mode&&this.consumeSpaces();var n=this.fetch();if(~Kr.endOfExpression.indexOf(n.text))break;if(t&&n.text===t)break;if(e&&Ir[n.text]&&Ir[n.text].infix)break;n=this.parseAtom(t);if(!n)break;"internal"!==n.type&&r.push(n)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)},f.handleInfixNodes=function(e){for(var t,r,n,i=-1,a=0;at.charCodeAt(0))return null;this.settings.strict&&(B(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),a={type:"textord",mode:"text",loc:W0.range(e),text:t}}if(this.consume(),i)for(var o=0;o":">","<":"<",'"':""","'":"'"},R=/[&><"']/g,Z={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(R,function(e){return O[e]})},hyphenate:function(e){return e.replace(I,"-$1").toLowerCase()},getBaseElem:C,isCharacterBox:function(e){e=C(e);return"mathord"===e.type||"textord"===e.type||"atom"===e.type},protocolFromUrl:function(e){e=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=e?e[1]:"_relative"}},E={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:function(e){return"#"+e}},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:function(e,t){return t.push(e),t}},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:function(e){return Math.max(0,e)},cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:function(e){return Math.max(0,e)},cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:function(e){return Math.max(0,e)},cli:"-e, --max-expand ",cliProcessor:function(e){return"Infinity"===e?1/0:parseInt(e)}},globalGroup:{type:"boolean",cli:!1}};(t=W.prototype).reportNonstrict=function(e,t,r){var n=this.strict;if((n="function"==typeof n?n(e,t,r):n)&&"ignore"!==n){if(!0===n||"error"===n)throw new $("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===n?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n||!0!==n&&"error"!==n&&("warn"===n?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),1))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=Z.protocolFromUrl(e.url));e="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(e)};var H=W,e=((t=X.prototype).sup=function(){return L[D[this.id]]},t.sub=function(){return L[P[this.id]]},t.fracNum=function(){return L[F[this.id]]},t.fracDen=function(){return L[V[this.id]]},t.cramp=function(){return L[G[this.id]]},t.text=function(){return L[U[this.id]]},X),L=[new e(0,0,!(t.isTight=function(){return 2<=this.size})),new e(1,0,!0),new e(2,1,!1),new e(3,1,!0),new e(4,2,!1),new e(5,2,!0),new e(6,3,!1),new e(7,3,!0)],D=[4,5,4,5,6,7,6,7],P=[5,5,5,5,7,7,7,7],F=[2,3,4,5,6,7,6,7],V=[3,3,5,5,7,7,7,7],G=[1,1,3,3,5,5,7,7],U=[0,1,2,3,2,3,2,3],K={DISPLAY:L[0],TEXT:L[2],SCRIPT:L[4],SCRIPTSCRIPT:L[6]},Y=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];function X(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}function W(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},E){var r;E.hasOwnProperty(t)&&(r=E[t],this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:function(e){if(e.default)return e.default;if(e=e.type,"string"!=typeof(e=Array.isArray(e)?e[0]:e))return e.enum[0];switch(e){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}(r))}}var j=[];function _(e){for(var t=0;t=j[t]&&e<=j[t+1])return 1}Y.forEach(function(e){return e.blocks.forEach(function(e){return j.push.apply(j,e)})});var ne={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},ie=((t=le.prototype).hasClass=function(e){return Z.contains(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t"}var ve=t,we={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},ke={ex:!0,em:!0,mu:!0},Q=function(e){return+e.toFixed(4)+"em"},Se=((e=He.prototype).setAttribute=function(e,t){this.attributes[e]=t},e.hasClass=function(e){return Z.contains(this.classes,e)},e.toNode=function(){return be.call(this,"span")},e.toMarkup=function(){return xe.call(this,"span")},He),Me=((t=Ee.prototype).setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return Z.contains(this.classes,e)},t.toNode=function(){return be.call(this,"a")},t.toMarkup=function(){return xe.call(this,"a")},Ee),ze=((e=Re.prototype).hasClass=function(e){return Z.contains(this.classes,e)},e.toNode=function(){var e,t=document.createElement("img");for(e in t.src=this.src,t.alt=this.alt,t.className="mord",this.style)this.style.hasOwnProperty(e)&&(t.style[e]=this.style[e]);return t},e.toMarkup=function(){var e,t=""+this.alt+""},Re),Ae={"î":"ı̂","ï":"ı̈","í":"ı́","ì":"ı̀"},b=((t=Oe.prototype).hasClass=function(e){return Z.contains(this.classes,e)},t.toNode=function(){var e,t=document.createTextNode(this.text),r=null;for(e in 0"+i)+"":i},Oe),Te=((e=Ie.prototype).toNode=function(){var e,t=document.createElementNS("http://www.w3.org/2000/svg","svg");for(e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);for(var r=0;r"},Ie),Be=((t=qe.prototype).toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","path");return this.alternate?e.setAttribute("d",this.alternate):e.setAttribute("d",ne[this.pathName]),e},t.toMarkup=function(){return this.alternate?"":""},qe),Ce=((e=Ne.prototype).toNode=function(){var e,t=document.createElementNS("http://www.w3.org/2000/svg","line");for(e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);return t},e.toMarkup=function(){var e,t=""},Ne);function Ne(e){this.attributes=void 0,this.attributes=e||{}}function qe(e,t){this.pathName=void 0,this.alternate=void 0,this.pathName=e,this.alternate=t}function Ie(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}function Oe(e,t,r,n,i,a,o,s){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=e,this.height=t||0,this.depth=r||0,this.italic=n||0,this.skew=i||0,this.width=a||0,this.classes=o||[],this.style=s||{},this.maxFontSize=0;e=function(e){for(var t=0;t=i[0]&&e<=i[1])return r.name}return null}(this.text.charCodeAt(0));e&&this.classes.push(e+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=Ae[this.text])}function Re(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}function Ee(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,ye.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}function He(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,ye.call(this,e,r,n),this.children=t||[]}function Le(e){if(e instanceof b)return e;throw new Error("Expected symbolNode but got "+String(e)+".")}var De={bin:1,close:1,inner:1,open:1,punct:1,rel:1},Pe={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},Fe={math:{},text:{}},p=Fe;function r(e,t,r,n,i,a){Fe[e][i]={font:t,group:r,replace:n},a&&n&&(Fe[e][n]=Fe[e][i])}var n="math",i="text",a="main",t="ams",e="accent-token",o="bin",s="close",Ve="inner",l="mathord",h="op-token",m="open",c="punct",u="rel",d="spacing",f="textord",Ge=(r(n,a,u,"≡","\\equiv",!0),r(n,a,u,"≺","\\prec",!0),r(n,a,u,"≻","\\succ",!0),r(n,a,u,"∼","\\sim",!0),r(n,a,u,"⊥","\\perp"),r(n,a,u,"⪯","\\preceq",!0),r(n,a,u,"⪰","\\succeq",!0),r(n,a,u,"≃","\\simeq",!0),r(n,a,u,"∣","\\mid",!0),r(n,a,u,"≪","\\ll",!0),r(n,a,u,"≫","\\gg",!0),r(n,a,u,"≍","\\asymp",!0),r(n,a,u,"∥","\\parallel"),r(n,a,u,"⋈","\\bowtie",!0),r(n,a,u,"⌣","\\smile",!0),r(n,a,u,"⊑","\\sqsubseteq",!0),r(n,a,u,"⊒","\\sqsupseteq",!0),r(n,a,u,"≐","\\doteq",!0),r(n,a,u,"⌢","\\frown",!0),r(n,a,u,"∋","\\ni",!0),r(n,a,u,"∝","\\propto",!0),r(n,a,u,"⊢","\\vdash",!0),r(n,a,u,"⊣","\\dashv",!0),r(n,a,u,"∋","\\owns"),r(n,a,c,".","\\ldotp"),r(n,a,c,"⋅","\\cdotp"),r(n,a,f,"#","\\#"),r(i,a,f,"#","\\#"),r(n,a,f,"&","\\&"),r(i,a,f,"&","\\&"),r(n,a,f,"ℵ","\\aleph",!0),r(n,a,f,"∀","\\forall",!0),r(n,a,f,"ℏ","\\hbar",!0),r(n,a,f,"∃","\\exists",!0),r(n,a,f,"∇","\\nabla",!0),r(n,a,f,"♭","\\flat",!0),r(n,a,f,"ℓ","\\ell",!0),r(n,a,f,"♮","\\natural",!0),r(n,a,f,"♣","\\clubsuit",!0),r(n,a,f,"℘","\\wp",!0),r(n,a,f,"♯","\\sharp",!0),r(n,a,f,"♢","\\diamondsuit",!0),r(n,a,f,"ℜ","\\Re",!0),r(n,a,f,"♡","\\heartsuit",!0),r(n,a,f,"ℑ","\\Im",!0),r(n,a,f,"♠","\\spadesuit",!0),r(n,a,f,"§","\\S",!0),r(i,a,f,"§","\\S"),r(n,a,f,"¶","\\P",!0),r(i,a,f,"¶","\\P"),r(n,a,f,"†","\\dag"),r(i,a,f,"†","\\dag"),r(i,a,f,"†","\\textdagger"),r(n,a,f,"‡","\\ddag"),r(i,a,f,"‡","\\ddag"),r(i,a,f,"‡","\\textdaggerdbl"),r(n,a,s,"⎱","\\rmoustache",!0),r(n,a,m,"⎰","\\lmoustache",!0),r(n,a,s,"⟯","\\rgroup",!0),r(n,a,m,"⟮","\\lgroup",!0),r(n,a,o,"∓","\\mp",!0),r(n,a,o,"⊖","\\ominus",!0),r(n,a,o,"⊎","\\uplus",!0),r(n,a,o,"⊓","\\sqcap",!0),r(n,a,o,"∗","\\ast"),r(n,a,o,"⊔","\\sqcup",!0),r(n,a,o,"◯","\\bigcirc",!0),r(n,a,o,"∙","\\bullet",!0),r(n,a,o,"‡","\\ddagger"),r(n,a,o,"≀","\\wr",!0),r(n,a,o,"⨿","\\amalg"),r(n,a,o,"&","\\And"),r(n,a,u,"⟵","\\longleftarrow",!0),r(n,a,u,"⇐","\\Leftarrow",!0),r(n,a,u,"⟸","\\Longleftarrow",!0),r(n,a,u,"⟶","\\longrightarrow",!0),r(n,a,u,"⇒","\\Rightarrow",!0),r(n,a,u,"⟹","\\Longrightarrow",!0),r(n,a,u,"↔","\\leftrightarrow",!0),r(n,a,u,"⟷","\\longleftrightarrow",!0),r(n,a,u,"⇔","\\Leftrightarrow",!0),r(n,a,u,"⟺","\\Longleftrightarrow",!0),r(n,a,u,"↦","\\mapsto",!0),r(n,a,u,"⟼","\\longmapsto",!0),r(n,a,u,"↗","\\nearrow",!0),r(n,a,u,"↩","\\hookleftarrow",!0),r(n,a,u,"↪","\\hookrightarrow",!0),r(n,a,u,"↘","\\searrow",!0),r(n,a,u,"↼","\\leftharpoonup",!0),r(n,a,u,"⇀","\\rightharpoonup",!0),r(n,a,u,"↙","\\swarrow",!0),r(n,a,u,"↽","\\leftharpoondown",!0),r(n,a,u,"⇁","\\rightharpoondown",!0),r(n,a,u,"↖","\\nwarrow",!0),r(n,a,u,"⇌","\\rightleftharpoons",!0),r(n,t,u,"≮","\\nless",!0),r(n,t,u,"","\\@nleqslant"),r(n,t,u,"","\\@nleqq"),r(n,t,u,"⪇","\\lneq",!0),r(n,t,u,"≨","\\lneqq",!0),r(n,t,u,"","\\@lvertneqq"),r(n,t,u,"⋦","\\lnsim",!0),r(n,t,u,"⪉","\\lnapprox",!0),r(n,t,u,"⊀","\\nprec",!0),r(n,t,u,"⋠","\\npreceq",!0),r(n,t,u,"⋨","\\precnsim",!0),r(n,t,u,"⪹","\\precnapprox",!0),r(n,t,u,"≁","\\nsim",!0),r(n,t,u,"","\\@nshortmid"),r(n,t,u,"∤","\\nmid",!0),r(n,t,u,"⊬","\\nvdash",!0),r(n,t,u,"⊭","\\nvDash",!0),r(n,t,u,"⋪","\\ntriangleleft"),r(n,t,u,"⋬","\\ntrianglelefteq",!0),r(n,t,u,"⊊","\\subsetneq",!0),r(n,t,u,"","\\@varsubsetneq"),r(n,t,u,"⫋","\\subsetneqq",!0),r(n,t,u,"","\\@varsubsetneqq"),r(n,t,u,"≯","\\ngtr",!0),r(n,t,u,"","\\@ngeqslant"),r(n,t,u,"","\\@ngeqq"),r(n,t,u,"⪈","\\gneq",!0),r(n,t,u,"≩","\\gneqq",!0),r(n,t,u,"","\\@gvertneqq"),r(n,t,u,"⋧","\\gnsim",!0),r(n,t,u,"⪊","\\gnapprox",!0),r(n,t,u,"⊁","\\nsucc",!0),r(n,t,u,"⋡","\\nsucceq",!0),r(n,t,u,"⋩","\\succnsim",!0),r(n,t,u,"⪺","\\succnapprox",!0),r(n,t,u,"≆","\\ncong",!0),r(n,t,u,"","\\@nshortparallel"),r(n,t,u,"∦","\\nparallel",!0),r(n,t,u,"⊯","\\nVDash",!0),r(n,t,u,"⋫","\\ntriangleright"),r(n,t,u,"⋭","\\ntrianglerighteq",!0),r(n,t,u,"","\\@nsupseteqq"),r(n,t,u,"⊋","\\supsetneq",!0),r(n,t,u,"","\\@varsupsetneq"),r(n,t,u,"⫌","\\supsetneqq",!0),r(n,t,u,"","\\@varsupsetneqq"),r(n,t,u,"⊮","\\nVdash",!0),r(n,t,u,"⪵","\\precneqq",!0),r(n,t,u,"⪶","\\succneqq",!0),r(n,t,u,"","\\@nsubseteqq"),r(n,t,o,"⊴","\\unlhd"),r(n,t,o,"⊵","\\unrhd"),r(n,t,u,"↚","\\nleftarrow",!0),r(n,t,u,"↛","\\nrightarrow",!0),r(n,t,u,"⇍","\\nLeftarrow",!0),r(n,t,u,"⇏","\\nRightarrow",!0),r(n,t,u,"↮","\\nleftrightarrow",!0),r(n,t,u,"⇎","\\nLeftrightarrow",!0),r(n,t,u,"△","\\vartriangle"),r(n,t,f,"ℏ","\\hslash"),r(n,t,f,"▽","\\triangledown"),r(n,t,f,"◊","\\lozenge"),r(n,t,f,"Ⓢ","\\circledS"),r(n,t,f,"®","\\circledR"),r(i,t,f,"®","\\circledR"),r(n,t,f,"∡","\\measuredangle",!0),r(n,t,f,"∄","\\nexists"),r(n,t,f,"℧","\\mho"),r(n,t,f,"Ⅎ","\\Finv",!0),r(n,t,f,"⅁","\\Game",!0),r(n,t,f,"‵","\\backprime"),r(n,t,f,"▲","\\blacktriangle"),r(n,t,f,"▼","\\blacktriangledown"),r(n,t,f,"■","\\blacksquare"),r(n,t,f,"⧫","\\blacklozenge"),r(n,t,f,"★","\\bigstar"),r(n,t,f,"∢","\\sphericalangle",!0),r(n,t,f,"∁","\\complement",!0),r(n,t,f,"ð","\\eth",!0),r(i,a,f,"ð","ð"),r(n,t,f,"╱","\\diagup"),r(n,t,f,"╲","\\diagdown"),r(n,t,f,"□","\\square"),r(n,t,f,"□","\\Box"),r(n,t,f,"◊","\\Diamond"),r(n,t,f,"¥","\\yen",!0),r(i,t,f,"¥","\\yen",!0),r(n,t,f,"✓","\\checkmark",!0),r(i,t,f,"✓","\\checkmark"),r(n,t,f,"ℶ","\\beth",!0),r(n,t,f,"ℸ","\\daleth",!0),r(n,t,f,"ℷ","\\gimel",!0),r(n,t,f,"ϝ","\\digamma",!0),r(n,t,f,"ϰ","\\varkappa"),r(n,t,m,"┌","\\@ulcorner",!0),r(n,t,s,"┐","\\@urcorner",!0),r(n,t,m,"└","\\@llcorner",!0),r(n,t,s,"┘","\\@lrcorner",!0),r(n,t,u,"≦","\\leqq",!0),r(n,t,u,"⩽","\\leqslant",!0),r(n,t,u,"⪕","\\eqslantless",!0),r(n,t,u,"≲","\\lesssim",!0),r(n,t,u,"⪅","\\lessapprox",!0),r(n,t,u,"≊","\\approxeq",!0),r(n,t,o,"⋖","\\lessdot"),r(n,t,u,"⋘","\\lll",!0),r(n,t,u,"≶","\\lessgtr",!0),r(n,t,u,"⋚","\\lesseqgtr",!0),r(n,t,u,"⪋","\\lesseqqgtr",!0),r(n,t,u,"≑","\\doteqdot"),r(n,t,u,"≓","\\risingdotseq",!0),r(n,t,u,"≒","\\fallingdotseq",!0),r(n,t,u,"∽","\\backsim",!0),r(n,t,u,"⋍","\\backsimeq",!0),r(n,t,u,"⫅","\\subseteqq",!0),r(n,t,u,"⋐","\\Subset",!0),r(n,t,u,"⊏","\\sqsubset",!0),r(n,t,u,"≼","\\preccurlyeq",!0),r(n,t,u,"⋞","\\curlyeqprec",!0),r(n,t,u,"≾","\\precsim",!0),r(n,t,u,"⪷","\\precapprox",!0),r(n,t,u,"⊲","\\vartriangleleft"),r(n,t,u,"⊴","\\trianglelefteq"),r(n,t,u,"⊨","\\vDash",!0),r(n,t,u,"⊪","\\Vvdash",!0),r(n,t,u,"⌣","\\smallsmile"),r(n,t,u,"⌢","\\smallfrown"),r(n,t,u,"≏","\\bumpeq",!0),r(n,t,u,"≎","\\Bumpeq",!0),r(n,t,u,"≧","\\geqq",!0),r(n,t,u,"⩾","\\geqslant",!0),r(n,t,u,"⪖","\\eqslantgtr",!0),r(n,t,u,"≳","\\gtrsim",!0),r(n,t,u,"⪆","\\gtrapprox",!0),r(n,t,o,"⋗","\\gtrdot"),r(n,t,u,"⋙","\\ggg",!0),r(n,t,u,"≷","\\gtrless",!0),r(n,t,u,"⋛","\\gtreqless",!0),r(n,t,u,"⪌","\\gtreqqless",!0),r(n,t,u,"≖","\\eqcirc",!0),r(n,t,u,"≗","\\circeq",!0),r(n,t,u,"≜","\\triangleq",!0),r(n,t,u,"∼","\\thicksim"),r(n,t,u,"≈","\\thickapprox"),r(n,t,u,"⫆","\\supseteqq",!0),r(n,t,u,"⋑","\\Supset",!0),r(n,t,u,"⊐","\\sqsupset",!0),r(n,t,u,"≽","\\succcurlyeq",!0),r(n,t,u,"⋟","\\curlyeqsucc",!0),r(n,t,u,"≿","\\succsim",!0),r(n,t,u,"⪸","\\succapprox",!0),r(n,t,u,"⊳","\\vartriangleright"),r(n,t,u,"⊵","\\trianglerighteq"),r(n,t,u,"⊩","\\Vdash",!0),r(n,t,u,"∣","\\shortmid"),r(n,t,u,"∥","\\shortparallel"),r(n,t,u,"≬","\\between",!0),r(n,t,u,"⋔","\\pitchfork",!0),r(n,t,u,"∝","\\varpropto"),r(n,t,u,"◀","\\blacktriangleleft"),r(n,t,u,"∴","\\therefore",!0),r(n,t,u,"∍","\\backepsilon"),r(n,t,u,"▶","\\blacktriangleright"),r(n,t,u,"∵","\\because",!0),r(n,t,u,"⋘","\\llless"),r(n,t,u,"⋙","\\gggtr"),r(n,t,o,"⊲","\\lhd"),r(n,t,o,"⊳","\\rhd"),r(n,t,u,"≂","\\eqsim",!0),r(n,a,u,"⋈","\\Join"),r(n,t,u,"≑","\\Doteq",!0),r(n,t,o,"∔","\\dotplus",!0),r(n,t,o,"∖","\\smallsetminus"),r(n,t,o,"⋒","\\Cap",!0),r(n,t,o,"⋓","\\Cup",!0),r(n,t,o,"⩞","\\doublebarwedge",!0),r(n,t,o,"⊟","\\boxminus",!0),r(n,t,o,"⊞","\\boxplus",!0),r(n,t,o,"⋇","\\divideontimes",!0),r(n,t,o,"⋉","\\ltimes",!0),r(n,t,o,"⋊","\\rtimes",!0),r(n,t,o,"⋋","\\leftthreetimes",!0),r(n,t,o,"⋌","\\rightthreetimes",!0),r(n,t,o,"⋏","\\curlywedge",!0),r(n,t,o,"⋎","\\curlyvee",!0),r(n,t,o,"⊝","\\circleddash",!0),r(n,t,o,"⊛","\\circledast",!0),r(n,t,o,"⋅","\\centerdot"),r(n,t,o,"⊺","\\intercal",!0),r(n,t,o,"⋒","\\doublecap"),r(n,t,o,"⋓","\\doublecup"),r(n,t,o,"⊠","\\boxtimes",!0),r(n,t,u,"⇢","\\dashrightarrow",!0),r(n,t,u,"⇠","\\dashleftarrow",!0),r(n,t,u,"⇇","\\leftleftarrows",!0),r(n,t,u,"⇆","\\leftrightarrows",!0),r(n,t,u,"⇚","\\Lleftarrow",!0),r(n,t,u,"↞","\\twoheadleftarrow",!0),r(n,t,u,"↢","\\leftarrowtail",!0),r(n,t,u,"↫","\\looparrowleft",!0),r(n,t,u,"⇋","\\leftrightharpoons",!0),r(n,t,u,"↶","\\curvearrowleft",!0),r(n,t,u,"↺","\\circlearrowleft",!0),r(n,t,u,"↰","\\Lsh",!0),r(n,t,u,"⇈","\\upuparrows",!0),r(n,t,u,"↿","\\upharpoonleft",!0),r(n,t,u,"⇃","\\downharpoonleft",!0),r(n,a,u,"⊶","\\origof",!0),r(n,a,u,"⊷","\\imageof",!0),r(n,t,u,"⊸","\\multimap",!0),r(n,t,u,"↭","\\leftrightsquigarrow",!0),r(n,t,u,"⇉","\\rightrightarrows",!0),r(n,t,u,"⇄","\\rightleftarrows",!0),r(n,t,u,"↠","\\twoheadrightarrow",!0),r(n,t,u,"↣","\\rightarrowtail",!0),r(n,t,u,"↬","\\looparrowright",!0),r(n,t,u,"↷","\\curvearrowright",!0),r(n,t,u,"↻","\\circlearrowright",!0),r(n,t,u,"↱","\\Rsh",!0),r(n,t,u,"⇊","\\downdownarrows",!0),r(n,t,u,"↾","\\upharpoonright",!0),r(n,t,u,"⇂","\\downharpoonright",!0),r(n,t,u,"⇝","\\rightsquigarrow",!0),r(n,t,u,"⇝","\\leadsto"),r(n,t,u,"⇛","\\Rrightarrow",!0),r(n,t,u,"↾","\\restriction"),r(n,a,f,"‘","`"),r(n,a,f,"$","\\$"),r(i,a,f,"$","\\$"),r(i,a,f,"$","\\textdollar"),r(n,a,f,"%","\\%"),r(i,a,f,"%","\\%"),r(n,a,f,"_","\\_"),r(i,a,f,"_","\\_"),r(i,a,f,"_","\\textunderscore"),r(n,a,f,"∠","\\angle",!0),r(n,a,f,"∞","\\infty",!0),r(n,a,f,"′","\\prime"),r(n,a,f,"△","\\triangle"),r(n,a,f,"Γ","\\Gamma",!0),r(n,a,f,"Δ","\\Delta",!0),r(n,a,f,"Θ","\\Theta",!0),r(n,a,f,"Λ","\\Lambda",!0),r(n,a,f,"Ξ","\\Xi",!0),r(n,a,f,"Π","\\Pi",!0),r(n,a,f,"Σ","\\Sigma",!0),r(n,a,f,"Υ","\\Upsilon",!0),r(n,a,f,"Φ","\\Phi",!0),r(n,a,f,"Ψ","\\Psi",!0),r(n,a,f,"Ω","\\Omega",!0),r(n,a,f,"A","Α"),r(n,a,f,"B","Β"),r(n,a,f,"E","Ε"),r(n,a,f,"Z","Ζ"),r(n,a,f,"H","Η"),r(n,a,f,"I","Ι"),r(n,a,f,"K","Κ"),r(n,a,f,"M","Μ"),r(n,a,f,"N","Ν"),r(n,a,f,"O","Ο"),r(n,a,f,"P","Ρ"),r(n,a,f,"T","Τ"),r(n,a,f,"X","Χ"),r(n,a,f,"¬","\\neg",!0),r(n,a,f,"¬","\\lnot"),r(n,a,f,"⊤","\\top"),r(n,a,f,"⊥","\\bot"),r(n,a,f,"∅","\\emptyset"),r(n,t,f,"∅","\\varnothing"),r(n,a,l,"α","\\alpha",!0),r(n,a,l,"β","\\beta",!0),r(n,a,l,"γ","\\gamma",!0),r(n,a,l,"δ","\\delta",!0),r(n,a,l,"ϵ","\\epsilon",!0),r(n,a,l,"ζ","\\zeta",!0),r(n,a,l,"η","\\eta",!0),r(n,a,l,"θ","\\theta",!0),r(n,a,l,"ι","\\iota",!0),r(n,a,l,"κ","\\kappa",!0),r(n,a,l,"λ","\\lambda",!0),r(n,a,l,"μ","\\mu",!0),r(n,a,l,"ν","\\nu",!0),r(n,a,l,"ξ","\\xi",!0),r(n,a,l,"ο","\\omicron",!0),r(n,a,l,"π","\\pi",!0),r(n,a,l,"ρ","\\rho",!0),r(n,a,l,"σ","\\sigma",!0),r(n,a,l,"τ","\\tau",!0),r(n,a,l,"υ","\\upsilon",!0),r(n,a,l,"ϕ","\\phi",!0),r(n,a,l,"χ","\\chi",!0),r(n,a,l,"ψ","\\psi",!0),r(n,a,l,"ω","\\omega",!0),r(n,a,l,"ε","\\varepsilon",!0),r(n,a,l,"ϑ","\\vartheta",!0),r(n,a,l,"ϖ","\\varpi",!0),r(n,a,l,"ϱ","\\varrho",!0),r(n,a,l,"ς","\\varsigma",!0),r(n,a,l,"φ","\\varphi",!0),r(n,a,o,"∗","*",!0),r(n,a,o,"+","+"),r(n,a,o,"−","-",!0),r(n,a,o,"⋅","\\cdot",!0),r(n,a,o,"∘","\\circ",!0),r(n,a,o,"÷","\\div",!0),r(n,a,o,"±","\\pm",!0),r(n,a,o,"×","\\times",!0),r(n,a,o,"∩","\\cap",!0),r(n,a,o,"∪","\\cup",!0),r(n,a,o,"∖","\\setminus",!0),r(n,a,o,"∧","\\land"),r(n,a,o,"∨","\\lor"),r(n,a,o,"∧","\\wedge",!0),r(n,a,o,"∨","\\vee",!0),r(n,a,f,"√","\\surd"),r(n,a,m,"⟨","\\langle",!0),r(n,a,m,"∣","\\lvert"),r(n,a,m,"∥","\\lVert"),r(n,a,s,"?","?"),r(n,a,s,"!","!"),r(n,a,s,"⟩","\\rangle",!0),r(n,a,s,"∣","\\rvert"),r(n,a,s,"∥","\\rVert"),r(n,a,u,"=","="),r(n,a,u,":",":"),r(n,a,u,"≈","\\approx",!0),r(n,a,u,"≅","\\cong",!0),r(n,a,u,"≥","\\ge"),r(n,a,u,"≥","\\geq",!0),r(n,a,u,"←","\\gets"),r(n,a,u,">","\\gt",!0),r(n,a,u,"∈","\\in",!0),r(n,a,u,"","\\@not"),r(n,a,u,"⊂","\\subset",!0),r(n,a,u,"⊃","\\supset",!0),r(n,a,u,"⊆","\\subseteq",!0),r(n,a,u,"⊇","\\supseteq",!0),r(n,t,u,"⊈","\\nsubseteq",!0),r(n,t,u,"⊉","\\nsupseteq",!0),r(n,a,u,"⊨","\\models"),r(n,a,u,"←","\\leftarrow",!0),r(n,a,u,"≤","\\le"),r(n,a,u,"≤","\\leq",!0),r(n,a,u,"<","\\lt",!0),r(n,a,u,"→","\\rightarrow",!0),r(n,a,u,"→","\\to"),r(n,t,u,"≱","\\ngeq",!0),r(n,t,u,"≰","\\nleq",!0),r(n,a,d," ","\\ "),r(n,a,d," ","\\space"),r(n,a,d," ","\\nobreakspace"),r(i,a,d," ","\\ "),r(i,a,d," "," "),r(i,a,d," ","\\space"),r(i,a,d," ","\\nobreakspace"),r(n,a,d,null,"\\nobreak"),r(n,a,d,null,"\\allowbreak"),r(n,a,c,",",","),r(n,a,c,";",";"),r(n,t,o,"⊼","\\barwedge",!0),r(n,t,o,"⊻","\\veebar",!0),r(n,a,o,"⊙","\\odot",!0),r(n,a,o,"⊕","\\oplus",!0),r(n,a,o,"⊗","\\otimes",!0),r(n,a,f,"∂","\\partial",!0),r(n,a,o,"⊘","\\oslash",!0),r(n,t,o,"⊚","\\circledcirc",!0),r(n,t,o,"⊡","\\boxdot",!0),r(n,a,o,"△","\\bigtriangleup"),r(n,a,o,"▽","\\bigtriangledown"),r(n,a,o,"†","\\dagger"),r(n,a,o,"⋄","\\diamond"),r(n,a,o,"⋆","\\star"),r(n,a,o,"◃","\\triangleleft"),r(n,a,o,"▹","\\triangleright"),r(n,a,m,"{","\\{"),r(i,a,f,"{","\\{"),r(i,a,f,"{","\\textbraceleft"),r(n,a,s,"}","\\}"),r(i,a,f,"}","\\}"),r(i,a,f,"}","\\textbraceright"),r(n,a,m,"{","\\lbrace"),r(n,a,s,"}","\\rbrace"),r(n,a,m,"[","\\lbrack",!0),r(i,a,f,"[","\\lbrack",!0),r(n,a,s,"]","\\rbrack",!0),r(i,a,f,"]","\\rbrack",!0),r(n,a,m,"(","\\lparen",!0),r(n,a,s,")","\\rparen",!0),r(i,a,f,"<","\\textless",!0),r(i,a,f,">","\\textgreater",!0),r(n,a,m,"⌊","\\lfloor",!0),r(n,a,s,"⌋","\\rfloor",!0),r(n,a,m,"⌈","\\lceil",!0),r(n,a,s,"⌉","\\rceil",!0),r(n,a,f,"\\","\\backslash"),r(n,a,f,"∣","|"),r(n,a,f,"∣","\\vert"),r(i,a,f,"|","\\textbar",!0),r(n,a,f,"∥","\\|"),r(n,a,f,"∥","\\Vert"),r(i,a,f,"∥","\\textbardbl"),r(i,a,f,"~","\\textasciitilde"),r(i,a,f,"\\","\\textbackslash"),r(i,a,f,"^","\\textasciicircum"),r(n,a,u,"↑","\\uparrow",!0),r(n,a,u,"⇑","\\Uparrow",!0),r(n,a,u,"↓","\\downarrow",!0),r(n,a,u,"⇓","\\Downarrow",!0),r(n,a,u,"↕","\\updownarrow",!0),r(n,a,u,"⇕","\\Updownarrow",!0),r(n,a,h,"∐","\\coprod"),r(n,a,h,"⋁","\\bigvee"),r(n,a,h,"⋀","\\bigwedge"),r(n,a,h,"⨄","\\biguplus"),r(n,a,h,"⋂","\\bigcap"),r(n,a,h,"⋃","\\bigcup"),r(n,a,h,"∫","\\int"),r(n,a,h,"∫","\\intop"),r(n,a,h,"∬","\\iint"),r(n,a,h,"∭","\\iiint"),r(n,a,h,"∏","\\prod"),r(n,a,h,"∑","\\sum"),r(n,a,h,"⨂","\\bigotimes"),r(n,a,h,"⨁","\\bigoplus"),r(n,a,h,"⨀","\\bigodot"),r(n,a,h,"∮","\\oint"),r(n,a,h,"∯","\\oiint"),r(n,a,h,"∰","\\oiiint"),r(n,a,h,"⨆","\\bigsqcup"),r(n,a,h,"∫","\\smallint"),r(i,a,Ve,"…","\\textellipsis"),r(n,a,Ve,"…","\\mathellipsis"),r(i,a,Ve,"…","\\ldots",!0),r(n,a,Ve,"…","\\ldots",!0),r(n,a,Ve,"⋯","\\@cdots",!0),r(n,a,Ve,"⋱","\\ddots",!0),r(n,a,f,"⋮","\\varvdots"),r(n,a,e,"ˊ","\\acute"),r(n,a,e,"ˋ","\\grave"),r(n,a,e,"¨","\\ddot"),r(n,a,e,"~","\\tilde"),r(n,a,e,"ˉ","\\bar"),r(n,a,e,"˘","\\breve"),r(n,a,e,"ˇ","\\check"),r(n,a,e,"^","\\hat"),r(n,a,e,"⃗","\\vec"),r(n,a,e,"˙","\\dot"),r(n,a,e,"˚","\\mathring"),r(n,a,l,"","\\@imath"),r(n,a,l,"","\\@jmath"),r(n,a,f,"ı","ı"),r(n,a,f,"ȷ","ȷ"),r(i,a,f,"ı","\\i",!0),r(i,a,f,"ȷ","\\j",!0),r(i,a,f,"ß","\\ss",!0),r(i,a,f,"æ","\\ae",!0),r(i,a,f,"œ","\\oe",!0),r(i,a,f,"ø","\\o",!0),r(i,a,f,"Æ","\\AE",!0),r(i,a,f,"Œ","\\OE",!0),r(i,a,f,"Ø","\\O",!0),r(i,a,e,"ˊ","\\'"),r(i,a,e,"ˋ","\\`"),r(i,a,e,"ˆ","\\^"),r(i,a,e,"˜","\\~"),r(i,a,e,"ˉ","\\="),r(i,a,e,"˘","\\u"),r(i,a,e,"˙","\\."),r(i,a,e,"¸","\\c"),r(i,a,e,"˚","\\r"),r(i,a,e,"ˇ","\\v"),r(i,a,e,"¨",'\\"'),r(i,a,e,"˝","\\H"),r(i,a,e,"◯","\\textcircled"),{"--":!0,"---":!0,"``":!0,"''":!0});r(i,a,f,"–","--",!0),r(i,a,f,"–","\\textendash"),r(i,a,f,"—","---",!0),r(i,a,f,"—","\\textemdash"),r(i,a,f,"‘","`",!0),r(i,a,f,"‘","\\textquoteleft"),r(i,a,f,"’","'",!0),r(i,a,f,"’","\\textquoteright"),r(i,a,f,"“","``",!0),r(i,a,f,"“","\\textquotedblleft"),r(i,a,f,"”","''",!0),r(i,a,f,"”","\\textquotedblright"),r(n,a,f,"°","\\degree",!0),r(i,a,f,"°","\\degree"),r(i,a,f,"°","\\textdegree",!0),r(n,a,f,"£","\\pounds"),r(n,a,f,"£","\\mathsterling",!0),r(i,a,f,"£","\\pounds"),r(i,a,f,"£","\\textsterling",!0),r(n,t,f,"✠","\\maltese"),r(i,t,f,"✠","\\maltese");for(var Ue='0123456789/@."',Ye=0;Yet&&(t=a.height),a.depth>r&&(r=a.depth),a.maxFontSize>n&&(n=a.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n}function v(e,t,r,n){return e=new Se(e,t,r,n),it(e),e}function at(e,t,r,n){return new Se(e,t,r,n)}function ot(e){return e=new ie(e),it(e),e}function st(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")}var lt=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["","",""],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],ht=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],mt={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},ct={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},ee={fontMap:mt,makeSymbol:nt,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&rt(e,"Main-Bold",t).metrics?nt(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===p[t][e].font?nt(e,"Main-Regular",t,r,n):nt(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:v,makeSvgSpan:at,makeLineSpan:function(e,t,r){e=v([e],[],t);return e.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),e.style.borderBottomWidth=Q(e.height),e.maxFontSize=1,e},makeAnchor:function(e,t,r,n){e=new Me(e,t,r,n);return it(e),e},makeFragment:ot,wrapFragment:function(e,t){return e instanceof ie?v([],[e],t):e},makeVList:function(e,t){for(var e=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,i=n,a=1;a"},m.toText=function(){return this.children.map(function(e){return e.toText()}).join("")};var Ht=Ft,Lt=((s=Pt.prototype).toNode=function(){return document.createTextNode(this.text)},s.toMarkup=function(){return Z.escape(this.toText())},s.toText=function(){return this.text},Pt),M={MathNode:Ht,TextNode:Lt,SpaceNode:((u=Dt.prototype).toNode=function(){var e;return this.character?document.createTextNode(this.character):((e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace")).setAttribute("width",Q(this.width)),e)},u.toMarkup=function(){return this.character?""+this.character+"":''},u.toText=function(){return this.character||" "},Dt),newDocumentFragment:qt},z=function(e,t){if(!e)return new M.MathNode("mrow");if(gt[e.type])return gt[e.type](e,t);throw new $("Got group of unknown type: '"+e.type+"'")};function Dt(e){this.width=void 0,this.character=void 0,this.width=e,this.character=.05555<=e&&e<=.05556?" ":.1666<=e&&e<=.1667?" ":.2222<=e&&e<=.2223?" ":.2777<=e&&e<=.2778?"  ":-.05556<=e&&e<=-.05555?" ⁣":-.1667<=e&&e<=-.1666?" ⁣":-.2223<=e&&e<=-.2222?" ⁣":-.2778<=e&&e<=-.2777?" ⁣":null}function Pt(e){this.text=void 0,this.text=e}function Ft(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}function Vt(e,t,r,n,i){e=S(e,r),r=1===e.length&&e[0]instanceof Ht&&Z.contains(["mrow","mtable"],e[0].type)?e[0]:new M.MathNode("mrow",e),e=new M.MathNode("annotation",[new M.TextNode(t)]),e.setAttribute("encoding","application/x-tex"),t=new M.MathNode("semantics",[r,e]),r=new M.MathNode("math",[t]);return r.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&r.setAttribute("display","block"),ee.makeSpan([i?"katex":"katex-mathml"],[r])}function Gt(e){return(e=new M.MathNode("mo",[new M.TextNode(Wt[e.replace(/^\\/,"")])])).setAttribute("stretchy","true"),e}function Ut(f,g){var e=(r=function(){var e,t=4e5,r=f.label.substr(1);if(Z.contains(["widehat","widecheck","widetilde","utilde"],r))return a=5<(a="ordgroup"===(a=f.base).type?a.body.length:1)?"widehat"===r||"widecheck"===r?(s=420,t=2364,e=.42,r+"4"):(s=312,t=2340,e=.34,"tilde4"):(a=[1,1,2,2,3,3][a],"widehat"===r||"widecheck"===r?(t=[0,1062,2364,2364,2364][a],s=[0,239,300,360,420][a],e=[0,.24,.3,.3,.36,.42][a],r+a):(t=[0,600,1033,2339,2340][a],s=[0,260,286,306,312][a],e=[0,.26,.286,.3,.306,.34][a],"tilde"+a)),a=new Be(a),a=new Te([a],{width:"100%",height:Q(e),viewBox:"0 0 "+t+" "+s,preserveAspectRatio:"none"}),{span:ee.makeSvgSpan([],[a],g),minWidth:0,height:e};var n,i,a,o=[],s=jt[r],l=s[0],h=s[1],m=s[2],c=m/1e3,u=l.length;if(1===u)n=["hide-tail"],i=[s[3]];else if(2===u)n=["halfarrow-left","halfarrow-right"],i=["xMinYMin","xMaxYMin"];else{if(3!==u)throw new Error("Correct katexImagesData or update code here to support\n "+u+" children.");n=["brace-left","brace-center","brace-right"],i=["xMinYMin","xMidYMin","xMaxYMin"]}for(var p=0;p but got "+String(e)+".")}(re(e,t)),e.base=r):s=(r=A(e,"accent")).base;var r,n,e=re(s,t.havingCrampedStyle()),i=0;r.isShifty&&Z.isCharacterBox(s)&&(s=Z.getBaseElem(s),i=Le(re(s,t.havingCrampedStyle())).skew);var a,o,s="\\c"===r.label,l=s?e.height+e.depth:Math.min(e.height,t.fontMetrics().xHeight),h=r.isStretchy?(h=Ut(r,t),ee.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:e},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:0":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"});w({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,e=e.funcName;return{type:"cdlabel",mode:r.mode,side:e.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),r=ee.wrapFragment(re(e.label,r,t),t);return r.classes.push("cd-label-"+e.side),r.style.bottom=Q(.8-r.depth),r.height=0,r.depth=0,r},mathmlBuilder:function(e,t){t=new M.MathNode("mrow",[z(e.label,t)]);return(t=new M.MathNode("mpadded",[t])).setAttribute("width","0"),"left"===e.side&&t.setAttribute("lspace","-1width"),t.setAttribute("voffset","0.7em"),(t=new M.MathNode("mstyle",[t])).setAttribute("displaystyle","false"),t.setAttribute("scriptlevel","1"),t}}),w({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){e=ee.wrapFragment(re(e.fragment,t),t);return e.classes.push("cd-vert-arrow"),e},mathmlBuilder:function(e,t){return new M.MathNode("mrow",[z(e.fragment,t)])}}),w({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var e=e.parser,r=A(t[0],"ordgroup").body,n="",i=0;i>10),56320+(1023&t))),{type:"textord",mode:e.mode,text:t}}});function r0(e,t){return t=te(e.body,t.withColor(e.color),!1),ee.makeFragment(t)}function n0(e,t){return t=S(e.body,t.withColor(e.color)),(t=new M.MathNode("mstyle",t)).setAttribute("mathcolor",e.color),t}function i0(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new $("Expected a control sequence",e);return t}function a0(e,t,r,n){var i=e.gullet.macros.get(r.text);null==i&&(r.noexpand=!0,i={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,i,n)}function o0(e,t,r){if(r=he(p.math[e]&&p.math[e].replace||e,t,r))return r;throw new Error("Unsupported symbol "+e+" and font size "+t+".")}function s0(e,t,r,n){return t=r.havingBaseStyle(t),n=ee.makeSpan(n.concat(t.sizingClasses(r)),[e],r),e=t.sizeMultiplier/r.sizeMultiplier,n.height*=e,n.depth*=e,n.maxFontSize=t.sizeMultiplier,n}function l0(e,t,r){r=t.havingBaseStyle(r),r=(1-t.sizeMultiplier/r.sizeMultiplier)*t.fontMetrics().axisHeight,e.classes.push("delimcenter"),e.style.top=Q(r),e.height-=r,e.depth+=r}function h0(e,t,r,n,i,a){return e=ee.makeSymbol(e,"Size"+t+"-Regular",i,n),i=s0(ee.makeSpan(["delimsizing","size"+t],[e],n),K.TEXT,n,a),r&&l0(i,n,K.TEXT),i}function m0(e,t,r){return{type:"elem",elem:ee.makeSpan(["delimsizinginner","Size1-Regular"===t?"delim-size1":"delim-size4"],[ee.makeSpan([],[ee.makeSymbol(e,t,r)])])}}function c0(e,t,r){var n=(ae["Size4-Regular"][e.charCodeAt(0)]?ae["Size4-Regular"]:ae["Size1-Regular"])[e.charCodeAt(0)][4],e=new Be("inner",function(e,t){switch(e){case"⎜":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"∣":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"∥":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"⎟":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"⎢":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"⎥":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"⎪":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"⏐":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"‖":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),e=new Te([e],{width:Q(n),height:Q(t),style:"width:"+Q(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"});return(e=ee.makeSvgSpan([],[e],r)).height=t,e.style.height=Q(t),e.style.width=Q(n),{type:"elem",elem:e}}function u0(e,t,r,n,i,a){var o,s=o=f=e,l=null,h="Size1-Regular";"\\uparrow"===e?o=f="⏐":"\\Uparrow"===e?o=f="‖":"\\downarrow"===e?s=o="⏐":"\\Downarrow"===e?s=o="‖":"\\updownarrow"===e?(s="\\uparrow",o="⏐",f="\\downarrow"):"\\Updownarrow"===e?(s="\\Uparrow",o="‖",f="\\Downarrow"):Z.contains(b0,e)?o="∣":Z.contains(x0,e)?o="∥":"["===e||"\\lbrack"===e?(s="⎡",o="⎢",f="⎣",h="Size4-Regular"):"]"===e||"\\rbrack"===e?(s="⎤",o="⎥",f="⎦",h="Size4-Regular"):"\\lfloor"===e||"⌊"===e?(o=s="⎢",f="⎣",h="Size4-Regular"):"\\lceil"===e||"⌈"===e?(s="⎡",o=f="⎢",h="Size4-Regular"):"\\rfloor"===e||"⌋"===e?(o=s="⎥",f="⎦",h="Size4-Regular"):"\\rceil"===e||"⌉"===e?(s="⎤",o=f="⎥",h="Size4-Regular"):"("===e||"\\lparen"===e?(s="⎛",o="⎜",f="⎝",h="Size4-Regular"):")"===e||"\\rparen"===e?(s="⎞",o="⎟",f="⎠",h="Size4-Regular"):"\\{"===e||"\\lbrace"===e?(s="⎧",l="⎨",f="⎩",o="⎪",h="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(s="⎫",l="⎬",f="⎭",o="⎪",h="Size4-Regular"):"\\lgroup"===e||"⟮"===e?(s="⎧",f="⎩",o="⎪",h="Size4-Regular"):"\\rgroup"===e||"⟯"===e?(s="⎫",f="⎭",o="⎪",h="Size4-Regular"):"\\lmoustache"===e||"⎰"===e?(s="⎧",f="⎭",o="⎪",h="Size4-Regular"):"\\rmoustache"!==e&&"⎱"!==e||(s="⎫",f="⎩",o="⎪",h="Size4-Regular");var e=(e=o0(s,h,i)).height+e.depth,m=(m=o0(o,h,i)).height+m.depth,c=(c=o0(f,h,i)).height+c.depth,u=0,p=1;null!==l&&(u=(d=o0(l,h,i)).height+d.depth,p=2);var t=(d=e+c+u)+Math.max(0,Math.ceil((t-d)/(p*m)))*p*m,d=n.fontMetrics().axisHeight,p=(r&&(d*=n.sizeMultiplier),t/2-d),d=((m=[]).push(m0(f,h,i)),m.push(y0),null===l?m.push(c0(o,t-e-c+.016,n)):(m.push(c0(o,r=(t-e-c-u)/2+.016,n)),m.push(y0),m.push(m0(l,h,i)),m.push(y0),m.push(c0(o,r,n))),m.push(y0),m.push(m0(s,h,i)),n.havingBaseStyle(K.TEXT)),f=ee.makeVList({positionType:"bottom",positionData:p,children:m},d);return s0(ee.makeSpan(["delimsizing","mult"],[f],d),K.TEXT,n,a)}function p0(n,e,t,r,i){return r=function(e,t){e*=1e3;var r="";switch(n){case"sqrtMain":r="M95,"+(622+e+80)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" 80h400000v"+(40+e)+"h-400000z";break;case"sqrtSize1":r="M263,"+(601+e+80)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" 80h400000v"+(40+e)+"h-400000z";break;case"sqrtSize2":r="M983 "+(10+e+80)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" 80h400000v"+(40+e)+"h-400000z";break;case"sqrtSize3":r="M424,"+(2398+e+80)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" 80\nh400000v"+(40+e)+"h-400000z";break;case"sqrtSize4":r="M473,"+(2713+e+80)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" 80h400000v"+(40+e)+"H1017.7z";break;case"sqrtTall":r="M702 "+(80+e)+"H400000"+(40+e)+"\nH742v"+(t-54-80-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 80H400000v"+(40+e)+"H742z"}return r}(r,t),r=new Be(n,r),r=new Te([r],{width:"400em",height:Q(e),viewBox:"0 0 400000 "+t,preserveAspectRatio:"xMinYMin slice"}),ee.makeSvgSpan(["hide-tail"],[r],i)}function d0(e,t,r,n){for(var i=Math.min(2,3-n.style.size);i"!==e&&"\\gt"!==e&&"⟩"!==e||(e="\\rangle"),c=Z.contains(k0,e)?M0:Z.contains(v0,e)?A0:z0;var o,s,l,h,m,c=d0(e,t,c,n);return"small"===c.type?(o=e,s=c.style,l=r,h=n,m=a,o=ee.makeSymbol(o,"Main-Regular",i,h),o=s0(o,s,h,m),l&&l0(o,h,s),o):"large"===c.type?h0(e,c.size,r,n,i,a):u0(e,t,r,n,i,a)}w({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var e=e.parser,r=A(t[0],"color-token").color,t=t[1];return{type:"color",mode:e.mode,color:r,body:k(t)}},htmlBuilder:r0,mathmlBuilder:n0}),w({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,e=e.breakOnTokenText,t=A(t[0],"color-token").color,e=(r.gullet.macros.set("\\current@color",t),r.parseExpression(!0,e));return{type:"color",mode:r.mode,color:t,body:e}},htmlBuilder:r0,mathmlBuilder:n0}),w({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var e=e.parser,r=r[0],n=!e.settings.displayMode||!e.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:e.mode,newLine:n,size:r&&A(r,"size").value}},htmlBuilder:function(e,t){var r=ee.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size)&&(r.style.marginTop=Q(J(e.size,t))),r},mathmlBuilder:function(e,t){var r=new M.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size)&&r.setAttribute("height",Q(J(e.size,t))),r}});var g0={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},y0=(w({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,e=e.funcName,r=(t.consumeSpaces(),t.fetch());if(g0[r.text])return"\\global"!==e&&"\\\\globallong"!==e||(r.text=g0[r.text]),A(t.parseFunction(),"internal");throw new $("Invalid token after macro prefix",r)}}),w({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,e=e.funcName,r=t.gullet.popToken(),n=r.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new $("Expected a control sequence",r);for(var i,a=0,o=[[]];"{"!==t.gullet.future().text;)if("#"===(r=t.gullet.popToken()).text){if("{"===t.gullet.future().text){i=t.gullet.future(),o[a].push("{");break}if(r=t.gullet.popToken(),!/^[1-9]$/.test(r.text))throw new $('Invalid argument number "'+r.text+'"');if(parseInt(r.text)!==a+1)throw new $('Argument number "'+r.text+'" out of order');a++,o.push([])}else{if("EOF"===r.text)throw new $("Expected a macro definition");o[a].push(r.text)}var s=t.gullet.consumeArg().tokens;return i&&s.unshift(i),"\\edef"!==e&&"\\xdef"!==e||(s=t.gullet.expandTokens(s)).reverse(),t.gullet.macros.set(n,{tokens:s,numArgs:a,delimiters:o},e===g0[e]),{type:"internal",mode:t.mode}}}),w({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t,r,n=e.parser,e=e.funcName,i=i0(n.gullet.popToken());n.gullet.consumeSpaces(),r="="===(r=(t=n).gullet.popToken()).text&&" "===(r=t.gullet.popToken()).text?t.gullet.popToken():r;return a0(n,i,r,"\\\\globallet"===e),{type:"internal",mode:n.mode}}}),w({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,e=e.funcName,r=i0(t.gullet.popToken()),n=t.gullet.popToken(),i=t.gullet.popToken();return a0(t,r,i,"\\\\globalfuture"===e),t.gullet.pushToken(i),t.gullet.pushToken(n),{type:"internal",mode:t.mode}}}),{type:"kern",size:-.008}),b0=["|","\\lvert","\\rvert","\\vert"],x0=["\\|","\\lVert","\\rVert","\\Vert"],v0=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","\\surd"],w0=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱"],k0=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],S0=[0,1.2,1.8,2.4,3],M0=[{type:"small",style:K.SCRIPTSCRIPT},{type:"small",style:K.SCRIPT},{type:"small",style:K.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],z0=[{type:"small",style:K.SCRIPTSCRIPT},{type:"small",style:K.SCRIPT},{type:"small",style:K.TEXT},{type:"stack"}],A0=[{type:"small",style:K.SCRIPTSCRIPT},{type:"small",style:K.SCRIPT},{type:"small",style:K.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],T0={sqrtImage:function(e,t){var r,n=t.havingBaseSizing(),i=d0("\\surd",e*n.sizeMultiplier,A0,n),n=n.sizeMultiplier,a=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),o=0,s=0,l=0,i="small"===i.type?(e<1?n=1:e<1.4&&(n=.7),s=(1+a)/n,(r=p0("sqrtMain",o=(1+a+.08)/n,l=1e3+1e3*a+80,a,t)).style.minWidth="0.853em",.833/n):"large"===i.type?(l=1080*S0[i.size],s=(S0[i.size]+a)/n,o=(S0[i.size]+a+.08)/n,(r=p0("sqrtSize"+i.size,o,l,a,t)).style.minWidth="1.02em",1/n):(o=e+a+.08,s=e+a,l=Math.floor(1e3*e+a)+80,(r=p0("sqrtTall",o,l,a,t)).style.minWidth="0.742em",1.056);return r.height=s,r.style.height=Q(o),{span:r,advanceWidth:i,ruleWidth:(t.fontMetrics().sqrtRuleThickness+a)*n}},sizedDelim:function(e,t,r,n,i){if("<"===e||"\\lt"===e||"⟨"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"⟩"!==e||(e="\\rangle"),Z.contains(v0,e)||Z.contains(k0,e))return h0(e,t,!1,r,n,i);if(Z.contains(w0,e))return u0(e,S0[t],!1,r,n,i);throw new $("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:S0,customSizedDelim:f0,leftRightDelim:function(e,t,r,n,i,a){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,t=Math.max(t-o,r+o),r=Math.max(t/500*901,2*t-s);return f0(e,r,!0,n,i,a)}},B0={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},C0=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","<",">","\\langle","⟨","\\rangle","⟩","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function N0(e,t){var r=$t(e);if(r&&Z.contains(C0,r.text))return r;throw new $(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function q0(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}w({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){t=N0(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:B0[e.funcName].size,mclass:B0[e.funcName].mclass,delim:t.text}},htmlBuilder:function(e,t){return"."===e.delim?ee.makeSpan([e.mclass]):T0.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[],t=("."!==e.delim&&t.push(It(e.delim,e.mode)),new M.MathNode("mo",t)),e=("mopen"===e.mclass||"mclose"===e.mclass?t.setAttribute("fence","true"):t.setAttribute("fence","false"),t.setAttribute("stretchy","true"),Q(T0.sizeToMaxHeight[e.size]));return t.setAttribute("minsize",e),t.setAttribute("maxsize",e),t}}),w({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new $("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:N0(t[0],e).text,color:r}}}),w({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var t=N0(t[0],e),e=e.parser,r=(++e.leftrightDepth,e.parseExpression(!1)),n=(--e.leftrightDepth,e.expect("\\right",!1),A(e.parseFunction(),"leftright-right"));return{type:"leftright",mode:e.mode,body:r,left:t.text,right:n.delim,rightColor:n.color}},htmlBuilder:function(e,t){q0(e);for(var r,n=te(e.body,t,!0,["mopen","mclose"]),i=0,a=0,o=!1,s=0;sAV".indexOf(c)))throw new $('Expected one of "<>AV=|." after @',l[m]);for(var p=0;p<2;p++){for(var d=!0,f=m+1;f=K.SCRIPT.id?t.text():K.DISPLAY:"text"===e&&t.size===K.DISPLAY.size?t=K.TEXT:"script"===e?t=K.SCRIPT:"scriptscript"===e&&(t=K.SCRIPTSCRIPT),t}function ir(e,t){var r=nr(e.size,t.style),n=r.fracNum(),i=r.fracDen(),n=t.havingStyle(n),a=re(e.numer,n,t);e.continued&&(m=8.5/t.fontMetrics().ptPerEm,c=3.5/t.fontMetrics().ptPerEm,a.height=a.heightr.height+r.depth+i&&(i=(i+s-r.height-r.depth)/2),a.height-r.height-i-o),i=(r.style.paddingLeft=Q(n),ee.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+s)},{type:"elem",elem:a},{type:"kern",size:o}]},t));return e.index?(n=t.havingStyle(K.SCRIPTSCRIPT),r=re(e.index,n,t),s=.6*(i.height-i.depth),a=ee.makeVList({positionType:"shift",positionData:-s,children:[{type:"elem",elem:r}]},t),o=ee.makeSpan(["root"],[a]),ee.makeSpan(["mord","sqrt"],[o,i],t)):ee.makeSpan(["mord","sqrt"],[i],t)},mathmlBuilder:function(e,t){var r=e.body,e=e.index;return e?new M.MathNode("mroot",[z(r,t),z(e,t)]):new M.MathNode("msqrt",[z(r,t)])}}),{display:K.DISPLAY,text:K.TEXT,script:K.SCRIPT,scriptscript:K.SCRIPTSCRIPT}),Mr=(w({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,e=e.parser,r=e.parseExpression(!0,r),n=n.slice(1,n.length-5);return{type:"styling",mode:e.mode,style:n,body:r}},htmlBuilder:function(e,t){var r=Sr[e.style],r=t.havingStyle(r).withFont("");return xr(e.body,r,t)},mathmlBuilder:function(e,t){var r=Sr[e.style],t=t.havingStyle(r),r=S(e.body,t),t=new M.MathNode("mstyle",r),r={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return t.setAttribute("scriptlevel",r[0]),t.setAttribute("displaystyle",r[1]),t}}),yt({type:"supsub",htmlBuilder:function(e,t){r=t;var r=(o=(a=e).base)?"op"===o.type?o.limits&&(r.style.size===K.DISPLAY.size||o.alwaysHandleSupSub)?cr:null:"operatorname"===o.type?o.alwaysHandleSupSub&&(r.style.size===K.DISPLAY.size||o.limits)?pr:null:"accent"===o.type?Z.isCharacterBox(o.base)?Zt:null:"horizBrace"===o.type&&!a.sub===o.isOver?sr:null:null;if(r)return r(e,t);var n,i,a=e.base,o=e.sup,r=e.sub,s=re(a,t),l=t.fontMetrics(),h=0,m=0,a=a&&Z.isCharacterBox(a),c=(o&&(c=t.havingStyle(t.style.sup()),n=re(o,c,t),a||(h=s.height-c.fontMetrics().supDrop*c.sizeMultiplier/t.sizeMultiplier)),r&&(o=t.havingStyle(t.style.sub()),i=re(r,o,t),a||(m=s.depth+o.fontMetrics().subDrop*o.sizeMultiplier/t.sizeMultiplier)),t.style===K.DISPLAY?l.sup1:t.style.cramped?l.sup3:l.sup2),r=t.sizeMultiplier,a=Q(.5/l.ptPerEm/r),o=null;if(i&&(r=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name),s instanceof b||r)&&(o=Q(-s.italic)),n&&i){h=Math.max(h,c,n.depth+.25*l.xHeight),m=Math.max(m,l.sub2);e=4*l.defaultRuleThickness;h-n.depth-(i.height-m)":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"}),Gr=(T("\\dots",function(e){var t="\\dotso",e=e.expandAfterFuture().text;return e in Vr?t=Vr[e]:("\\not"===e.substr(0,4)||e in p.math&&Z.contains(["bin","rel"],p.math[e].group))&&(t="\\dotsb"),t}),{")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0}),e=(T("\\dotso",function(e){return e.future().text in Gr?"\\ldots\\,":"\\ldots"}),T("\\dotsc",function(e){e=e.future().text;return e in Gr&&","!==e?"\\ldots\\,":"\\ldots"}),T("\\cdots",function(e){return e.future().text in Gr?"\\@cdots\\,":"\\@cdots"}),T("\\dotsb","\\cdots"),T("\\dotsm","\\cdots"),T("\\dotsi","\\!\\cdots"),T("\\dotsx","\\ldots\\,"),T("\\DOTSI","\\relax"),T("\\DOTSB","\\relax"),T("\\DOTSX","\\relax"),T("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),T("\\,","\\tmspace+{3mu}{.1667em}"),T("\\thinspace","\\,"),T("\\>","\\mskip{4mu}"),T("\\:","\\tmspace+{4mu}{.2222em}"),T("\\medspace","\\:"),T("\\;","\\tmspace+{5mu}{.2777em}"),T("\\thickspace","\\;"),T("\\!","\\tmspace-{3mu}{.1667em}"),T("\\negthinspace","\\!"),T("\\negmedspace","\\tmspace-{4mu}{.2222em}"),T("\\negthickspace","\\tmspace-{5mu}{.277em}"),T("\\enspace","\\kern.5em "),T("\\enskip","\\hskip.5em\\relax"),T("\\quad","\\hskip1em\\relax"),T("\\qquad","\\hskip2em\\relax"),T("\\tag","\\@ifstar\\tag@literal\\tag@paren"),T("\\tag@paren","\\tag@literal{({#1})}"),T("\\tag@literal",function(e){if(e.macros.get("\\df@tag"))throw new $("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"}),T("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),T("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),T("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),T("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),T("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),T("\\newline","\\\\\\relax"),T("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}"),Q(ae["Main-Regular"]["T".charCodeAt(0)][1]-.7*ae["Main-Regular"]["A".charCodeAt(0)][1])),Ur=(T("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+e+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),T("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+e+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),T("\\hspace","\\@ifstar\\@hspacer\\@hspace"),T("\\@hspace","\\hskip #1\\relax"),T("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),T("\\ordinarycolon",":"),T("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),T("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),T("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),T("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),T("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),T("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),T("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),T("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),T("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),T("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),T("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),T("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),T("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),T("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),T("∷","\\dblcolon"),T("∹","\\eqcolon"),T("≔","\\coloneqq"),T("≕","\\eqqcolon"),T("⩴","\\Coloneqq"),T("\\ratio","\\vcentcolon"),T("\\coloncolon","\\dblcolon"),T("\\colonequals","\\coloneqq"),T("\\coloncolonequals","\\Coloneqq"),T("\\equalscolon","\\eqqcolon"),T("\\equalscoloncolon","\\Eqqcolon"),T("\\colonminus","\\coloneq"),T("\\coloncolonminus","\\Coloneq"),T("\\minuscolon","\\eqcolon"),T("\\minuscoloncolon","\\Eqcolon"),T("\\coloncolonapprox","\\Colonapprox"),T("\\coloncolonsim","\\Colonsim"),T("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),T("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),T("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),T("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),T("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`∌}}"),T("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),T("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),T("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),T("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),T("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),T("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),T("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),T("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),T("\\gvertneqq","\\html@mathml{\\@gvertneqq}{≩}"),T("\\lvertneqq","\\html@mathml{\\@lvertneqq}{≨}"),T("\\ngeqq","\\html@mathml{\\@ngeqq}{≱}"),T("\\ngeqslant","\\html@mathml{\\@ngeqslant}{≱}"),T("\\nleqq","\\html@mathml{\\@nleqq}{≰}"),T("\\nleqslant","\\html@mathml{\\@nleqslant}{≰}"),T("\\nshortmid","\\html@mathml{\\@nshortmid}{∤}"),T("\\nshortparallel","\\html@mathml{\\@nshortparallel}{∦}"),T("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{⊈}"),T("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{⊉}"),T("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{⊊}"),T("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{⫋}"),T("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{⊋}"),T("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{⫌}"),T("\\imath","\\html@mathml{\\@imath}{ı}"),T("\\jmath","\\html@mathml{\\@jmath}{ȷ}"),T("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`⟦}}"),T("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`⟧}}"),T("⟦","\\llbracket"),T("⟧","\\rrbracket"),T("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`⦃}}"),T("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`⦄}}"),T("⦃","\\lBrace"),T("⦄","\\rBrace"),T("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`⦵}}"),T("⦵","\\minuso"),T("\\darr","\\downarrow"),T("\\dArr","\\Downarrow"),T("\\Darr","\\Downarrow"),T("\\lang","\\langle"),T("\\rang","\\rangle"),T("\\uarr","\\uparrow"),T("\\uArr","\\Uparrow"),T("\\Uarr","\\Uparrow"),T("\\N","\\mathbb{N}"),T("\\R","\\mathbb{R}"),T("\\Z","\\mathbb{Z}"),T("\\alef","\\aleph"),T("\\alefsym","\\aleph"),T("\\Alpha","\\mathrm{A}"),T("\\Beta","\\mathrm{B}"),T("\\bull","\\bullet"),T("\\Chi","\\mathrm{X}"),T("\\clubs","\\clubsuit"),T("\\cnums","\\mathbb{C}"),T("\\Complex","\\mathbb{C}"),T("\\Dagger","\\ddagger"),T("\\diamonds","\\diamondsuit"),T("\\empty","\\emptyset"),T("\\Epsilon","\\mathrm{E}"),T("\\Eta","\\mathrm{H}"),T("\\exist","\\exists"),T("\\harr","\\leftrightarrow"),T("\\hArr","\\Leftrightarrow"),T("\\Harr","\\Leftrightarrow"),T("\\hearts","\\heartsuit"),T("\\image","\\Im"),T("\\infin","\\infty"),T("\\Iota","\\mathrm{I}"),T("\\isin","\\in"),T("\\Kappa","\\mathrm{K}"),T("\\larr","\\leftarrow"),T("\\lArr","\\Leftarrow"),T("\\Larr","\\Leftarrow"),T("\\lrarr","\\leftrightarrow"),T("\\lrArr","\\Leftrightarrow"),T("\\Lrarr","\\Leftrightarrow"),T("\\Mu","\\mathrm{M}"),T("\\natnums","\\mathbb{N}"),T("\\Nu","\\mathrm{N}"),T("\\Omicron","\\mathrm{O}"),T("\\plusmn","\\pm"),T("\\rarr","\\rightarrow"),T("\\rArr","\\Rightarrow"),T("\\Rarr","\\Rightarrow"),T("\\real","\\Re"),T("\\reals","\\mathbb{R}"),T("\\Reals","\\mathbb{R}"),T("\\Rho","\\mathrm{P}"),T("\\sdot","\\cdot"),T("\\sect","\\S"),T("\\spades","\\spadesuit"),T("\\sub","\\subset"),T("\\sube","\\subseteq"),T("\\supe","\\supseteq"),T("\\Tau","\\mathrm{T}"),T("\\thetasym","\\vartheta"),T("\\weierp","\\wp"),T("\\Zeta","\\mathrm{Z}"),T("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),T("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),T("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),T("\\bra","\\mathinner{\\langle{#1}|}"),T("\\ket","\\mathinner{|{#1}\\rangle}"),T("\\braket","\\mathinner{\\langle{#1}\\rangle}"),T("\\Bra","\\left\\langle#1\\right|"),T("\\Ket","\\left|#1\\right\\rangle"),T("\\bra@ket",Pr(!1)),T("\\bra@set",Pr(!0)),T("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),T("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),T("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),T("\\angln","{\\angl n}"),T("\\blue","\\textcolor{##6495ed}{#1}"),T("\\orange","\\textcolor{##ffa500}{#1}"),T("\\pink","\\textcolor{##ff00af}{#1}"),T("\\red","\\textcolor{##df0030}{#1}"),T("\\green","\\textcolor{##28ae7b}{#1}"),T("\\gray","\\textcolor{gray}{#1}"),T("\\purple","\\textcolor{##9d38bd}{#1}"),T("\\blueA","\\textcolor{##ccfaff}{#1}"),T("\\blueB","\\textcolor{##80f6ff}{#1}"),T("\\blueC","\\textcolor{##63d9ea}{#1}"),T("\\blueD","\\textcolor{##11accd}{#1}"),T("\\blueE","\\textcolor{##0c7f99}{#1}"),T("\\tealA","\\textcolor{##94fff5}{#1}"),T("\\tealB","\\textcolor{##26edd5}{#1}"),T("\\tealC","\\textcolor{##01d1c1}{#1}"),T("\\tealD","\\textcolor{##01a995}{#1}"),T("\\tealE","\\textcolor{##208170}{#1}"),T("\\greenA","\\textcolor{##b6ffb0}{#1}"),T("\\greenB","\\textcolor{##8af281}{#1}"),T("\\greenC","\\textcolor{##74cf70}{#1}"),T("\\greenD","\\textcolor{##1fab54}{#1}"),T("\\greenE","\\textcolor{##0d923f}{#1}"),T("\\goldA","\\textcolor{##ffd0a9}{#1}"),T("\\goldB","\\textcolor{##ffbb71}{#1}"),T("\\goldC","\\textcolor{##ff9c39}{#1}"),T("\\goldD","\\textcolor{##e07d10}{#1}"),T("\\goldE","\\textcolor{##a75a05}{#1}"),T("\\redA","\\textcolor{##fca9a9}{#1}"),T("\\redB","\\textcolor{##ff8482}{#1}"),T("\\redC","\\textcolor{##f9685d}{#1}"),T("\\redD","\\textcolor{##e84d39}{#1}"),T("\\redE","\\textcolor{##bc2612}{#1}"),T("\\maroonA","\\textcolor{##ffbde0}{#1}"),T("\\maroonB","\\textcolor{##ff92c6}{#1}"),T("\\maroonC","\\textcolor{##ed5fa6}{#1}"),T("\\maroonD","\\textcolor{##ca337c}{#1}"),T("\\maroonE","\\textcolor{##9e034e}{#1}"),T("\\purpleA","\\textcolor{##ddd7ff}{#1}"),T("\\purpleB","\\textcolor{##c6b9fc}{#1}"),T("\\purpleC","\\textcolor{##aa87ff}{#1}"),T("\\purpleD","\\textcolor{##7854ab}{#1}"),T("\\purpleE","\\textcolor{##543b78}{#1}"),T("\\mintA","\\textcolor{##f5f9e8}{#1}"),T("\\mintB","\\textcolor{##edf2df}{#1}"),T("\\mintC","\\textcolor{##e0e5cc}{#1}"),T("\\grayA","\\textcolor{##f6f7f7}{#1}"),T("\\grayB","\\textcolor{##f0f1f2}{#1}"),T("\\grayC","\\textcolor{##e3e5e6}{#1}"),T("\\grayD","\\textcolor{##d6d8da}{#1}"),T("\\grayE","\\textcolor{##babec2}{#1}"),T("\\grayF","\\textcolor{##888d93}{#1}"),T("\\grayG","\\textcolor{##626569}{#1}"),T("\\grayH","\\textcolor{##3b3e40}{#1}"),T("\\grayI","\\textcolor{##21242c}{#1}"),T("\\kaBlue","\\textcolor{##314453}{#1}"),T("\\kaGreen","\\textcolor{##71B307}{#1}"),{"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0}),Yr=((t=Kr.prototype).feed=function(e){this.lexer=new Or(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;var t=this.popToken(),e=this.consumeArg(["]"]),r=e.tokens,n=e.end}else{e=this.consumeArg();r=e.tokens,t=e.start,n=e.end}return this.pushToken(new D0("EOF",n.loc)),this.pushTokens(r),t.range(n,"")},t.consumeSpaces=function(){for(;" "===this.future().text;)this.stack.pop()},t.consumeArg=function(e){var t=[],r=e&&0this.settings.maxExpand)throw new $("Too many expansions: infinite loop or need to increase maxExpand setting");var i=n.tokens,a=this.consumeArgs(n.numArgs,n.delimiters);if(n.numArgs)for(var o=(i=i.slice()).length-1;0<=o;--o){var s=i[o];if("#"===s.text){if(0===o)throw new $("Incomplete placeholder at end of macro body",s);if("#"===(s=i[--o]).text)i.splice(o+1,1);else{if(!/^[1-9]$/.test(s.text))throw new $("Not a valid argument number",s);i.splice.apply(i,[o,2].concat(a[+s.text-1]))}}}return this.pushTokens(i),i},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof D0)return e.treatAsRelax&&(e.text="\\relax"),this.stack.pop()}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new D0(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof D0&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},t.expandMacroAsText=function(e){e=this.expandMacro(e);return e&&e.map(function(e){return e.text}).join("")},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){e=this.lexer.catcodes[e];if(null!=e&&13!==e)return}e="function"==typeof t?t(this):t;if("string"!=typeof e)return e;var r=0;if(-1!==e.indexOf("#"))for(var n=e.replace(/##/g,"");-1!==n.indexOf("#"+(r+1));)++r;for(var i=new Or(e,this.settings),a=[],o=i.lex();"EOF"!==o.text;)a.push(o),o=i.lex();return a.reverse(),{tokens:a,numArgs:r}},t.isDefined=function(e){return this.macros.has(e)||qr.hasOwnProperty(e)||p.math.hasOwnProperty(e)||p.text.hasOwnProperty(e)||Ur.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:qr.hasOwnProperty(e)&&!qr[e].primitive},Kr),Xr=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,Wr=Object.freeze({"₊":"+","₋":"-","₌":"=","₍":"(","₎":")","₀":"0","₁":"1","₂":"2","₃":"3","₄":"4","₅":"5","₆":"6","₇":"7","₈":"8","₉":"9","ₐ":"a","ₑ":"e","ₕ":"h","ᵢ":"i","ⱼ":"j","ₖ":"k","ₗ":"l","ₘ":"m","ₙ":"n","ₒ":"o","ₚ":"p","ᵣ":"r","ₛ":"s","ₜ":"t","ᵤ":"u","ᵥ":"v","ₓ":"x","ᵦ":"β","ᵧ":"γ","ᵨ":"ρ","ᵩ":"ϕ","ᵪ":"χ","⁺":"+","⁻":"-","⁼":"=","⁽":"(","⁾":")","⁰":"0","¹":"1","²":"2","³":"3","⁴":"4","⁵":"5","⁶":"6","⁷":"7","⁸":"8","⁹":"9","ᴬ":"A","ᴮ":"B","ᴰ":"D","ᴱ":"E","ᴳ":"G","ᴴ":"H","ᴵ":"I","ᴶ":"J","ᴷ":"K","ᴸ":"L","ᴹ":"M","ᴺ":"N","ᴼ":"O","ᴾ":"P","ᴿ":"R","ᵀ":"T","ᵁ":"U","ⱽ":"V","ᵂ":"W","ᵃ":"a","ᵇ":"b","ᶜ":"c","ᵈ":"d","ᵉ":"e","ᶠ":"f","ᵍ":"g","ʰ":"h","ⁱ":"i","ʲ":"j","ᵏ":"k","ˡ":"l","ᵐ":"m","ⁿ":"n","ᵒ":"o","ᵖ":"p","ʳ":"r","ˢ":"s","ᵗ":"t","ᵘ":"u","ᵛ":"v","ʷ":"w","ˣ":"x","ʸ":"y","ᶻ":"z","ᵝ":"β","ᵞ":"γ","ᵟ":"δ","ᵠ":"ϕ","ᵡ":"χ","ᶿ":"θ"}),jr={"́":{text:"\\'",math:"\\acute"},"̀":{text:"\\`",math:"\\grave"},"̈":{text:'\\"',math:"\\ddot"},"̃":{text:"\\~",math:"\\tilde"},"̄":{text:"\\=",math:"\\bar"},"̆":{text:"\\u",math:"\\breve"},"̌":{text:"\\v",math:"\\check"},"̂":{text:"\\^",math:"\\hat"},"̇":{text:"\\.",math:"\\dot"},"̊":{text:"\\r",math:"\\mathring"},"̋":{text:"\\H"},"̧":{text:"\\c"}},_r={"á":"á","à":"à","ä":"ä","ǟ":"ǟ","ã":"ã","ā":"ā","ă":"ă","ắ":"ắ","ằ":"ằ","ẵ":"ẵ","ǎ":"ǎ","â":"â","ấ":"ấ","ầ":"ầ","ẫ":"ẫ","ȧ":"ȧ","ǡ":"ǡ","å":"å","ǻ":"ǻ","ḃ":"ḃ","ć":"ć","ḉ":"ḉ","č":"č","ĉ":"ĉ","ċ":"ċ","ç":"ç","ď":"ď","ḋ":"ḋ","ḑ":"ḑ","é":"é","è":"è","ë":"ë","ẽ":"ẽ","ē":"ē","ḗ":"ḗ","ḕ":"ḕ","ĕ":"ĕ","ḝ":"ḝ","ě":"ě","ê":"ê","ế":"ế","ề":"ề","ễ":"ễ","ė":"ė","ȩ":"ȩ","ḟ":"ḟ","ǵ":"ǵ","ḡ":"ḡ","ğ":"ğ","ǧ":"ǧ","ĝ":"ĝ","ġ":"ġ","ģ":"ģ","ḧ":"ḧ","ȟ":"ȟ","ĥ":"ĥ","ḣ":"ḣ","ḩ":"ḩ","í":"í","ì":"ì","ï":"ï","ḯ":"ḯ","ĩ":"ĩ","ī":"ī","ĭ":"ĭ","ǐ":"ǐ","î":"î","ǰ":"ǰ","ĵ":"ĵ","ḱ":"ḱ","ǩ":"ǩ","ķ":"ķ","ĺ":"ĺ","ľ":"ľ","ļ":"ļ","ḿ":"ḿ","ṁ":"ṁ","ń":"ń","ǹ":"ǹ","ñ":"ñ","ň":"ň","ṅ":"ṅ","ņ":"ņ","ó":"ó","ò":"ò","ö":"ö","ȫ":"ȫ","õ":"õ","ṍ":"ṍ","ṏ":"ṏ","ȭ":"ȭ","ō":"ō","ṓ":"ṓ","ṑ":"ṑ","ŏ":"ŏ","ǒ":"ǒ","ô":"ô","ố":"ố","ồ":"ồ","ỗ":"ỗ","ȯ":"ȯ","ȱ":"ȱ","ő":"ő","ṕ":"ṕ","ṗ":"ṗ","ŕ":"ŕ","ř":"ř","ṙ":"ṙ","ŗ":"ŗ","ś":"ś","ṥ":"ṥ","š":"š","ṧ":"ṧ","ŝ":"ŝ","ṡ":"ṡ","ş":"ş","ẗ":"ẗ","ť":"ť","ṫ":"ṫ","ţ":"ţ","ú":"ú","ù":"ù","ü":"ü","ǘ":"ǘ","ǜ":"ǜ","ǖ":"ǖ","ǚ":"ǚ","ũ":"ũ","ṹ":"ṹ","ū":"ū","ṻ":"ṻ","ŭ":"ŭ","ǔ":"ǔ","û":"û","ů":"ů","ű":"ű","ṽ":"ṽ","ẃ":"ẃ","ẁ":"ẁ","ẅ":"ẅ","ŵ":"ŵ","ẇ":"ẇ","ẘ":"ẘ","ẍ":"ẍ","ẋ":"ẋ","ý":"ý","ỳ":"ỳ","ÿ":"ÿ","ỹ":"ỹ","ȳ":"ȳ","ŷ":"ŷ","ẏ":"ẏ","ẙ":"ẙ","ź":"ź","ž":"ž","ẑ":"ẑ","ż":"ż","Á":"Á","À":"À","Ä":"Ä","Ǟ":"Ǟ","Ã":"Ã","Ā":"Ā","Ă":"Ă","Ắ":"Ắ","Ằ":"Ằ","Ẵ":"Ẵ","Ǎ":"Ǎ","Â":"Â","Ấ":"Ấ","Ầ":"Ầ","Ẫ":"Ẫ","Ȧ":"Ȧ","Ǡ":"Ǡ","Å":"Å","Ǻ":"Ǻ","Ḃ":"Ḃ","Ć":"Ć","Ḉ":"Ḉ","Č":"Č","Ĉ":"Ĉ","Ċ":"Ċ","Ç":"Ç","Ď":"Ď","Ḋ":"Ḋ","Ḑ":"Ḑ","É":"É","È":"È","Ë":"Ë","Ẽ":"Ẽ","Ē":"Ē","Ḗ":"Ḗ","Ḕ":"Ḕ","Ĕ":"Ĕ","Ḝ":"Ḝ","Ě":"Ě","Ê":"Ê","Ế":"Ế","Ề":"Ề","Ễ":"Ễ","Ė":"Ė","Ȩ":"Ȩ","Ḟ":"Ḟ","Ǵ":"Ǵ","Ḡ":"Ḡ","Ğ":"Ğ","Ǧ":"Ǧ","Ĝ":"Ĝ","Ġ":"Ġ","Ģ":"Ģ","Ḧ":"Ḧ","Ȟ":"Ȟ","Ĥ":"Ĥ","Ḣ":"Ḣ","Ḩ":"Ḩ","Í":"Í","Ì":"Ì","Ï":"Ï","Ḯ":"Ḯ","Ĩ":"Ĩ","Ī":"Ī","Ĭ":"Ĭ","Ǐ":"Ǐ","Î":"Î","İ":"İ","Ĵ":"Ĵ","Ḱ":"Ḱ","Ǩ":"Ǩ","Ķ":"Ķ","Ĺ":"Ĺ","Ľ":"Ľ","Ļ":"Ļ","Ḿ":"Ḿ","Ṁ":"Ṁ","Ń":"Ń","Ǹ":"Ǹ","Ñ":"Ñ","Ň":"Ň","Ṅ":"Ṅ","Ņ":"Ņ","Ó":"Ó","Ò":"Ò","Ö":"Ö","Ȫ":"Ȫ","Õ":"Õ","Ṍ":"Ṍ","Ṏ":"Ṏ","Ȭ":"Ȭ","Ō":"Ō","Ṓ":"Ṓ","Ṑ":"Ṑ","Ŏ":"Ŏ","Ǒ":"Ǒ","Ô":"Ô","Ố":"Ố","Ồ":"Ồ","Ỗ":"Ỗ","Ȯ":"Ȯ","Ȱ":"Ȱ","Ő":"Ő","Ṕ":"Ṕ","Ṗ":"Ṗ","Ŕ":"Ŕ","Ř":"Ř","Ṙ":"Ṙ","Ŗ":"Ŗ","Ś":"Ś","Ṥ":"Ṥ","Š":"Š","Ṧ":"Ṧ","Ŝ":"Ŝ","Ṡ":"Ṡ","Ş":"Ş","Ť":"Ť","Ṫ":"Ṫ","Ţ":"Ţ","Ú":"Ú","Ù":"Ù","Ü":"Ü","Ǘ":"Ǘ","Ǜ":"Ǜ","Ǖ":"Ǖ","Ǚ":"Ǚ","Ũ":"Ũ","Ṹ":"Ṹ","Ū":"Ū","Ṻ":"Ṻ","Ŭ":"Ŭ","Ǔ":"Ǔ","Û":"Û","Ů":"Ů","Ű":"Ű","Ṽ":"Ṽ","Ẃ":"Ẃ","Ẁ":"Ẁ","Ẅ":"Ẅ","Ŵ":"Ŵ","Ẇ":"Ẇ","Ẍ":"Ẍ","Ẋ":"Ẋ","Ý":"Ý","Ỳ":"Ỳ","Ÿ":"Ÿ","Ỹ":"Ỹ","Ȳ":"Ȳ","Ŷ":"Ŷ","Ẏ":"Ẏ","Ź":"Ź","Ž":"Ž","Ẑ":"Ẑ","Ż":"Ż","ά":"ά","ὰ":"ὰ","ᾱ":"ᾱ","ᾰ":"ᾰ","έ":"έ","ὲ":"ὲ","ή":"ή","ὴ":"ὴ","ί":"ί","ὶ":"ὶ","ϊ":"ϊ","ΐ":"ΐ","ῒ":"ῒ","ῑ":"ῑ","ῐ":"ῐ","ό":"ό","ὸ":"ὸ","ύ":"ύ","ὺ":"ὺ","ϋ":"ϋ","ΰ":"ΰ","ῢ":"ῢ","ῡ":"ῡ","ῠ":"ῠ","ώ":"ώ","ὼ":"ὼ","Ύ":"Ύ","Ὺ":"Ὺ","Ϋ":"Ϋ","Ῡ":"Ῡ","Ῠ":"Ῠ","Ώ":"Ώ","Ὼ":"Ὼ"},$r=((c=Zr.prototype).expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new $("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},c.consume=function(){this.nextToken=null},c.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},c.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},c.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},c.subparse=function(e){var t=this.nextToken,e=(this.consume(),this.gullet.pushToken(new D0("}")),this.gullet.pushTokens(e),this.parseExpression(!1));return this.expect("}"),this.nextToken=t,e},c.parseExpression=function(e,t){for(var r=[];;){"math"===this.mode&&this.consumeSpaces();var n=this.fetch();if(-1!==Zr.endOfExpression.indexOf(n.text))break;if(t&&n.text===t)break;if(e&&qr[n.text]&&qr[n.text].infix)break;n=this.parseAtom(t);if(!n)break;"internal"!==n.type&&r.push(n)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)},c.handleInfixNodes=function(e){for(var t,r,n,i=-1,a=0;a= sbp.limit) + return; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 248)) { + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + I_p1 = sbp.cursor; + if (I_p1 < I_x) + I_p1 = I_x; + } + } + + function r_main_suffix() { + var among_var, v_1; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_0, 32); + sbp.limit_backward = v_1; + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + if (sbp.in_grouping_b(g_s_ending, 97, 229)) + sbp.slice_del(); + break; + } + } + } + } + + function r_consonant_pair() { + var v_1 = sbp.limit - sbp.cursor, + v_2; + if (sbp.cursor >= I_p1) { + v_2 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + if (sbp.find_among_b(a_1, 4)) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_2; + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + } else + sbp.limit_backward = v_2; + } + } + + function r_other_suffix() { + var among_var, v_1 = sbp.limit - sbp.cursor, + v_2, v_3; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "st")) { + sbp.bra = sbp.cursor; + if (sbp.eq_s_b(2, "ig")) + sbp.slice_del(); + } + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor >= I_p1) { + v_2 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 5); + sbp.limit_backward = v_2; + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_del(); + v_3 = sbp.limit - sbp.cursor; + r_consonant_pair(); + sbp.cursor = sbp.limit - v_3; + break; + case 2: + sbp.slice_from("l\u00F8s"); + break; + } + } + } + } + + function r_undouble() { + var v_1; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + if (sbp.out_grouping_b(g_v, 97, 248)) { + sbp.bra = sbp.cursor; + S_ch = sbp.slice_to(S_ch); + sbp.limit_backward = v_1; + if (sbp.eq_v_b(S_ch)) + sbp.slice_del(); + } else + sbp.limit_backward = v_1; + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_main_suffix(); + sbp.cursor = sbp.limit; + r_consonant_pair(); + sbp.cursor = sbp.limit; + r_other_suffix(); + sbp.cursor = sbp.limit; + r_undouble(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.da.stemmer, 'stemmer-da'); + + /* stop word filter function */ + lunr.da.stopWordFilter = function(token) { + if (lunr.da.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.da.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.da.stopWordFilter.stopWords.length = 95; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.da.stopWordFilter.stopWords.elements = ' ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været'.split(' '); + + lunr.Pipeline.registerFunction(lunr.da.stopWordFilter, 'stopWordFilter-da'); + }; +})) \ No newline at end of file diff --git a/js/lunr.da.min.js b/js/lunr.da.min.js new file mode 100644 index 0000000..2c3f742 --- /dev/null +++ b/js/lunr.da.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,t,i;r.da=function(){this.pipeline.reset(),this.pipeline.add(r.da.trimmer,r.da.stopWordFilter,r.da.stemmer)},r.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.da.trimmer=r.trimmerSupport.generateTrimmer(r.da.wordCharacters),r.Pipeline.registerFunction(r.da.trimmer,"trimmer-da"),r.da.stemmer=(e=r.stemmerSupport.Among,t=r.stemmerSupport.SnowballProgram,i=new function(){var n,s,o,d=[new e("hed",-1,1),new e("ethed",0,1),new e("ered",-1,1),new e("e",-1,1),new e("erede",3,1),new e("ende",3,1),new e("erende",5,1),new e("ene",3,1),new e("erne",3,1),new e("ere",3,1),new e("en",-1,1),new e("heden",10,1),new e("eren",10,1),new e("er",-1,1),new e("heder",13,1),new e("erer",13,1),new e("s",-1,2),new e("heds",16,1),new e("es",16,1),new e("endes",18,1),new e("erendes",19,1),new e("enes",18,1),new e("ernes",18,1),new e("eres",18,1),new e("ens",16,1),new e("hedens",24,1),new e("erens",24,1),new e("ers",16,1),new e("ets",16,1),new e("erets",28,1),new e("et",-1,1),new e("eret",30,1)],i=[new e("gd",-1,-1),new e("dt",-1,-1),new e("gt",-1,-1),new e("kt",-1,-1)],a=[new e("ig",-1,1),new e("lig",0,1),new e("elig",1,1),new e("els",-1,1),new e("løst",-1,2)],u=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],l=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new t;function m(){var e,r=c.limit-c.cursor;c.cursor>=s&&(e=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,c.find_among_b(i,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var e,r=c.cursor;if(!function(){var e,r=c.cursor+3;if(s=c.limit,0<=r&&r<=c.limit){for(n=r;;){if(e=c.cursor,c.in_grouping(u,97,248)){c.cursor=e;break}if((c.cursor=e)>=c.limit)return;c.cursor++}for(;!c.out_grouping(u,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(s=c.cursor)=s&&(r=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,e=c.find_among_b(d,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(l,97,229)&&c.slice_del()}c.cursor=c.limit,m(),c.cursor=c.limit;var i,t,r=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,"st")&&(c.bra=c.cursor,c.eq_s_b(2,"ig"))&&c.slice_del(),c.cursor=c.limit-r,c.cursor>=s&&(r=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,i=c.find_among_b(a,5),c.limit_backward=r,i))switch(c.bra=c.cursor,i){case 1:c.slice_del(),t=c.limit-c.cursor,m(),c.cursor=c.limit-t;break;case 2:c.slice_from("løs")}return c.cursor=c.limit,c.cursor>=s&&(e=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,c.out_grouping_b(u,97,248)?(c.bra=c.cursor,o=c.slice_to(o),c.limit_backward=e,c.eq_v_b(o)&&c.slice_del()):c.limit_backward=e),!0}},function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}),r.Pipeline.registerFunction(r.da.stemmer,"stemmer-da"),r.da.stopWordFilter=function(e){if(-1===r.da.stopWordFilter.stopWords.indexOf(e))return e},r.da.stopWordFilter.stopWords=new r.SortedSet,r.da.stopWordFilter.stopWords.length=95,r.da.stopWordFilter.stopWords.elements=" ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" "),r.Pipeline.registerFunction(r.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/js/lunr.de.js b/js/lunr.de.js new file mode 100644 index 0000000..3ed2b93 --- /dev/null +++ b/js/lunr.de.js @@ -0,0 +1,380 @@ +/*! + * Lunr languages, `German` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.de = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.de.trimmer, + lunr.de.stopWordFilter, + lunr.de.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.de.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.de.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.de.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.de.trimmer, 'trimmer-de'); + + /* lunr stemmer function */ + lunr.de.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function GermanStemmer() { + var a_0 = [new Among("", -1, 6), new Among("U", 0, 2), + new Among("Y", 0, 1), new Among("\u00E4", 0, 3), + new Among("\u00F6", 0, 4), new Among("\u00FC", 0, 5) + ], + a_1 = [ + new Among("e", -1, 2), new Among("em", -1, 1), + new Among("en", -1, 2), new Among("ern", -1, 1), + new Among("er", -1, 1), new Among("s", -1, 3), + new Among("es", 5, 2) + ], + a_2 = [new Among("en", -1, 1), + new Among("er", -1, 1), new Among("st", -1, 2), + new Among("est", 2, 1) + ], + a_3 = [new Among("ig", -1, 1), + new Among("lich", -1, 1) + ], + a_4 = [new Among("end", -1, 1), + new Among("ig", -1, 2), new Among("ung", -1, 1), + new Among("lich", -1, 3), new Among("isch", -1, 2), + new Among("ik", -1, 2), new Among("heit", -1, 3), + new Among("keit", -1, 4) + ], + g_v = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8, 0, 32, 8 + ], + g_s_ending = [117, 30, 5], + g_st_ending = [ + 117, 30, 4 + ], + I_x, I_p2, I_p1, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function habr1(c1, c2, v_1) { + if (sbp.eq_s(1, c1)) { + sbp.ket = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 252)) { + sbp.slice_from(c2); + sbp.cursor = v_1; + return true; + } + } + return false; + } + + function r_prelude() { + var v_1 = sbp.cursor, + v_2, v_3, v_4, v_5; + while (true) { + v_2 = sbp.cursor; + sbp.bra = v_2; + if (sbp.eq_s(1, "\u00DF")) { + sbp.ket = sbp.cursor; + sbp.slice_from("ss"); + } else { + if (v_2 >= sbp.limit) + break; + sbp.cursor = v_2 + 1; + } + } + sbp.cursor = v_1; + while (true) { + v_3 = sbp.cursor; + while (true) { + v_4 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 252)) { + v_5 = sbp.cursor; + sbp.bra = v_5; + if (habr1("u", "U", v_4)) + break; + sbp.cursor = v_5; + if (habr1("y", "Y", v_4)) + break; + } + if (v_4 >= sbp.limit) { + sbp.cursor = v_3; + return; + } + sbp.cursor = v_4 + 1; + } + } + } + + function habr2() { + while (!sbp.in_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + + function r_mark_regions() { + I_p1 = sbp.limit; + I_p2 = I_p1; + var c = sbp.cursor + 3; + if (0 <= c && c <= sbp.limit) { + I_x = c; + if (!habr2()) { + I_p1 = sbp.cursor; + if (I_p1 < I_x) + I_p1 = I_x; + if (!habr2()) + I_p2 = sbp.cursor; + } + } + } + + function r_postlude() { + var among_var, v_1; + while (true) { + v_1 = sbp.cursor; + sbp.bra = v_1; + among_var = sbp.find_among(a_0, 6); + if (!among_var) + return; + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("y"); + break; + case 2: + case 5: + sbp.slice_from("u"); + break; + case 3: + sbp.slice_from("a"); + break; + case 4: + sbp.slice_from("o"); + break; + case 6: + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + break; + } + } + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_standard_suffix() { + var among_var, v_1 = sbp.limit - sbp.cursor, + v_2, v_3, v_4; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_1, 7); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "s")) { + sbp.bra = sbp.cursor; + if (sbp.eq_s_b(3, "nis")) + sbp.slice_del(); + } + break; + case 3: + if (sbp.in_grouping_b(g_s_ending, 98, 116)) + sbp.slice_del(); + break; + } + } + } + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 4); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + if (sbp.in_grouping_b(g_st_ending, 98, 116)) { + var c = sbp.cursor - 3; + if (sbp.limit_backward <= c && c <= sbp.limit) { + sbp.cursor = c; + sbp.slice_del(); + } + } + break; + } + } + } + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 8); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2()) { + switch (among_var) { + case 1: + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ig")) { + sbp.bra = sbp.cursor; + v_2 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "e")) { + sbp.cursor = sbp.limit - v_2; + if (r_R2()) + sbp.slice_del(); + } + } + break; + case 2: + v_3 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "e")) { + sbp.cursor = sbp.limit - v_3; + sbp.slice_del(); + } + break; + case 3: + sbp.slice_del(); + sbp.ket = sbp.cursor; + v_4 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(2, "er")) { + sbp.cursor = sbp.limit - v_4; + if (!sbp.eq_s_b(2, "en")) + break; + } + sbp.bra = sbp.cursor; + if (r_R1()) + sbp.slice_del(); + break; + case 4: + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 2); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2() && among_var == 1) + sbp.slice_del(); + } + break; + } + } + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_prelude(); + sbp.cursor = v_1; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_standard_suffix(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.de.stemmer, 'stemmer-de'); + + /* stop word filter function */ + lunr.de.stopWordFilter = function(token) { + if (lunr.de.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.de.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.de.stopWordFilter.stopWords.length = 232; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.de.stopWordFilter.stopWords.elements = ' aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über'.split(' '); + + lunr.Pipeline.registerFunction(lunr.de.stopWordFilter, 'stopWordFilter-de'); + }; +})) \ No newline at end of file diff --git a/js/lunr.de.min.js b/js/lunr.de.min.js new file mode 100644 index 0000000..a10d26b --- /dev/null +++ b/js/lunr.de.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,n,i;r.de=function(){this.pipeline.reset(),this.pipeline.add(r.de.trimmer,r.de.stopWordFilter,r.de.stemmer)},r.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.de.trimmer=r.trimmerSupport.generateTrimmer(r.de.wordCharacters),r.Pipeline.registerFunction(r.de.trimmer,"trimmer-de"),r.de.stemmer=(e=r.stemmerSupport.Among,n=r.stemmerSupport.SnowballProgram,i=new function(){var t,o,c,u=[new e("",-1,6),new e("U",0,2),new e("Y",0,1),new e("ä",0,3),new e("ö",0,4),new e("ü",0,5)],d=[new e("e",-1,2),new e("em",-1,1),new e("en",-1,2),new e("ern",-1,1),new e("er",-1,1),new e("s",-1,3),new e("es",5,2)],l=[new e("en",-1,1),new e("er",-1,1),new e("st",-1,2),new e("est",2,1)],a=[new e("ig",-1,1),new e("lich",-1,1)],m=[new e("end",-1,1),new e("ig",-1,2),new e("ung",-1,1),new e("lich",-1,3),new e("isch",-1,2),new e("ik",-1,2),new e("heit",-1,3),new e("keit",-1,4)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],h=[117,30,5],b=[117,30,4],f=new n;function _(e,r,n){return f.eq_s(1,e)&&(f.ket=f.cursor,f.in_grouping(w,97,252))&&(f.slice_from(r),f.cursor=n,1)}function p(){for(;!f.in_grouping(w,97,252);){if(f.cursor>=f.limit)return 1;f.cursor++}for(;!f.out_grouping(w,97,252);){if(f.cursor>=f.limit)return 1;f.cursor++}}function g(){return c<=f.cursor}function k(){return o<=f.cursor}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e=f.cursor;!function(){for(var e,r,n,i,s=f.cursor;;)if(e=f.cursor,f.bra=e,f.eq_s(1,"ß"))f.ket=f.cursor,f.slice_from("ss");else{if(e>=f.limit)break;f.cursor=e+1}for(f.cursor=s;;)for(r=f.cursor;;){if(n=f.cursor,f.in_grouping(w,97,252)){if(i=f.cursor,f.bra=i,_("u","U",n))break;if(f.cursor=i,_("y","Y",n))break}if(n>=f.limit)return f.cursor=r;f.cursor=n+1}}(),f.cursor=e,c=f.limit,o=c,0<=(s=f.cursor+3)&&s<=f.limit&&(t=s,p()||((c=f.cursor)=f.limit)return;f.cursor++}}}(),!0}},function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}),r.Pipeline.registerFunction(r.de.stemmer,"stemmer-de"),r.de.stopWordFilter=function(e){if(-1===r.de.stopWordFilter.stopWords.indexOf(e))return e},r.de.stopWordFilter.stopWords=new r.SortedSet,r.de.stopWordFilter.stopWords.length=232,r.de.stopWordFilter.stopWords.elements=" aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" "),r.Pipeline.registerFunction(r.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/js/lunr.du.js b/js/lunr.du.js new file mode 100644 index 0000000..7d13826 --- /dev/null +++ b/js/lunr.du.js @@ -0,0 +1,444 @@ +/*! + * Lunr languages, `Dutch` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.du = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.du.trimmer, + lunr.du.stopWordFilter, + lunr.du.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.du.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.du.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.du.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.du.trimmer, 'trimmer-du'); + + /* lunr stemmer function */ + lunr.du.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function DutchStemmer() { + var a_0 = [new Among("", -1, 6), new Among("\u00E1", 0, 1), + new Among("\u00E4", 0, 1), new Among("\u00E9", 0, 2), + new Among("\u00EB", 0, 2), new Among("\u00ED", 0, 3), + new Among("\u00EF", 0, 3), new Among("\u00F3", 0, 4), + new Among("\u00F6", 0, 4), new Among("\u00FA", 0, 5), + new Among("\u00FC", 0, 5) + ], + a_1 = [new Among("", -1, 3), + new Among("I", 0, 2), new Among("Y", 0, 1) + ], + a_2 = [ + new Among("dd", -1, -1), new Among("kk", -1, -1), + new Among("tt", -1, -1) + ], + a_3 = [new Among("ene", -1, 2), + new Among("se", -1, 3), new Among("en", -1, 2), + new Among("heden", 2, 1), new Among("s", -1, 3) + ], + a_4 = [ + new Among("end", -1, 1), new Among("ig", -1, 2), + new Among("ing", -1, 1), new Among("lijk", -1, 3), + new Among("baar", -1, 4), new Among("bar", -1, 5) + ], + a_5 = [ + new Among("aa", -1, -1), new Among("ee", -1, -1), + new Among("oo", -1, -1), new Among("uu", -1, -1) + ], + g_v = [17, 65, + 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 + ], + g_v_I = [1, 0, 0, + 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 + ], + g_v_j = [ + 17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 + ], + I_p2, I_p1, B_e_found, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function r_prelude() { + var among_var, v_1 = sbp.cursor, + v_2, v_3; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_0, 11); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("a"); + continue; + case 2: + sbp.slice_from("e"); + continue; + case 3: + sbp.slice_from("i"); + continue; + case 4: + sbp.slice_from("o"); + continue; + case 5: + sbp.slice_from("u"); + continue; + case 6: + if (sbp.cursor >= sbp.limit) + break; + sbp.cursor++; + continue; + } + } + break; + } + sbp.cursor = v_1; + sbp.bra = v_1; + if (sbp.eq_s(1, "y")) { + sbp.ket = sbp.cursor; + sbp.slice_from("Y"); + } else + sbp.cursor = v_1; + while (true) { + v_2 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 232)) { + v_3 = sbp.cursor; + sbp.bra = v_3; + if (sbp.eq_s(1, "i")) { + sbp.ket = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 232)) { + sbp.slice_from("I"); + sbp.cursor = v_2; + } + } else { + sbp.cursor = v_3; + if (sbp.eq_s(1, "y")) { + sbp.ket = sbp.cursor; + sbp.slice_from("Y"); + sbp.cursor = v_2; + } else if (habr1(v_2)) + break; + } + } else if (habr1(v_2)) + break; + } + } + + function habr1(v_1) { + sbp.cursor = v_1; + if (v_1 >= sbp.limit) + return true; + sbp.cursor++; + return false; + } + + function r_mark_regions() { + I_p1 = sbp.limit; + I_p2 = I_p1; + if (!habr2()) { + I_p1 = sbp.cursor; + if (I_p1 < 3) + I_p1 = 3; + if (!habr2()) + I_p2 = sbp.cursor; + } + } + + function habr2() { + while (!sbp.in_grouping(g_v, 97, 232)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 232)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + + function r_postlude() { + var among_var; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_1, 3); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("y"); + break; + case 2: + sbp.slice_from("i"); + break; + case 3: + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + break; + } + } + } + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_undouble() { + var v_1 = sbp.limit - sbp.cursor; + if (sbp.find_among_b(a_2, 3)) { + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + } + } + + function r_e_ending() { + var v_1; + B_e_found = false; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "e")) { + sbp.bra = sbp.cursor; + if (r_R1()) { + v_1 = sbp.limit - sbp.cursor; + if (sbp.out_grouping_b(g_v, 97, 232)) { + sbp.cursor = sbp.limit - v_1; + sbp.slice_del(); + B_e_found = true; + r_undouble(); + } + } + } + } + + function r_en_ending() { + var v_1; + if (r_R1()) { + v_1 = sbp.limit - sbp.cursor; + if (sbp.out_grouping_b(g_v, 97, 232)) { + sbp.cursor = sbp.limit - v_1; + if (!sbp.eq_s_b(3, "gem")) { + sbp.cursor = sbp.limit - v_1; + sbp.slice_del(); + r_undouble(); + } + } + } + } + + function r_standard_suffix() { + var among_var, v_1 = sbp.limit - sbp.cursor, + v_2, v_3, v_4, v_5, v_6; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 5); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R1()) + sbp.slice_from("heid"); + break; + case 2: + r_en_ending(); + break; + case 3: + if (r_R1() && sbp.out_grouping_b(g_v_j, 97, 232)) + sbp.slice_del(); + break; + } + } + sbp.cursor = sbp.limit - v_1; + r_e_ending(); + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(4, "heid")) { + sbp.bra = sbp.cursor; + if (r_R2()) { + v_2 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "c")) { + sbp.cursor = sbp.limit - v_2; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "en")) { + sbp.bra = sbp.cursor; + r_en_ending(); + } + } + } + } + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 6); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R2()) { + sbp.slice_del(); + v_3 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ig")) { + sbp.bra = sbp.cursor; + if (r_R2()) { + v_4 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "e")) { + sbp.cursor = sbp.limit - v_4; + sbp.slice_del(); + break; + } + } + } + sbp.cursor = sbp.limit - v_3; + r_undouble(); + } + break; + case 2: + if (r_R2()) { + v_5 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "e")) { + sbp.cursor = sbp.limit - v_5; + sbp.slice_del(); + } + } + break; + case 3: + if (r_R2()) { + sbp.slice_del(); + r_e_ending(); + } + break; + case 4: + if (r_R2()) + sbp.slice_del(); + break; + case 5: + if (r_R2() && B_e_found) + sbp.slice_del(); + break; + } + } + sbp.cursor = sbp.limit - v_1; + if (sbp.out_grouping_b(g_v_I, 73, 232)) { + v_6 = sbp.limit - sbp.cursor; + if (sbp.find_among_b(a_5, 4) && sbp.out_grouping_b(g_v, 97, 232)) { + sbp.cursor = sbp.limit - v_6; + sbp.ket = sbp.cursor; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + } + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_prelude(); + sbp.cursor = v_1; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_standard_suffix(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.du.stemmer, 'stemmer-du'); + + /* stop word filter function */ + lunr.du.stopWordFilter = function(token) { + if (lunr.du.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.du.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.du.stopWordFilter.stopWords.length = 103; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.du.stopWordFilter.stopWords.elements = ' aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou'.split(' '); + + lunr.Pipeline.registerFunction(lunr.du.stopWordFilter, 'stopWordFilter-du'); + }; +})) \ No newline at end of file diff --git a/js/lunr.du.min.js b/js/lunr.du.min.js new file mode 100644 index 0000000..a93f314 --- /dev/null +++ b/js/lunr.du.min.js @@ -0,0 +1 @@ +!function(r,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(r.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,i,o;e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer)},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=(r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,o=new function(){var c,a,l,m=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],d=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],e=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],f=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],w=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],b=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],p=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],g=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],k=new i;function h(r){if((k.cursor=r)>=k.limit)return 1;k.cursor++}function v(){for(;!k.in_grouping(b,97,232);){if(k.cursor>=k.limit)return 1;k.cursor++}for(;!k.out_grouping(b,97,232);){if(k.cursor>=k.limit)return 1;k.cursor++}}function q(){return a<=k.cursor}function z(){return c<=k.cursor}function W(){var r=k.limit-k.cursor;k.find_among_b(e,3)&&(k.cursor=k.limit-r,k.ket=k.cursor,k.cursor>k.limit_backward)&&(k.cursor--,k.bra=k.cursor,k.slice_del())}function j(){var r;l=!1,k.ket=k.cursor,k.eq_s_b(1,"e")&&(k.bra=k.cursor,q())&&(r=k.limit-k.cursor,k.out_grouping_b(b,97,232))&&(k.cursor=k.limit-r,k.slice_del(),l=!0,W())}function F(){var r;q()&&(r=k.limit-k.cursor,k.out_grouping_b(b,97,232))&&(k.cursor=k.limit-r,k.eq_s_b(3,"gem")||(k.cursor=k.limit-r,k.slice_del(),W()))}this.setCurrent=function(r){k.setCurrent(r)},this.getCurrent=function(){return k.getCurrent()},this.stem=function(){for(var r,e,i,o=k.cursor,t=k.cursor;;){if(k.bra=k.cursor,r=k.find_among(m,11))switch(k.ket=k.cursor,r){case 1:k.slice_from("a");continue;case 2:k.slice_from("e");continue;case 3:k.slice_from("i");continue;case 4:k.slice_from("o");continue;case 5:k.slice_from("u");continue;case 6:if(!(k.cursor>=k.limit)){k.cursor++;continue}}break}for(k.cursor=t,k.bra=t,k.eq_s(1,"y")?(k.ket=k.cursor,k.slice_from("Y")):k.cursor=t;;)if(e=k.cursor,k.in_grouping(b,97,232)){if(i=k.cursor,k.bra=i,k.eq_s(1,"i"))k.ket=k.cursor,k.in_grouping(b,97,232)&&(k.slice_from("I"),k.cursor=e);else if(k.cursor=i,k.eq_s(1,"y"))k.ket=k.cursor,k.slice_from("Y"),k.cursor=e;else if(h(e))break}else if(h(e))break;k.cursor=o,a=k.limit,c=a,v()||((a=k.cursor)<3&&(a=3),v())||(c=k.cursor),k.limit_backward=o,k.cursor=k.limit;var s,n,u,t=k.limit-k.cursor;if(k.ket=k.cursor,o=k.find_among_b(f,5))switch(k.bra=k.cursor,o){case 1:q()&&k.slice_from("heid");break;case 2:F();break;case 3:q()&&k.out_grouping_b(g,97,232)&&k.slice_del()}if(k.cursor=k.limit-t,j(),k.cursor=k.limit-t,k.ket=k.cursor,k.eq_s_b(4,"heid")&&(k.bra=k.cursor,z())&&(u=k.limit-k.cursor,k.eq_s_b(1,"c")||(k.cursor=k.limit-u,k.slice_del(),k.ket=k.cursor,k.eq_s_b(2,"en")&&(k.bra=k.cursor,F()))),k.cursor=k.limit-t,k.ket=k.cursor,o=k.find_among_b(_,6))switch(k.bra=k.cursor,o){case 1:if(z()){if(k.slice_del(),s=k.limit-k.cursor,k.ket=k.cursor,k.eq_s_b(2,"ig")&&(k.bra=k.cursor,z())&&(n=k.limit-k.cursor,!k.eq_s_b(1,"e"))){k.cursor=k.limit-n,k.slice_del();break}k.cursor=k.limit-s,W()}break;case 2:z()&&(n=k.limit-k.cursor,k.eq_s_b(1,"e")||(k.cursor=k.limit-n,k.slice_del()));break;case 3:z()&&(k.slice_del(),j());break;case 4:z()&&k.slice_del();break;case 5:z()&&l&&k.slice_del()}return k.cursor=k.limit-t,k.out_grouping_b(p,73,232)&&(u=k.limit-k.cursor,k.find_among_b(w,4))&&k.out_grouping_b(b,97,232)&&(k.cursor=k.limit-u,k.ket=k.cursor,k.cursor>k.limit_backward)&&(k.cursor--,k.bra=k.cursor,k.slice_del()),k.cursor=k.limit_backward,function(){for(var r;;)if(k.bra=k.cursor,r=k.find_among(d,3))switch(k.ket=k.cursor,r){case 1:k.slice_from("y");break;case 2:k.slice_from("i");break;case 3:if(k.cursor>=k.limit)return;k.cursor++}}(),!0}},function(r){return o.setCurrent(r),o.stem(),o.getCurrent()}),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=function(r){if(-1===e.du.stopWordFilter.stopWords.indexOf(r))return r},e.du.stopWordFilter.stopWords=new e.SortedSet,e.du.stopWordFilter.stopWords.length=103,e.du.stopWordFilter.stopWords.elements=" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" "),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/js/lunr.es.js b/js/lunr.es.js new file mode 100644 index 0000000..f8c382d --- /dev/null +++ b/js/lunr.es.js @@ -0,0 +1,595 @@ +/*! + * Lunr languages, `Spanish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.es = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.es.trimmer, + lunr.es.stopWordFilter, + lunr.es.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.es.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.es.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.es.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.es.trimmer, 'trimmer-es'); + + /* lunr stemmer function */ + lunr.es.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function SpanishStemmer() { + var a_0 = [new Among("", -1, 6), new Among("\u00E1", 0, 1), + new Among("\u00E9", 0, 2), new Among("\u00ED", 0, 3), + new Among("\u00F3", 0, 4), new Among("\u00FA", 0, 5) + ], + a_1 = [ + new Among("la", -1, -1), new Among("sela", 0, -1), + new Among("le", -1, -1), new Among("me", -1, -1), + new Among("se", -1, -1), new Among("lo", -1, -1), + new Among("selo", 5, -1), new Among("las", -1, -1), + new Among("selas", 7, -1), new Among("les", -1, -1), + new Among("los", -1, -1), new Among("selos", 10, -1), + new Among("nos", -1, -1) + ], + a_2 = [new Among("ando", -1, 6), + new Among("iendo", -1, 6), new Among("yendo", -1, 7), + new Among("\u00E1ndo", -1, 2), new Among("i\u00E9ndo", -1, 1), + new Among("ar", -1, 6), new Among("er", -1, 6), + new Among("ir", -1, 6), new Among("\u00E1r", -1, 3), + new Among("\u00E9r", -1, 4), new Among("\u00EDr", -1, 5) + ], + a_3 = [ + new Among("ic", -1, -1), new Among("ad", -1, -1), + new Among("os", -1, -1), new Among("iv", -1, 1) + ], + a_4 = [ + new Among("able", -1, 1), new Among("ible", -1, 1), + new Among("ante", -1, 1) + ], + a_5 = [new Among("ic", -1, 1), + new Among("abil", -1, 1), new Among("iv", -1, 1) + ], + a_6 = [ + new Among("ica", -1, 1), new Among("ancia", -1, 2), + new Among("encia", -1, 5), new Among("adora", -1, 2), + new Among("osa", -1, 1), new Among("ista", -1, 1), + new Among("iva", -1, 9), new Among("anza", -1, 1), + new Among("log\u00EDa", -1, 3), new Among("idad", -1, 8), + new Among("able", -1, 1), new Among("ible", -1, 1), + new Among("ante", -1, 2), new Among("mente", -1, 7), + new Among("amente", 13, 6), new Among("aci\u00F3n", -1, 2), + new Among("uci\u00F3n", -1, 4), new Among("ico", -1, 1), + new Among("ismo", -1, 1), new Among("oso", -1, 1), + new Among("amiento", -1, 1), new Among("imiento", -1, 1), + new Among("ivo", -1, 9), new Among("ador", -1, 2), + new Among("icas", -1, 1), new Among("ancias", -1, 2), + new Among("encias", -1, 5), new Among("adoras", -1, 2), + new Among("osas", -1, 1), new Among("istas", -1, 1), + new Among("ivas", -1, 9), new Among("anzas", -1, 1), + new Among("log\u00EDas", -1, 3), new Among("idades", -1, 8), + new Among("ables", -1, 1), new Among("ibles", -1, 1), + new Among("aciones", -1, 2), new Among("uciones", -1, 4), + new Among("adores", -1, 2), new Among("antes", -1, 2), + new Among("icos", -1, 1), new Among("ismos", -1, 1), + new Among("osos", -1, 1), new Among("amientos", -1, 1), + new Among("imientos", -1, 1), new Among("ivos", -1, 9) + ], + a_7 = [ + new Among("ya", -1, 1), new Among("ye", -1, 1), + new Among("yan", -1, 1), new Among("yen", -1, 1), + new Among("yeron", -1, 1), new Among("yendo", -1, 1), + new Among("yo", -1, 1), new Among("yas", -1, 1), + new Among("yes", -1, 1), new Among("yais", -1, 1), + new Among("yamos", -1, 1), new Among("y\u00F3", -1, 1) + ], + a_8 = [ + new Among("aba", -1, 2), new Among("ada", -1, 2), + new Among("ida", -1, 2), new Among("ara", -1, 2), + new Among("iera", -1, 2), new Among("\u00EDa", -1, 2), + new Among("ar\u00EDa", 5, 2), new Among("er\u00EDa", 5, 2), + new Among("ir\u00EDa", 5, 2), new Among("ad", -1, 2), + new Among("ed", -1, 2), new Among("id", -1, 2), + new Among("ase", -1, 2), new Among("iese", -1, 2), + new Among("aste", -1, 2), new Among("iste", -1, 2), + new Among("an", -1, 2), new Among("aban", 16, 2), + new Among("aran", 16, 2), new Among("ieran", 16, 2), + new Among("\u00EDan", 16, 2), new Among("ar\u00EDan", 20, 2), + new Among("er\u00EDan", 20, 2), new Among("ir\u00EDan", 20, 2), + new Among("en", -1, 1), new Among("asen", 24, 2), + new Among("iesen", 24, 2), new Among("aron", -1, 2), + new Among("ieron", -1, 2), new Among("ar\u00E1n", -1, 2), + new Among("er\u00E1n", -1, 2), new Among("ir\u00E1n", -1, 2), + new Among("ado", -1, 2), new Among("ido", -1, 2), + new Among("ando", -1, 2), new Among("iendo", -1, 2), + new Among("ar", -1, 2), new Among("er", -1, 2), + new Among("ir", -1, 2), new Among("as", -1, 2), + new Among("abas", 39, 2), new Among("adas", 39, 2), + new Among("idas", 39, 2), new Among("aras", 39, 2), + new Among("ieras", 39, 2), new Among("\u00EDas", 39, 2), + new Among("ar\u00EDas", 45, 2), new Among("er\u00EDas", 45, 2), + new Among("ir\u00EDas", 45, 2), new Among("es", -1, 1), + new Among("ases", 49, 2), new Among("ieses", 49, 2), + new Among("abais", -1, 2), new Among("arais", -1, 2), + new Among("ierais", -1, 2), new Among("\u00EDais", -1, 2), + new Among("ar\u00EDais", 55, 2), new Among("er\u00EDais", 55, 2), + new Among("ir\u00EDais", 55, 2), new Among("aseis", -1, 2), + new Among("ieseis", -1, 2), new Among("asteis", -1, 2), + new Among("isteis", -1, 2), new Among("\u00E1is", -1, 2), + new Among("\u00E9is", -1, 1), new Among("ar\u00E9is", 64, 2), + new Among("er\u00E9is", 64, 2), new Among("ir\u00E9is", 64, 2), + new Among("ados", -1, 2), new Among("idos", -1, 2), + new Among("amos", -1, 2), new Among("\u00E1bamos", 70, 2), + new Among("\u00E1ramos", 70, 2), new Among("i\u00E9ramos", 70, 2), + new Among("\u00EDamos", 70, 2), new Among("ar\u00EDamos", 74, 2), + new Among("er\u00EDamos", 74, 2), new Among("ir\u00EDamos", 74, 2), + new Among("emos", -1, 1), new Among("aremos", 78, 2), + new Among("eremos", 78, 2), new Among("iremos", 78, 2), + new Among("\u00E1semos", 78, 2), new Among("i\u00E9semos", 78, 2), + new Among("imos", -1, 2), new Among("ar\u00E1s", -1, 2), + new Among("er\u00E1s", -1, 2), new Among("ir\u00E1s", -1, 2), + new Among("\u00EDs", -1, 2), new Among("ar\u00E1", -1, 2), + new Among("er\u00E1", -1, 2), new Among("ir\u00E1", -1, 2), + new Among("ar\u00E9", -1, 2), new Among("er\u00E9", -1, 2), + new Among("ir\u00E9", -1, 2), new Among("i\u00F3", -1, 2) + ], + a_9 = [ + new Among("a", -1, 1), new Among("e", -1, 2), + new Among("o", -1, 1), new Among("os", -1, 1), + new Among("\u00E1", -1, 1), new Among("\u00E9", -1, 2), + new Among("\u00ED", -1, 1), new Among("\u00F3", -1, 1) + ], + g_v = [17, + 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 + ], + I_p2, I_p1, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function habr1() { + if (sbp.out_grouping(g_v, 97, 252)) { + while (!sbp.in_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + return true; + } + + function habr2() { + if (sbp.in_grouping(g_v, 97, 252)) { + var v_1 = sbp.cursor; + if (habr1()) { + sbp.cursor = v_1; + if (!sbp.in_grouping(g_v, 97, 252)) + return true; + while (!sbp.out_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + } + return false; + } + return true; + } + + function habr3() { + var v_1 = sbp.cursor, + v_2; + if (habr2()) { + sbp.cursor = v_1; + if (!sbp.out_grouping(g_v, 97, 252)) + return; + v_2 = sbp.cursor; + if (habr1()) { + sbp.cursor = v_2; + if (!sbp.in_grouping(g_v, 97, 252) || sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + } + I_pV = sbp.cursor; + } + + function habr4() { + while (!sbp.in_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function r_mark_regions() { + var v_1 = sbp.cursor; + I_pV = sbp.limit; + I_p1 = I_pV; + I_p2 = I_pV; + habr3(); + sbp.cursor = v_1; + if (habr4()) { + I_p1 = sbp.cursor; + if (habr4()) + I_p2 = sbp.cursor; + } + } + + function r_postlude() { + var among_var; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_0, 6); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("a"); + continue; + case 2: + sbp.slice_from("e"); + continue; + case 3: + sbp.slice_from("i"); + continue; + case 4: + sbp.slice_from("o"); + continue; + case 5: + sbp.slice_from("u"); + continue; + case 6: + if (sbp.cursor >= sbp.limit) + break; + sbp.cursor++; + continue; + } + } + break; + } + } + + function r_RV() { + return I_pV <= sbp.cursor; + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_attached_pronoun() { + var among_var; + sbp.ket = sbp.cursor; + if (sbp.find_among_b(a_1, 13)) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among_b(a_2, 11); + if (among_var && r_RV()) + switch (among_var) { + case 1: + sbp.bra = sbp.cursor; + sbp.slice_from("iendo"); + break; + case 2: + sbp.bra = sbp.cursor; + sbp.slice_from("ando"); + break; + case 3: + sbp.bra = sbp.cursor; + sbp.slice_from("ar"); + break; + case 4: + sbp.bra = sbp.cursor; + sbp.slice_from("er"); + break; + case 5: + sbp.bra = sbp.cursor; + sbp.slice_from("ir"); + break; + case 6: + sbp.slice_del(); + break; + case 7: + if (sbp.eq_s_b(1, "u")) + sbp.slice_del(); + break; + } + } + } + + function habr5(a, n) { + if (!r_R2()) + return true; + sbp.slice_del(); + sbp.ket = sbp.cursor; + var among_var = sbp.find_among_b(a, n); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1 && r_R2()) + sbp.slice_del(); + } + return false; + } + + function habr6(c1) { + if (!r_R2()) + return true; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, c1)) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + return false; + } + + function r_standard_suffix() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 46); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) + return false; + sbp.slice_del(); + break; + case 2: + if (habr6("ic")) + return false; + break; + case 3: + if (!r_R2()) + return false; + sbp.slice_from("log"); + break; + case 4: + if (!r_R2()) + return false; + sbp.slice_from("u"); + break; + case 5: + if (!r_R2()) + return false; + sbp.slice_from("ente"); + break; + case 6: + if (!r_R1()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 4); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2()) { + sbp.slice_del(); + if (among_var == 1) { + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + } + } + } + break; + case 7: + if (habr5(a_4, 3)) + return false; + break; + case 8: + if (habr5(a_5, 3)) + return false; + break; + case 9: + if (habr6("at")) + return false; + break; + } + return true; + } + return false; + } + + function r_y_verb_suffix() { + var among_var, v_1; + if (sbp.cursor >= I_pV) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 12); + sbp.limit_backward = v_1; + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) { + if (!sbp.eq_s_b(1, "u")) + return false; + sbp.slice_del(); + } + return true; + } + } + return false; + } + + function r_verb_suffix() { + var among_var, v_1, v_2, v_3; + if (sbp.cursor >= I_pV) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_8, 96); + sbp.limit_backward = v_1; + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + v_2 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(1, "u")) { + v_3 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(1, "g")) + sbp.cursor = sbp.limit - v_3; + else + sbp.cursor = sbp.limit - v_2; + } else + sbp.cursor = sbp.limit - v_2; + sbp.bra = sbp.cursor; + case 2: + sbp.slice_del(); + break; + } + } + } + } + + function r_residual_suffix() { + var among_var, v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_9, 8); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_RV()) + sbp.slice_del(); + break; + case 2: + if (r_RV()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "u")) { + sbp.bra = sbp.cursor; + v_1 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(1, "g")) { + sbp.cursor = sbp.limit - v_1; + if (r_RV()) + sbp.slice_del(); + } + } + } + break; + } + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_attached_pronoun(); + sbp.cursor = sbp.limit; + if (!r_standard_suffix()) { + sbp.cursor = sbp.limit; + if (!r_y_verb_suffix()) { + sbp.cursor = sbp.limit; + r_verb_suffix(); + } + } + sbp.cursor = sbp.limit; + r_residual_suffix(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.es.stemmer, 'stemmer-es'); + + /* stop word filter function */ + lunr.es.stopWordFilter = function(token) { + if (lunr.es.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.es.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.es.stopWordFilter.stopWords.length = 309; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.es.stopWordFilter.stopWords.elements = ' a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos'.split(' '); + + lunr.Pipeline.registerFunction(lunr.es.stopWordFilter, 'stopWordFilter-es'); + }; +})) \ No newline at end of file diff --git a/js/lunr.es.min.js b/js/lunr.es.min.js new file mode 100644 index 0000000..f8463d4 --- /dev/null +++ b/js/lunr.es.min.js @@ -0,0 +1 @@ +!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(s){if(void 0===s)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===s.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,W,r;s.es=function(){this.pipeline.reset(),this.pipeline.add(s.es.trimmer,s.es.stopWordFilter,s.es.stemmer)},s.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",s.es.trimmer=s.trimmerSupport.generateTrimmer(s.es.wordCharacters),s.Pipeline.registerFunction(s.es.trimmer,"trimmer-es"),s.es.stemmer=(e=s.stemmerSupport.Among,W=s.stemmerSupport.SnowballProgram,r=new function(){var u,w,c,m=[new e("",-1,6),new e("á",0,1),new e("é",0,2),new e("í",0,3),new e("ó",0,4),new e("ú",0,5)],l=[new e("la",-1,-1),new e("sela",0,-1),new e("le",-1,-1),new e("me",-1,-1),new e("se",-1,-1),new e("lo",-1,-1),new e("selo",5,-1),new e("las",-1,-1),new e("selas",7,-1),new e("les",-1,-1),new e("los",-1,-1),new e("selos",10,-1),new e("nos",-1,-1)],d=[new e("ando",-1,6),new e("iendo",-1,6),new e("yendo",-1,7),new e("ándo",-1,2),new e("iéndo",-1,1),new e("ar",-1,6),new e("er",-1,6),new e("ir",-1,6),new e("ár",-1,3),new e("ér",-1,4),new e("ír",-1,5)],s=[new e("ic",-1,-1),new e("ad",-1,-1),new e("os",-1,-1),new e("iv",-1,1)],r=[new e("able",-1,1),new e("ible",-1,1),new e("ante",-1,1)],n=[new e("ic",-1,1),new e("abil",-1,1),new e("iv",-1,1)],i=[new e("ica",-1,1),new e("ancia",-1,2),new e("encia",-1,5),new e("adora",-1,2),new e("osa",-1,1),new e("ista",-1,1),new e("iva",-1,9),new e("anza",-1,1),new e("logía",-1,3),new e("idad",-1,8),new e("able",-1,1),new e("ible",-1,1),new e("ante",-1,2),new e("mente",-1,7),new e("amente",13,6),new e("ación",-1,2),new e("ución",-1,4),new e("ico",-1,1),new e("ismo",-1,1),new e("oso",-1,1),new e("amiento",-1,1),new e("imiento",-1,1),new e("ivo",-1,9),new e("ador",-1,2),new e("icas",-1,1),new e("ancias",-1,2),new e("encias",-1,5),new e("adoras",-1,2),new e("osas",-1,1),new e("istas",-1,1),new e("ivas",-1,9),new e("anzas",-1,1),new e("logías",-1,3),new e("idades",-1,8),new e("ables",-1,1),new e("ibles",-1,1),new e("aciones",-1,2),new e("uciones",-1,4),new e("adores",-1,2),new e("antes",-1,2),new e("icos",-1,1),new e("ismos",-1,1),new e("osos",-1,1),new e("amientos",-1,1),new e("imientos",-1,1),new e("ivos",-1,9)],b=[new e("ya",-1,1),new e("ye",-1,1),new e("yan",-1,1),new e("yen",-1,1),new e("yeron",-1,1),new e("yendo",-1,1),new e("yo",-1,1),new e("yas",-1,1),new e("yes",-1,1),new e("yais",-1,1),new e("yamos",-1,1),new e("yó",-1,1)],f=[new e("aba",-1,2),new e("ada",-1,2),new e("ida",-1,2),new e("ara",-1,2),new e("iera",-1,2),new e("ía",-1,2),new e("aría",5,2),new e("ería",5,2),new e("iría",5,2),new e("ad",-1,2),new e("ed",-1,2),new e("id",-1,2),new e("ase",-1,2),new e("iese",-1,2),new e("aste",-1,2),new e("iste",-1,2),new e("an",-1,2),new e("aban",16,2),new e("aran",16,2),new e("ieran",16,2),new e("ían",16,2),new e("arían",20,2),new e("erían",20,2),new e("irían",20,2),new e("en",-1,1),new e("asen",24,2),new e("iesen",24,2),new e("aron",-1,2),new e("ieron",-1,2),new e("arán",-1,2),new e("erán",-1,2),new e("irán",-1,2),new e("ado",-1,2),new e("ido",-1,2),new e("ando",-1,2),new e("iendo",-1,2),new e("ar",-1,2),new e("er",-1,2),new e("ir",-1,2),new e("as",-1,2),new e("abas",39,2),new e("adas",39,2),new e("idas",39,2),new e("aras",39,2),new e("ieras",39,2),new e("ías",39,2),new e("arías",45,2),new e("erías",45,2),new e("irías",45,2),new e("es",-1,1),new e("ases",49,2),new e("ieses",49,2),new e("abais",-1,2),new e("arais",-1,2),new e("ierais",-1,2),new e("íais",-1,2),new e("aríais",55,2),new e("eríais",55,2),new e("iríais",55,2),new e("aseis",-1,2),new e("ieseis",-1,2),new e("asteis",-1,2),new e("isteis",-1,2),new e("áis",-1,2),new e("éis",-1,1),new e("aréis",64,2),new e("eréis",64,2),new e("iréis",64,2),new e("ados",-1,2),new e("idos",-1,2),new e("amos",-1,2),new e("ábamos",70,2),new e("áramos",70,2),new e("iéramos",70,2),new e("íamos",70,2),new e("aríamos",74,2),new e("eríamos",74,2),new e("iríamos",74,2),new e("emos",-1,1),new e("aremos",78,2),new e("eremos",78,2),new e("iremos",78,2),new e("ásemos",78,2),new e("iésemos",78,2),new e("imos",-1,2),new e("arás",-1,2),new e("erás",-1,2),new e("irás",-1,2),new e("ís",-1,2),new e("ará",-1,2),new e("erá",-1,2),new e("irá",-1,2),new e("aré",-1,2),new e("eré",-1,2),new e("iré",-1,2),new e("ió",-1,2)],_=[new e("a",-1,1),new e("e",-1,2),new e("o",-1,1),new e("os",-1,1),new e("á",-1,1),new e("é",-1,2),new e("í",-1,1),new e("ó",-1,1)],a=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],h=new W;function o(){if(!h.out_grouping(a,97,252))return 1;for(;!h.in_grouping(a,97,252);){if(h.cursor>=h.limit)return 1;h.cursor++}}function p(){var e=h.cursor;if(function(){if(!h.in_grouping(a,97,252))return 1;var e=h.cursor;if(o()){if(h.cursor=e,!h.in_grouping(a,97,252))return 1;for(;!h.out_grouping(a,97,252);){if(h.cursor>=h.limit)return 1;h.cursor++}}}()){if(h.cursor=e,!h.out_grouping(a,97,252))return;if(e=h.cursor,o()){if(h.cursor=e,!h.in_grouping(a,97,252)||h.cursor>=h.limit)return;h.cursor++}}c=h.cursor}function v(){for(;!h.in_grouping(a,97,252);){if(h.cursor>=h.limit)return;h.cursor++}for(;!h.out_grouping(a,97,252);){if(h.cursor>=h.limit)return;h.cursor++}return 1}function g(){return c<=h.cursor}function t(){return u<=h.cursor}function k(e,s){if(!t())return 1;h.slice_del(),h.ket=h.cursor;e=h.find_among_b(e,s);e&&(h.bra=h.cursor,1==e)&&t()&&h.slice_del()}function y(e){if(!t())return 1;h.slice_del(),h.ket=h.cursor,h.eq_s_b(2,e)&&(h.bra=h.cursor,t())&&h.slice_del()}function q(){var e;if(h.ket=h.cursor,e=h.find_among_b(i,46)){switch(h.bra=h.cursor,e){case 1:if(!t())return;h.slice_del();break;case 2:if(y("ic"))return;break;case 3:if(!t())return;h.slice_from("log");break;case 4:if(!t())return;h.slice_from("u");break;case 5:if(!t())return;h.slice_from("ente");break;case 6:if(!(w<=h.cursor))return;h.slice_del(),h.ket=h.cursor,(e=h.find_among_b(s,4))&&(h.bra=h.cursor,t())&&(h.slice_del(),1==e)&&(h.ket=h.cursor,h.eq_s_b(2,"at"))&&(h.bra=h.cursor,t())&&h.slice_del();break;case 7:if(k(r,3))return;break;case 8:if(k(n,3))return;break;case 9:if(y("at"))return}return 1}}this.setCurrent=function(e){h.setCurrent(e)},this.getCurrent=function(){return h.getCurrent()},this.stem=function(){var e,s,r,n,i,a,o,t=h.cursor;if(r=h.cursor,c=h.limit,u=w=c,p(),h.cursor=r,v()&&(w=h.cursor,v())&&(u=h.cursor),h.limit_backward=t,h.cursor=h.limit,h.ket=h.cursor,h.find_among_b(l,13)&&(h.bra=h.cursor,e=h.find_among_b(d,11))&&g())switch(e){case 1:h.bra=h.cursor,h.slice_from("iendo");break;case 2:h.bra=h.cursor,h.slice_from("ando");break;case 3:h.bra=h.cursor,h.slice_from("ar");break;case 4:h.bra=h.cursor,h.slice_from("er");break;case 5:h.bra=h.cursor,h.slice_from("ir");break;case 6:h.slice_del();break;case 7:h.eq_s_b(1,"u")&&h.slice_del()}if((h.cursor=h.limit,!q())&&(h.cursor=h.limit,!function(){var e,s;if(h.cursor>=c&&(s=h.limit_backward,h.limit_backward=c,h.ket=h.cursor,e=h.find_among_b(b,12),h.limit_backward=s,e)){if(h.bra=h.cursor,1==e){if(!h.eq_s_b(1,"u"))return;h.slice_del()}return 1}}()&&(h.cursor=h.limit,h.cursor>=c)&&(r=h.limit_backward,h.limit_backward=c,h.ket=h.cursor,s=h.find_among_b(f,96),h.limit_backward=r,s)))switch(h.bra=h.cursor,s){case 1:n=h.limit-h.cursor,h.eq_s_b(1,"u")&&(i=h.limit-h.cursor,h.eq_s_b(1,"g"))?h.cursor=h.limit-i:h.cursor=h.limit-n,h.bra=h.cursor;case 2:h.slice_del()}if(h.cursor=h.limit,h.ket=h.cursor,t=h.find_among_b(_,8))switch(h.bra=h.cursor,t){case 1:g()&&h.slice_del();break;case 2:g()&&(h.slice_del(),h.ket=h.cursor,h.eq_s_b(1,"u"))&&(h.bra=h.cursor,a=h.limit-h.cursor,h.eq_s_b(1,"g"))&&(h.cursor=h.limit-a,g())&&h.slice_del()}for(h.cursor=h.limit_backward;;){if(h.bra=h.cursor,o=h.find_among(m,6))switch(h.ket=h.cursor,o){case 1:h.slice_from("a");continue;case 2:h.slice_from("e");continue;case 3:h.slice_from("i");continue;case 4:h.slice_from("o");continue;case 5:h.slice_from("u");continue;case 6:if(!(h.cursor>=h.limit)){h.cursor++;continue}}break}return!0}},function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}),s.Pipeline.registerFunction(s.es.stemmer,"stemmer-es"),s.es.stopWordFilter=function(e){if(-1===s.es.stopWordFilter.stopWords.indexOf(e))return e},s.es.stopWordFilter.stopWords=new s.SortedSet,s.es.stopWordFilter.stopWords.length=309,s.es.stopWordFilter.stopWords.elements=" a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" "),s.Pipeline.registerFunction(s.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/js/lunr.fi.js b/js/lunr.fi.js new file mode 100644 index 0000000..c49d7de --- /dev/null +++ b/js/lunr.fi.js @@ -0,0 +1,536 @@ +/*! + * Lunr languages, `Finnish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.fi = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.fi.trimmer, + lunr.fi.stopWordFilter, + lunr.fi.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.fi.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.fi.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.fi.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.fi.trimmer, 'trimmer-fi'); + + /* lunr stemmer function */ + lunr.fi.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function FinnishStemmer() { + var a_0 = [new Among("pa", -1, 1), new Among("sti", -1, 2), + new Among("kaan", -1, 1), new Among("han", -1, 1), + new Among("kin", -1, 1), new Among("h\u00E4n", -1, 1), + new Among("k\u00E4\u00E4n", -1, 1), new Among("ko", -1, 1), + new Among("p\u00E4", -1, 1), new Among("k\u00F6", -1, 1) + ], + a_1 = [ + new Among("lla", -1, -1), new Among("na", -1, -1), + new Among("ssa", -1, -1), new Among("ta", -1, -1), + new Among("lta", 3, -1), new Among("sta", 3, -1) + ], + a_2 = [ + new Among("ll\u00E4", -1, -1), new Among("n\u00E4", -1, -1), + new Among("ss\u00E4", -1, -1), new Among("t\u00E4", -1, -1), + new Among("lt\u00E4", 3, -1), new Among("st\u00E4", 3, -1) + ], + a_3 = [ + new Among("lle", -1, -1), new Among("ine", -1, -1) + ], + a_4 = [ + new Among("nsa", -1, 3), new Among("mme", -1, 3), + new Among("nne", -1, 3), new Among("ni", -1, 2), + new Among("si", -1, 1), new Among("an", -1, 4), + new Among("en", -1, 6), new Among("\u00E4n", -1, 5), + new Among("ns\u00E4", -1, 3) + ], + a_5 = [new Among("aa", -1, -1), + new Among("ee", -1, -1), new Among("ii", -1, -1), + new Among("oo", -1, -1), new Among("uu", -1, -1), + new Among("\u00E4\u00E4", -1, -1), + new Among("\u00F6\u00F6", -1, -1) + ], + a_6 = [new Among("a", -1, 8), + new Among("lla", 0, -1), new Among("na", 0, -1), + new Among("ssa", 0, -1), new Among("ta", 0, -1), + new Among("lta", 4, -1), new Among("sta", 4, -1), + new Among("tta", 4, 9), new Among("lle", -1, -1), + new Among("ine", -1, -1), new Among("ksi", -1, -1), + new Among("n", -1, 7), new Among("han", 11, 1), + new Among("den", 11, -1, r_VI), new Among("seen", 11, -1, r_LONG), + new Among("hen", 11, 2), new Among("tten", 11, -1, r_VI), + new Among("hin", 11, 3), new Among("siin", 11, -1, r_VI), + new Among("hon", 11, 4), new Among("h\u00E4n", 11, 5), + new Among("h\u00F6n", 11, 6), new Among("\u00E4", -1, 8), + new Among("ll\u00E4", 22, -1), new Among("n\u00E4", 22, -1), + new Among("ss\u00E4", 22, -1), new Among("t\u00E4", 22, -1), + new Among("lt\u00E4", 26, -1), new Among("st\u00E4", 26, -1), + new Among("tt\u00E4", 26, 9) + ], + a_7 = [new Among("eja", -1, -1), + new Among("mma", -1, 1), new Among("imma", 1, -1), + new Among("mpa", -1, 1), new Among("impa", 3, -1), + new Among("mmi", -1, 1), new Among("immi", 5, -1), + new Among("mpi", -1, 1), new Among("impi", 7, -1), + new Among("ej\u00E4", -1, -1), new Among("mm\u00E4", -1, 1), + new Among("imm\u00E4", 10, -1), new Among("mp\u00E4", -1, 1), + new Among("imp\u00E4", 12, -1) + ], + a_8 = [new Among("i", -1, -1), + new Among("j", -1, -1) + ], + a_9 = [new Among("mma", -1, 1), + new Among("imma", 0, -1) + ], + g_AEI = [17, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8 + ], + g_V1 = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 32 + ], + g_V2 = [17, 65, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8, 0, 32 + ], + g_particle_end = [17, 97, 24, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 + ], + B_ending_removed, S_x, I_p2, I_p1, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function r_mark_regions() { + I_p1 = sbp.limit; + I_p2 = I_p1; + if (!habr1()) { + I_p1 = sbp.cursor; + if (!habr1()) + I_p2 = sbp.cursor; + } + } + + function habr1() { + var v_1; + while (true) { + v_1 = sbp.cursor; + if (sbp.in_grouping(g_V1, 97, 246)) + break; + sbp.cursor = v_1; + if (v_1 >= sbp.limit) + return true; + sbp.cursor++; + } + sbp.cursor = v_1; + while (!sbp.out_grouping(g_V1, 97, 246)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_particle_etc() { + var among_var, v_1; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_0, 10); + if (among_var) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_1; + switch (among_var) { + case 1: + if (!sbp.in_grouping_b(g_particle_end, 97, 246)) + return; + break; + case 2: + if (!r_R2()) + return; + break; + } + sbp.slice_del(); + } else + sbp.limit_backward = v_1; + } + } + + function r_possessive() { + var among_var, v_1, v_2; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 9); + if (among_var) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_1; + switch (among_var) { + case 1: + v_2 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "k")) { + sbp.cursor = sbp.limit - v_2; + sbp.slice_del(); + } + break; + case 2: + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(3, "kse")) { + sbp.bra = sbp.cursor; + sbp.slice_from("ksi"); + } + break; + case 3: + sbp.slice_del(); + break; + case 4: + if (sbp.find_among_b(a_1, 6)) + sbp.slice_del(); + break; + case 5: + if (sbp.find_among_b(a_2, 6)) + sbp.slice_del(); + break; + case 6: + if (sbp.find_among_b(a_3, 2)) + sbp.slice_del(); + break; + } + } else + sbp.limit_backward = v_1; + } + } + + function r_LONG() { + return sbp.find_among_b(a_5, 7); + } + + function r_VI() { + return sbp.eq_s_b(1, "i") && sbp.in_grouping_b(g_V2, 97, 246); + } + + function r_case_ending() { + var among_var, v_1, v_2; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 30); + if (among_var) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_1; + switch (among_var) { + case 1: + if (!sbp.eq_s_b(1, "a")) + return; + break; + case 2: + case 9: + if (!sbp.eq_s_b(1, "e")) + return; + break; + case 3: + if (!sbp.eq_s_b(1, "i")) + return; + break; + case 4: + if (!sbp.eq_s_b(1, "o")) + return; + break; + case 5: + if (!sbp.eq_s_b(1, "\u00E4")) + return; + break; + case 6: + if (!sbp.eq_s_b(1, "\u00F6")) + return; + break; + case 7: + v_2 = sbp.limit - sbp.cursor; + if (!r_LONG()) { + sbp.cursor = sbp.limit - v_2; + if (!sbp.eq_s_b(2, "ie")) { + sbp.cursor = sbp.limit - v_2; + break; + } + } + sbp.cursor = sbp.limit - v_2; + if (sbp.cursor <= sbp.limit_backward) { + sbp.cursor = sbp.limit - v_2; + break; + } + sbp.cursor--; + sbp.bra = sbp.cursor; + break; + case 8: + if (!sbp.in_grouping_b(g_V1, 97, 246) || !sbp.out_grouping_b(g_V1, 97, 246)) + return; + break; + } + sbp.slice_del(); + B_ending_removed = true; + } else + sbp.limit_backward = v_1; + } + } + + function r_other_endings() { + var among_var, v_1, v_2; + if (sbp.cursor >= I_p2) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p2; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 14); + if (among_var) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_1; + if (among_var == 1) { + v_2 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(2, "po")) + return; + sbp.cursor = sbp.limit - v_2; + } + sbp.slice_del(); + } else + sbp.limit_backward = v_1; + } + } + + function r_i_plural() { + var v_1; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + if (sbp.find_among_b(a_8, 2)) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_1; + sbp.slice_del(); + } else + sbp.limit_backward = v_1; + } + } + + function r_t_plural() { + var among_var, v_1, v_2, v_3, v_4, v_5; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "t")) { + sbp.bra = sbp.cursor; + v_2 = sbp.limit - sbp.cursor; + if (sbp.in_grouping_b(g_V1, 97, 246)) { + sbp.cursor = sbp.limit - v_2; + sbp.slice_del(); + sbp.limit_backward = v_1; + v_3 = sbp.limit - sbp.cursor; + if (sbp.cursor >= I_p2) { + sbp.cursor = I_p2; + v_4 = sbp.limit_backward; + sbp.limit_backward = sbp.cursor; + sbp.cursor = sbp.limit - v_3; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_9, 2); + if (among_var) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_4; + if (among_var == 1) { + v_5 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(2, "po")) + return; + sbp.cursor = sbp.limit - v_5; + } + sbp.slice_del(); + return; + } + } + } + } + sbp.limit_backward = v_1; + } + } + + function r_tidy() { + var v_1, v_2, v_3, v_4; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + v_2 = sbp.limit - sbp.cursor; + if (r_LONG()) { + sbp.cursor = sbp.limit - v_2; + sbp.ket = sbp.cursor; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + } + sbp.cursor = sbp.limit - v_2; + sbp.ket = sbp.cursor; + if (sbp.in_grouping_b(g_AEI, 97, 228)) { + sbp.bra = sbp.cursor; + if (sbp.out_grouping_b(g_V1, 97, 246)) + sbp.slice_del(); + } + sbp.cursor = sbp.limit - v_2; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "j")) { + sbp.bra = sbp.cursor; + v_3 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "o")) { + sbp.cursor = sbp.limit - v_3; + if (sbp.eq_s_b(1, "u")) + sbp.slice_del(); + } else + sbp.slice_del(); + } + sbp.cursor = sbp.limit - v_2; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "o")) { + sbp.bra = sbp.cursor; + if (sbp.eq_s_b(1, "j")) + sbp.slice_del(); + } + sbp.cursor = sbp.limit - v_2; + sbp.limit_backward = v_1; + while (true) { + v_4 = sbp.limit - sbp.cursor; + if (sbp.out_grouping_b(g_V1, 97, 246)) { + sbp.cursor = sbp.limit - v_4; + break; + } + sbp.cursor = sbp.limit - v_4; + if (sbp.cursor <= sbp.limit_backward) + return; + sbp.cursor--; + } + sbp.ket = sbp.cursor; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + S_x = sbp.slice_to(); + if (sbp.eq_v_b(S_x)) + sbp.slice_del(); + } + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_mark_regions(); + B_ending_removed = false; + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_particle_etc(); + sbp.cursor = sbp.limit; + r_possessive(); + sbp.cursor = sbp.limit; + r_case_ending(); + sbp.cursor = sbp.limit; + r_other_endings(); + sbp.cursor = sbp.limit; + if (B_ending_removed) { + r_i_plural(); + sbp.cursor = sbp.limit; + } else { + sbp.cursor = sbp.limit; + r_t_plural(); + sbp.cursor = sbp.limit; + } + r_tidy(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.fi.stemmer, 'stemmer-fi'); + + /* stop word filter function */ + lunr.fi.stopWordFilter = function(token) { + if (lunr.fi.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.fi.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.fi.stopWordFilter.stopWords.length = 236; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.fi.stopWordFilter.stopWords.elements = ' ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli'.split(' '); + + lunr.Pipeline.registerFunction(lunr.fi.stopWordFilter, 'stopWordFilter-fi'); + }; +})) \ No newline at end of file diff --git a/js/lunr.fi.min.js b/js/lunr.fi.min.js new file mode 100644 index 0000000..4d8f82e --- /dev/null +++ b/js/lunr.fi.min.js @@ -0,0 +1 @@ +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var v,W,r;e.fi=function(){this.pipeline.reset(),this.pipeline.add(e.fi.trimmer,e.fi.stopWordFilter,e.fi.stemmer)},e.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fi.trimmer=e.trimmerSupport.generateTrimmer(e.fi.wordCharacters),e.Pipeline.registerFunction(e.fi.trimmer,"trimmer-fi"),e.fi.stemmer=(v=e.stemmerSupport.Among,W=e.stemmerSupport.SnowballProgram,r=new function(){var n,t,s,o,r=[new v("pa",-1,1),new v("sti",-1,2),new v("kaan",-1,1),new v("han",-1,1),new v("kin",-1,1),new v("hän",-1,1),new v("kään",-1,1),new v("ko",-1,1),new v("pä",-1,1),new v("kö",-1,1)],l=[new v("lla",-1,-1),new v("na",-1,-1),new v("ssa",-1,-1),new v("ta",-1,-1),new v("lta",3,-1),new v("sta",3,-1)],a=[new v("llä",-1,-1),new v("nä",-1,-1),new v("ssä",-1,-1),new v("tä",-1,-1),new v("ltä",3,-1),new v("stä",3,-1)],u=[new v("lle",-1,-1),new v("ine",-1,-1)],c=[new v("nsa",-1,3),new v("mme",-1,3),new v("nne",-1,3),new v("ni",-1,2),new v("si",-1,1),new v("an",-1,4),new v("en",-1,6),new v("än",-1,5),new v("nsä",-1,3)],i=[new v("aa",-1,-1),new v("ee",-1,-1),new v("ii",-1,-1),new v("oo",-1,-1),new v("uu",-1,-1),new v("ää",-1,-1),new v("öö",-1,-1)],m=[new v("a",-1,8),new v("lla",0,-1),new v("na",0,-1),new v("ssa",0,-1),new v("ta",0,-1),new v("lta",4,-1),new v("sta",4,-1),new v("tta",4,9),new v("lle",-1,-1),new v("ine",-1,-1),new v("ksi",-1,-1),new v("n",-1,7),new v("han",11,1),new v("den",11,-1,q),new v("seen",11,-1,j),new v("hen",11,2),new v("tten",11,-1,q),new v("hin",11,3),new v("siin",11,-1,q),new v("hon",11,4),new v("hän",11,5),new v("hön",11,6),new v("ä",-1,8),new v("llä",22,-1),new v("nä",22,-1),new v("ssä",22,-1),new v("tä",22,-1),new v("ltä",26,-1),new v("stä",26,-1),new v("ttä",26,9)],w=[new v("eja",-1,-1),new v("mma",-1,1),new v("imma",1,-1),new v("mpa",-1,1),new v("impa",3,-1),new v("mmi",-1,1),new v("immi",5,-1),new v("mpi",-1,1),new v("impi",7,-1),new v("ejä",-1,-1),new v("mmä",-1,1),new v("immä",10,-1),new v("mpä",-1,1),new v("impä",12,-1)],_=[new v("i",-1,-1),new v("j",-1,-1)],k=[new v("mma",-1,1),new v("imma",0,-1)],b=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],e=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],f=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],p=new W;function h(){for(var i;i=p.cursor,!p.in_grouping(d,97,246);){if((p.cursor=i)>=p.limit)return 1;p.cursor++}for(p.cursor=i;!p.out_grouping(d,97,246);){if(p.cursor>=p.limit)return 1;p.cursor++}}function g(){var i,e;if(p.cursor>=o)if(e=p.limit_backward,p.limit_backward=o,p.ket=p.cursor,i=p.find_among_b(r,10)){switch(p.bra=p.cursor,p.limit_backward=e,i){case 1:if(p.in_grouping_b(f,97,246))break;return;case 2:if(s<=p.cursor)break;return}p.slice_del()}else p.limit_backward=e}function j(){return p.find_among_b(i,7)}function q(){return p.eq_s_b(1,"i")&&p.in_grouping_b(e,97,246)}this.setCurrent=function(i){p.setCurrent(i)},this.getCurrent=function(){return p.getCurrent()},this.stem=function(){var i,e,r=p.cursor;if(o=p.limit,s=o,h()||(o=p.cursor,h())||(s=p.cursor),n=!1,p.limit_backward=r,p.cursor=p.limit,g(),p.cursor=p.limit,p.cursor>=o)if(r=p.limit_backward,p.limit_backward=o,p.ket=p.cursor,e=p.find_among_b(c,9))switch(p.bra=p.cursor,p.limit_backward=r,e){case 1:i=p.limit-p.cursor,p.eq_s_b(1,"k")||(p.cursor=p.limit-i,p.slice_del());break;case 2:p.slice_del(),p.ket=p.cursor,p.eq_s_b(3,"kse")&&(p.bra=p.cursor,p.slice_from("ksi"));break;case 3:p.slice_del();break;case 4:p.find_among_b(l,6)&&p.slice_del();break;case 5:p.find_among_b(a,6)&&p.slice_del();break;case 6:p.find_among_b(u,2)&&p.slice_del()}else p.limit_backward=r;return p.cursor=p.limit,function(){var i,e,r;if(p.cursor>=o)if(e=p.limit_backward,p.limit_backward=o,p.ket=p.cursor,i=p.find_among_b(m,30)){switch(p.bra=p.cursor,p.limit_backward=e,i){case 1:if(p.eq_s_b(1,"a"))break;return;case 2:case 9:if(p.eq_s_b(1,"e"))break;return;case 3:if(p.eq_s_b(1,"i"))break;return;case 4:if(p.eq_s_b(1,"o"))break;return;case 5:if(p.eq_s_b(1,"ä"))break;return;case 6:if(p.eq_s_b(1,"ö"))break;return;case 7:r=p.limit-p.cursor,j()||(p.cursor=p.limit-r,p.eq_s_b(2,"ie"))?(p.cursor=p.limit-r,p.cursor<=p.limit_backward?p.cursor=p.limit-r:(p.cursor--,p.bra=p.cursor)):p.cursor=p.limit-r;break;case 8:if(p.in_grouping_b(d,97,246)&&p.out_grouping_b(d,97,246))break;return}p.slice_del(),n=!0}else p.limit_backward=e}(),p.cursor=p.limit,function(){var i,e;if(p.cursor>=s)if(i=p.limit_backward,p.limit_backward=s,p.ket=p.cursor,e=p.find_among_b(w,14)){if(p.bra=p.cursor,p.limit_backward=i,1==e){if(e=p.limit-p.cursor,p.eq_s_b(2,"po"))return;p.cursor=p.limit-e}p.slice_del()}else p.limit_backward=i}(),p.cursor=p.limit,n?p.cursor>=o&&(e=p.limit_backward,p.limit_backward=o,p.ket=p.cursor,p.find_among_b(_,2)?(p.bra=p.cursor,p.limit_backward=e,p.slice_del()):p.limit_backward=e):(p.cursor=p.limit,function(){var i,e,r,n;if(p.cursor>=o)if(e=p.limit_backward,p.limit_backward=o,p.ket=p.cursor,p.eq_s_b(1,"t")&&(p.bra=p.cursor,n=p.limit-p.cursor,p.in_grouping_b(d,97,246))&&(p.cursor=p.limit-n,p.slice_del(),p.limit_backward=e,n=p.limit-p.cursor,p.cursor>=s)&&(p.cursor=s,r=p.limit_backward,p.limit_backward=p.cursor,p.cursor=p.limit-n,p.ket=p.cursor,i=p.find_among_b(k,2))){if(p.bra=p.cursor,p.limit_backward=r,1==i){if(n=p.limit-p.cursor,p.eq_s_b(2,"po"))return;p.cursor=p.limit-n}p.slice_del()}else p.limit_backward=e}()),p.cursor=p.limit,function(){var i,e,r,n;if(p.cursor>=o){for(i=p.limit_backward,p.limit_backward=o,e=p.limit-p.cursor,j()&&(p.cursor=p.limit-e,p.ket=p.cursor,p.cursor>p.limit_backward)&&(p.cursor--,p.bra=p.cursor,p.slice_del()),p.cursor=p.limit-e,p.ket=p.cursor,p.in_grouping_b(b,97,228)&&(p.bra=p.cursor,p.out_grouping_b(d,97,246))&&p.slice_del(),p.cursor=p.limit-e,p.ket=p.cursor,p.eq_s_b(1,"j")&&(p.bra=p.cursor,r=p.limit-p.cursor,p.eq_s_b(1,"o")||(p.cursor=p.limit-r,p.eq_s_b(1,"u")))&&p.slice_del(),p.cursor=p.limit-e,p.ket=p.cursor,p.eq_s_b(1,"o")&&(p.bra=p.cursor,p.eq_s_b(1,"j"))&&p.slice_del(),p.cursor=p.limit-e,p.limit_backward=i;;){if(n=p.limit-p.cursor,p.out_grouping_b(d,97,246)){p.cursor=p.limit-n;break}if(p.cursor=p.limit-n,p.cursor<=p.limit_backward)return;p.cursor--}p.ket=p.cursor,p.cursor>p.limit_backward&&(p.cursor--,p.bra=p.cursor,t=p.slice_to(),p.eq_v_b(t))&&p.slice_del()}}(),!0}},function(i){return r.setCurrent(i),r.stem(),r.getCurrent()}),e.Pipeline.registerFunction(e.fi.stemmer,"stemmer-fi"),e.fi.stopWordFilter=function(i){if(-1===e.fi.stopWordFilter.stopWords.indexOf(i))return i},e.fi.stopWordFilter.stopWords=new e.SortedSet,e.fi.stopWordFilter.stopWords.length=236,e.fi.stopWordFilter.stopWords.elements=" ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" "),e.Pipeline.registerFunction(e.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/js/lunr.fr.js b/js/lunr.fr.js new file mode 100644 index 0000000..07978b2 --- /dev/null +++ b/js/lunr.fr.js @@ -0,0 +1,698 @@ +/*! + * Lunr languages, `French` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.fr = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.fr.trimmer, + lunr.fr.stopWordFilter, + lunr.fr.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.fr.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.fr.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.fr.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.fr.trimmer, 'trimmer-fr'); + + /* lunr stemmer function */ + lunr.fr.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function FrenchStemmer() { + var a_0 = [new Among("col", -1, -1), new Among("par", -1, -1), + new Among("tap", -1, -1) + ], + a_1 = [new Among("", -1, 4), + new Among("I", 0, 1), new Among("U", 0, 2), new Among("Y", 0, 3) + ], + a_2 = [ + new Among("iqU", -1, 3), new Among("abl", -1, 3), + new Among("I\u00E8r", -1, 4), new Among("i\u00E8r", -1, 4), + new Among("eus", -1, 2), new Among("iv", -1, 1) + ], + a_3 = [ + new Among("ic", -1, 2), new Among("abil", -1, 1), + new Among("iv", -1, 3) + ], + a_4 = [new Among("iqUe", -1, 1), + new Among("atrice", -1, 2), new Among("ance", -1, 1), + new Among("ence", -1, 5), new Among("logie", -1, 3), + new Among("able", -1, 1), new Among("isme", -1, 1), + new Among("euse", -1, 11), new Among("iste", -1, 1), + new Among("ive", -1, 8), new Among("if", -1, 8), + new Among("usion", -1, 4), new Among("ation", -1, 2), + new Among("ution", -1, 4), new Among("ateur", -1, 2), + new Among("iqUes", -1, 1), new Among("atrices", -1, 2), + new Among("ances", -1, 1), new Among("ences", -1, 5), + new Among("logies", -1, 3), new Among("ables", -1, 1), + new Among("ismes", -1, 1), new Among("euses", -1, 11), + new Among("istes", -1, 1), new Among("ives", -1, 8), + new Among("ifs", -1, 8), new Among("usions", -1, 4), + new Among("ations", -1, 2), new Among("utions", -1, 4), + new Among("ateurs", -1, 2), new Among("ments", -1, 15), + new Among("ements", 30, 6), new Among("issements", 31, 12), + new Among("it\u00E9s", -1, 7), new Among("ment", -1, 15), + new Among("ement", 34, 6), new Among("issement", 35, 12), + new Among("amment", 34, 13), new Among("emment", 34, 14), + new Among("aux", -1, 10), new Among("eaux", 39, 9), + new Among("eux", -1, 1), new Among("it\u00E9", -1, 7) + ], + a_5 = [ + new Among("ira", -1, 1), new Among("ie", -1, 1), + new Among("isse", -1, 1), new Among("issante", -1, 1), + new Among("i", -1, 1), new Among("irai", 4, 1), + new Among("ir", -1, 1), new Among("iras", -1, 1), + new Among("ies", -1, 1), new Among("\u00EEmes", -1, 1), + new Among("isses", -1, 1), new Among("issantes", -1, 1), + new Among("\u00EEtes", -1, 1), new Among("is", -1, 1), + new Among("irais", 13, 1), new Among("issais", 13, 1), + new Among("irions", -1, 1), new Among("issions", -1, 1), + new Among("irons", -1, 1), new Among("issons", -1, 1), + new Among("issants", -1, 1), new Among("it", -1, 1), + new Among("irait", 21, 1), new Among("issait", 21, 1), + new Among("issant", -1, 1), new Among("iraIent", -1, 1), + new Among("issaIent", -1, 1), new Among("irent", -1, 1), + new Among("issent", -1, 1), new Among("iront", -1, 1), + new Among("\u00EEt", -1, 1), new Among("iriez", -1, 1), + new Among("issiez", -1, 1), new Among("irez", -1, 1), + new Among("issez", -1, 1) + ], + a_6 = [new Among("a", -1, 3), + new Among("era", 0, 2), new Among("asse", -1, 3), + new Among("ante", -1, 3), new Among("\u00E9e", -1, 2), + new Among("ai", -1, 3), new Among("erai", 5, 2), + new Among("er", -1, 2), new Among("as", -1, 3), + new Among("eras", 8, 2), new Among("\u00E2mes", -1, 3), + new Among("asses", -1, 3), new Among("antes", -1, 3), + new Among("\u00E2tes", -1, 3), new Among("\u00E9es", -1, 2), + new Among("ais", -1, 3), new Among("erais", 15, 2), + new Among("ions", -1, 1), new Among("erions", 17, 2), + new Among("assions", 17, 3), new Among("erons", -1, 2), + new Among("ants", -1, 3), new Among("\u00E9s", -1, 2), + new Among("ait", -1, 3), new Among("erait", 23, 2), + new Among("ant", -1, 3), new Among("aIent", -1, 3), + new Among("eraIent", 26, 2), new Among("\u00E8rent", -1, 2), + new Among("assent", -1, 3), new Among("eront", -1, 2), + new Among("\u00E2t", -1, 3), new Among("ez", -1, 2), + new Among("iez", 32, 2), new Among("eriez", 33, 2), + new Among("assiez", 33, 3), new Among("erez", 32, 2), + new Among("\u00E9", -1, 2) + ], + a_7 = [new Among("e", -1, 3), + new Among("I\u00E8re", 0, 2), new Among("i\u00E8re", 0, 2), + new Among("ion", -1, 1), new Among("Ier", -1, 2), + new Among("ier", -1, 2), new Among("\u00EB", -1, 4) + ], + a_8 = [ + new Among("ell", -1, -1), new Among("eill", -1, -1), + new Among("enn", -1, -1), new Among("onn", -1, -1), + new Among("ett", -1, -1) + ], + g_v = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 + ], + g_keep_with_s = [1, 65, 20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 + ], + I_p2, I_p1, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function habr1(c1, c2, v_1) { + if (sbp.eq_s(1, c1)) { + sbp.ket = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 251)) { + sbp.slice_from(c2); + sbp.cursor = v_1; + return true; + } + } + return false; + } + + function habr2(c1, c2, v_1) { + if (sbp.eq_s(1, c1)) { + sbp.ket = sbp.cursor; + sbp.slice_from(c2); + sbp.cursor = v_1; + return true; + } + return false; + } + + function r_prelude() { + var v_1, v_2; + while (true) { + v_1 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 251)) { + sbp.bra = sbp.cursor; + v_2 = sbp.cursor; + if (habr1("u", "U", v_1)) + continue; + sbp.cursor = v_2; + if (habr1("i", "I", v_1)) + continue; + sbp.cursor = v_2; + if (habr2("y", "Y", v_1)) + continue; + } + sbp.cursor = v_1; + sbp.bra = v_1; + if (!habr1("y", "Y", v_1)) { + sbp.cursor = v_1; + if (sbp.eq_s(1, "q")) { + sbp.bra = sbp.cursor; + if (habr2("u", "U", v_1)) + continue; + } + sbp.cursor = v_1; + if (v_1 >= sbp.limit) + return; + sbp.cursor++; + } + } + } + + function habr3() { + while (!sbp.in_grouping(g_v, 97, 251)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 251)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + + function r_mark_regions() { + var v_1 = sbp.cursor; + I_pV = sbp.limit; + I_p1 = I_pV; + I_p2 = I_pV; + if (sbp.in_grouping(g_v, 97, 251) && sbp.in_grouping(g_v, 97, 251) && sbp.cursor < sbp.limit) + sbp.cursor++; + else { + sbp.cursor = v_1; + if (!sbp.find_among(a_0, 3)) { + sbp.cursor = v_1; + do { + if (sbp.cursor >= sbp.limit) { + sbp.cursor = I_pV; + break; + } + sbp.cursor++; + } while (!sbp.in_grouping(g_v, 97, 251)); + } + } + I_pV = sbp.cursor; + sbp.cursor = v_1; + if (!habr3()) { + I_p1 = sbp.cursor; + if (!habr3()) + I_p2 = sbp.cursor; + } + } + + function r_postlude() { + var among_var, v_1; + while (true) { + v_1 = sbp.cursor; + sbp.bra = v_1; + among_var = sbp.find_among(a_1, 4); + if (!among_var) + break; + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("i"); + break; + case 2: + sbp.slice_from("u"); + break; + case 3: + sbp.slice_from("y"); + break; + case 4: + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + break; + } + } + } + + function r_RV() { + return I_pV <= sbp.cursor; + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_standard_suffix() { + var among_var, v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 43); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) + return false; + sbp.slice_del(); + break; + case 2: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ic")) { + sbp.bra = sbp.cursor; + if (!r_R2()) + sbp.slice_from("iqU"); + else + sbp.slice_del(); + } + break; + case 3: + if (!r_R2()) + return false; + sbp.slice_from("log"); + break; + case 4: + if (!r_R2()) + return false; + sbp.slice_from("u"); + break; + case 5: + if (!r_R2()) + return false; + sbp.slice_from("ent"); + break; + case 6: + if (!r_RV()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 6); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R2()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + } + break; + case 2: + if (r_R2()) + sbp.slice_del(); + else if (r_R1()) + sbp.slice_from("eux"); + break; + case 3: + if (r_R2()) + sbp.slice_del(); + break; + case 4: + if (r_RV()) + sbp.slice_from("i"); + break; + } + } + break; + case 7: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 3); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R2()) + sbp.slice_del(); + else + sbp.slice_from("abl"); + break; + case 2: + if (r_R2()) + sbp.slice_del(); + else + sbp.slice_from("iqU"); + break; + case 3: + if (r_R2()) + sbp.slice_del(); + break; + } + } + break; + case 8: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ic")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + else + sbp.slice_from("iqU"); + break; + } + } + } + break; + case 9: + sbp.slice_from("eau"); + break; + case 10: + if (!r_R1()) + return false; + sbp.slice_from("al"); + break; + case 11: + if (r_R2()) + sbp.slice_del(); + else if (!r_R1()) + return false; + else + sbp.slice_from("eux"); + break; + case 12: + if (!r_R1() || !sbp.out_grouping_b(g_v, 97, 251)) + return false; + sbp.slice_del(); + break; + case 13: + if (r_RV()) + sbp.slice_from("ant"); + return false; + case 14: + if (r_RV()) + sbp.slice_from("ent"); + return false; + case 15: + v_1 = sbp.limit - sbp.cursor; + if (sbp.in_grouping_b(g_v, 97, 251) && r_RV()) { + sbp.cursor = sbp.limit - v_1; + sbp.slice_del(); + } + return false; + } + return true; + } + return false; + } + + function r_i_verb_suffix() { + var among_var, v_1; + if (sbp.cursor < I_pV) + return false; + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_5, 35); + if (!among_var) { + sbp.limit_backward = v_1; + return false; + } + sbp.bra = sbp.cursor; + if (among_var == 1) { + if (!sbp.out_grouping_b(g_v, 97, 251)) { + sbp.limit_backward = v_1; + return false; + } + sbp.slice_del(); + } + sbp.limit_backward = v_1; + return true; + } + + function r_verb_suffix() { + var among_var, v_2, v_3; + if (sbp.cursor < I_pV) + return false; + v_2 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 38); + if (!among_var) { + sbp.limit_backward = v_2; + return false; + } + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) { + sbp.limit_backward = v_2; + return false; + } + sbp.slice_del(); + break; + case 2: + sbp.slice_del(); + break; + case 3: + sbp.slice_del(); + v_3 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "e")) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + } else + sbp.cursor = sbp.limit - v_3; + break; + } + sbp.limit_backward = v_2; + return true; + } + + function r_residual_suffix() { + var among_var, v_1 = sbp.limit - sbp.cursor, + v_2, v_4, v_5; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "s")) { + sbp.bra = sbp.cursor; + v_2 = sbp.limit - sbp.cursor; + if (sbp.out_grouping_b(g_keep_with_s, 97, 232)) { + sbp.cursor = sbp.limit - v_2; + sbp.slice_del(); + } else + sbp.cursor = sbp.limit - v_1; + } else + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor >= I_pV) { + v_4 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 7); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_R2()) { + v_5 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "s")) { + sbp.cursor = sbp.limit - v_5; + if (!sbp.eq_s_b(1, "t")) + break; + } + sbp.slice_del(); + } + break; + case 2: + sbp.slice_from("i"); + break; + case 3: + sbp.slice_del(); + break; + case 4: + if (sbp.eq_s_b(2, "gu")) + sbp.slice_del(); + break; + } + } + sbp.limit_backward = v_4; + } + } + + function r_un_double() { + var v_1 = sbp.limit - sbp.cursor; + if (sbp.find_among_b(a_8, 5)) { + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + } + } + + function r_un_accent() { + var v_1, v_2 = 1; + while (sbp.out_grouping_b(g_v, 97, 251)) + v_2--; + if (v_2 <= 0) { + sbp.ket = sbp.cursor; + v_1 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "\u00E9")) { + sbp.cursor = sbp.limit - v_1; + if (!sbp.eq_s_b(1, "\u00E8")) + return; + } + sbp.bra = sbp.cursor; + sbp.slice_from("e"); + } + } + + function habr5() { + if (!r_standard_suffix()) { + sbp.cursor = sbp.limit; + if (!r_i_verb_suffix()) { + sbp.cursor = sbp.limit; + if (!r_verb_suffix()) { + sbp.cursor = sbp.limit; + r_residual_suffix(); + return; + } + } + } + sbp.cursor = sbp.limit; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "Y")) { + sbp.bra = sbp.cursor; + sbp.slice_from("i"); + } else { + sbp.cursor = sbp.limit; + if (sbp.eq_s_b(1, "\u00E7")) { + sbp.bra = sbp.cursor; + sbp.slice_from("c"); + } + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_prelude(); + sbp.cursor = v_1; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + habr5(); + sbp.cursor = sbp.limit; + r_un_double(); + sbp.cursor = sbp.limit; + r_un_accent(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.fr.stemmer, 'stemmer-fr'); + + /* stop word filter function */ + lunr.fr.stopWordFilter = function(token) { + if (lunr.fr.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.fr.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.fr.stopWordFilter.stopWords.length = 164; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.fr.stopWordFilter.stopWords.elements = ' ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes'.split(' '); + + lunr.Pipeline.registerFunction(lunr.fr.stopWordFilter, 'stopWordFilter-fr'); + }; +})) \ No newline at end of file diff --git a/js/lunr.fr.min.js b/js/lunr.fr.min.js new file mode 100644 index 0000000..2f29909 --- /dev/null +++ b/js/lunr.fr.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,s,i;r.fr=function(){this.pipeline.reset(),this.pipeline.add(r.fr.trimmer,r.fr.stopWordFilter,r.fr.stemmer)},r.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.fr.trimmer=r.trimmerSupport.generateTrimmer(r.fr.wordCharacters),r.Pipeline.registerFunction(r.fr.trimmer,"trimmer-fr"),r.fr.stemmer=(e=r.stemmerSupport.Among,s=r.stemmerSupport.SnowballProgram,i=new function(){var i,n,t,o=[new e("col",-1,-1),new e("par",-1,-1),new e("tap",-1,-1)],u=[new e("",-1,4),new e("I",0,1),new e("U",0,2),new e("Y",0,3)],c=[new e("iqU",-1,3),new e("abl",-1,3),new e("Ièr",-1,4),new e("ièr",-1,4),new e("eus",-1,2),new e("iv",-1,1)],a=[new e("ic",-1,2),new e("abil",-1,1),new e("iv",-1,3)],l=[new e("iqUe",-1,1),new e("atrice",-1,2),new e("ance",-1,1),new e("ence",-1,5),new e("logie",-1,3),new e("able",-1,1),new e("isme",-1,1),new e("euse",-1,11),new e("iste",-1,1),new e("ive",-1,8),new e("if",-1,8),new e("usion",-1,4),new e("ation",-1,2),new e("ution",-1,4),new e("ateur",-1,2),new e("iqUes",-1,1),new e("atrices",-1,2),new e("ances",-1,1),new e("ences",-1,5),new e("logies",-1,3),new e("ables",-1,1),new e("ismes",-1,1),new e("euses",-1,11),new e("istes",-1,1),new e("ives",-1,8),new e("ifs",-1,8),new e("usions",-1,4),new e("ations",-1,2),new e("utions",-1,4),new e("ateurs",-1,2),new e("ments",-1,15),new e("ements",30,6),new e("issements",31,12),new e("ités",-1,7),new e("ment",-1,15),new e("ement",34,6),new e("issement",35,12),new e("amment",34,13),new e("emment",34,14),new e("aux",-1,10),new e("eaux",39,9),new e("eux",-1,1),new e("ité",-1,7)],w=[new e("ira",-1,1),new e("ie",-1,1),new e("isse",-1,1),new e("issante",-1,1),new e("i",-1,1),new e("irai",4,1),new e("ir",-1,1),new e("iras",-1,1),new e("ies",-1,1),new e("îmes",-1,1),new e("isses",-1,1),new e("issantes",-1,1),new e("îtes",-1,1),new e("is",-1,1),new e("irais",13,1),new e("issais",13,1),new e("irions",-1,1),new e("issions",-1,1),new e("irons",-1,1),new e("issons",-1,1),new e("issants",-1,1),new e("it",-1,1),new e("irait",21,1),new e("issait",21,1),new e("issant",-1,1),new e("iraIent",-1,1),new e("issaIent",-1,1),new e("irent",-1,1),new e("issent",-1,1),new e("iront",-1,1),new e("ît",-1,1),new e("iriez",-1,1),new e("issiez",-1,1),new e("irez",-1,1),new e("issez",-1,1)],f=[new e("a",-1,3),new e("era",0,2),new e("asse",-1,3),new e("ante",-1,3),new e("ée",-1,2),new e("ai",-1,3),new e("erai",5,2),new e("er",-1,2),new e("as",-1,3),new e("eras",8,2),new e("âmes",-1,3),new e("asses",-1,3),new e("antes",-1,3),new e("âtes",-1,3),new e("ées",-1,2),new e("ais",-1,3),new e("erais",15,2),new e("ions",-1,1),new e("erions",17,2),new e("assions",17,3),new e("erons",-1,2),new e("ants",-1,3),new e("és",-1,2),new e("ait",-1,3),new e("erait",23,2),new e("ant",-1,3),new e("aIent",-1,3),new e("eraIent",26,2),new e("èrent",-1,2),new e("assent",-1,3),new e("eront",-1,2),new e("ât",-1,3),new e("ez",-1,2),new e("iez",32,2),new e("eriez",33,2),new e("assiez",33,3),new e("erez",32,2),new e("é",-1,2)],m=[new e("e",-1,3),new e("Ière",0,2),new e("ière",0,2),new e("ion",-1,1),new e("Ier",-1,2),new e("ier",-1,2),new e("ë",-1,4)],_=[new e("ell",-1,-1),new e("eill",-1,-1),new e("enn",-1,-1),new e("onn",-1,-1),new e("ett",-1,-1)],b=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],d=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],k=new s;function p(e,r,s){return k.eq_s(1,e)&&(k.ket=k.cursor,k.in_grouping(b,97,251))&&(k.slice_from(r),k.cursor=s,1)}function g(e,r,s){return k.eq_s(1,e)&&(k.ket=k.cursor,k.slice_from(r),k.cursor=s,1)}function q(){for(;!k.in_grouping(b,97,251);){if(k.cursor>=k.limit)return 1;k.cursor++}for(;!k.out_grouping(b,97,251);){if(k.cursor>=k.limit)return 1;k.cursor++}}function v(){return t<=k.cursor}function z(){return n<=k.cursor}function h(){return i<=k.cursor}function W(){if(function(){var e,r;if(k.ket=k.cursor,e=k.find_among_b(l,43)){switch(k.bra=k.cursor,e){case 1:if(!h())return;k.slice_del();break;case 2:if(!h())return;k.slice_del(),k.ket=k.cursor,k.eq_s_b(2,"ic")&&(k.bra=k.cursor,h()?k.slice_del():k.slice_from("iqU"));break;case 3:if(!h())return;k.slice_from("log");break;case 4:if(!h())return;k.slice_from("u");break;case 5:if(!h())return;k.slice_from("ent");break;case 6:if(!v())return;if(k.slice_del(),k.ket=k.cursor,e=k.find_among_b(c,6))switch(k.bra=k.cursor,e){case 1:h()&&(k.slice_del(),k.ket=k.cursor,k.eq_s_b(2,"at"))&&(k.bra=k.cursor,h())&&k.slice_del();break;case 2:h()?k.slice_del():z()&&k.slice_from("eux");break;case 3:h()&&k.slice_del();break;case 4:v()&&k.slice_from("i")}break;case 7:if(!h())return;if(k.slice_del(),k.ket=k.cursor,e=k.find_among_b(a,3))switch(k.bra=k.cursor,e){case 1:h()?k.slice_del():k.slice_from("abl");break;case 2:h()?k.slice_del():k.slice_from("iqU");break;case 3:h()&&k.slice_del()}break;case 8:if(!h())return;k.slice_del(),k.ket=k.cursor,k.eq_s_b(2,"at")&&(k.bra=k.cursor,h())&&(k.slice_del(),k.ket=k.cursor,k.eq_s_b(2,"ic"))&&(k.bra=k.cursor,h()?k.slice_del():k.slice_from("iqU"));break;case 9:k.slice_from("eau");break;case 10:if(!z())return;k.slice_from("al");break;case 11:if(h())k.slice_del();else{if(!z())return;k.slice_from("eux")}break;case 12:if(!z()||!k.out_grouping_b(b,97,251))return;k.slice_del();break;case 13:return v()&&k.slice_from("ant"),0;case 14:return v()&&k.slice_from("ent"),0;case 15:return r=k.limit-k.cursor,k.in_grouping_b(b,97,251)&&v()&&(k.cursor=k.limit-r,k.slice_del()),0}return 1}}()||(k.cursor=k.limit,function(){var e,r;if(!(k.cursor=t){if(e=k.limit_backward,k.limit_backward=t,k.ket=k.cursor,s=k.find_among_b(m,7))switch(k.bra=k.cursor,s){case 1:if(h()){if(r=k.limit-k.cursor,!k.eq_s_b(1,"s")&&(k.cursor=k.limit-r,!k.eq_s_b(1,"t")))break;k.slice_del()}break;case 2:k.slice_from("i");break;case 3:k.slice_del();break;case 4:k.eq_s_b(2,"gu")&&k.slice_del()}k.limit_backward=e}}}this.setCurrent=function(e){k.setCurrent(e)},this.getCurrent=function(){return k.getCurrent()},this.stem=function(){var e=k.cursor,r=(!function(){for(var e,r;;){if(e=k.cursor,k.in_grouping(b,97,251)){if(k.bra=k.cursor,r=k.cursor,p("u","U",e))continue;if(k.cursor=r,p("i","I",e))continue;if(k.cursor=r,g("y","Y",e))continue}if(k.cursor=e,k.bra=e,!p("y","Y",e)&&(k.cursor=e,!k.eq_s(1,"q")||(k.bra=k.cursor,!g("u","U",e)))){if((k.cursor=e)>=k.limit)return;k.cursor++}}}(),k.cursor=e,k.cursor);if(t=k.limit,i=n=t,k.in_grouping(b,97,251)&&k.in_grouping(b,97,251)&&k.cursor=k.limit){k.cursor=t;break}}while(k.cursor++,!k.in_grouping(b,97,251))}t=k.cursor,k.cursor=r,q()||(n=k.cursor,q())||(i=k.cursor),k.limit_backward=e,k.cursor=k.limit,W(),k.cursor=k.limit,r=k.limit-k.cursor,k.find_among_b(_,5)&&(k.cursor=k.limit-r,k.ket=k.cursor,k.cursor>k.limit_backward)&&(k.cursor--,k.bra=k.cursor,k.slice_del()),k.cursor=k.limit;for(var s=1;k.out_grouping_b(b,97,251);)s--;return s<=0&&(k.ket=k.cursor,e=k.limit-k.cursor,k.eq_s_b(1,"é")||(k.cursor=k.limit-e,k.eq_s_b(1,"è")))&&(k.bra=k.cursor,k.slice_from("e")),k.cursor=k.limit_backward,function(){for(var e;e=k.cursor,k.bra=e,e=k.find_among(u,4);)switch(k.ket=k.cursor,e){case 1:k.slice_from("i");break;case 2:k.slice_from("u");break;case 3:k.slice_from("y");break;case 4:if(k.cursor>=k.limit)return;k.cursor++}}(),!0}},function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}),r.Pipeline.registerFunction(r.fr.stemmer,"stemmer-fr"),r.fr.stopWordFilter=function(e){if(-1===r.fr.stopWordFilter.stopWords.indexOf(e))return e},r.fr.stopWordFilter.stopWords=new r.SortedSet,r.fr.stopWordFilter.stopWords.length=164,r.fr.stopWordFilter.stopWords.elements=" ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" "),r.Pipeline.registerFunction(r.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/js/lunr.hu.js b/js/lunr.hu.js new file mode 100644 index 0000000..de7dc97 --- /dev/null +++ b/js/lunr.hu.js @@ -0,0 +1,561 @@ +/*! + * Lunr languages, `Hungarian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.hu = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.hu.trimmer, + lunr.hu.stopWordFilter, + lunr.hu.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.hu.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.hu.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.hu.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.hu.trimmer, 'trimmer-hu'); + + /* lunr stemmer function */ + lunr.hu.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function HungarianStemmer() { + var a_0 = [new Among("cs", -1, -1), new Among("dzs", -1, -1), + new Among("gy", -1, -1), new Among("ly", -1, -1), + new Among("ny", -1, -1), new Among("sz", -1, -1), + new Among("ty", -1, -1), new Among("zs", -1, -1) + ], + a_1 = [ + new Among("\u00E1", -1, 1), new Among("\u00E9", -1, 2) + ], + a_2 = [ + new Among("bb", -1, -1), new Among("cc", -1, -1), + new Among("dd", -1, -1), new Among("ff", -1, -1), + new Among("gg", -1, -1), new Among("jj", -1, -1), + new Among("kk", -1, -1), new Among("ll", -1, -1), + new Among("mm", -1, -1), new Among("nn", -1, -1), + new Among("pp", -1, -1), new Among("rr", -1, -1), + new Among("ccs", -1, -1), new Among("ss", -1, -1), + new Among("zzs", -1, -1), new Among("tt", -1, -1), + new Among("vv", -1, -1), new Among("ggy", -1, -1), + new Among("lly", -1, -1), new Among("nny", -1, -1), + new Among("tty", -1, -1), new Among("ssz", -1, -1), + new Among("zz", -1, -1) + ], + a_3 = [new Among("al", -1, 1), + new Among("el", -1, 2) + ], + a_4 = [new Among("ba", -1, -1), + new Among("ra", -1, -1), new Among("be", -1, -1), + new Among("re", -1, -1), new Among("ig", -1, -1), + new Among("nak", -1, -1), new Among("nek", -1, -1), + new Among("val", -1, -1), new Among("vel", -1, -1), + new Among("ul", -1, -1), new Among("n\u00E1l", -1, -1), + new Among("n\u00E9l", -1, -1), new Among("b\u00F3l", -1, -1), + new Among("r\u00F3l", -1, -1), new Among("t\u00F3l", -1, -1), + new Among("b\u00F5l", -1, -1), new Among("r\u00F5l", -1, -1), + new Among("t\u00F5l", -1, -1), new Among("\u00FCl", -1, -1), + new Among("n", -1, -1), new Among("an", 19, -1), + new Among("ban", 20, -1), new Among("en", 19, -1), + new Among("ben", 22, -1), new Among("k\u00E9ppen", 22, -1), + new Among("on", 19, -1), new Among("\u00F6n", 19, -1), + new Among("k\u00E9pp", -1, -1), new Among("kor", -1, -1), + new Among("t", -1, -1), new Among("at", 29, -1), + new Among("et", 29, -1), new Among("k\u00E9nt", 29, -1), + new Among("ank\u00E9nt", 32, -1), new Among("enk\u00E9nt", 32, -1), + new Among("onk\u00E9nt", 32, -1), new Among("ot", 29, -1), + new Among("\u00E9rt", 29, -1), new Among("\u00F6t", 29, -1), + new Among("hez", -1, -1), new Among("hoz", -1, -1), + new Among("h\u00F6z", -1, -1), new Among("v\u00E1", -1, -1), + new Among("v\u00E9", -1, -1) + ], + a_5 = [new Among("\u00E1n", -1, 2), + new Among("\u00E9n", -1, 1), new Among("\u00E1nk\u00E9nt", -1, 3) + ], + a_6 = [ + new Among("stul", -1, 2), new Among("astul", 0, 1), + new Among("\u00E1stul", 0, 3), new Among("st\u00FCl", -1, 2), + new Among("est\u00FCl", 3, 1), new Among("\u00E9st\u00FCl", 3, 4) + ], + a_7 = [ + new Among("\u00E1", -1, 1), new Among("\u00E9", -1, 2) + ], + a_8 = [ + new Among("k", -1, 7), new Among("ak", 0, 4), + new Among("ek", 0, 6), new Among("ok", 0, 5), + new Among("\u00E1k", 0, 1), new Among("\u00E9k", 0, 2), + new Among("\u00F6k", 0, 3) + ], + a_9 = [new Among("\u00E9i", -1, 7), + new Among("\u00E1\u00E9i", 0, 6), new Among("\u00E9\u00E9i", 0, 5), + new Among("\u00E9", -1, 9), new Among("k\u00E9", 3, 4), + new Among("ak\u00E9", 4, 1), new Among("ek\u00E9", 4, 1), + new Among("ok\u00E9", 4, 1), new Among("\u00E1k\u00E9", 4, 3), + new Among("\u00E9k\u00E9", 4, 2), new Among("\u00F6k\u00E9", 4, 1), + new Among("\u00E9\u00E9", 3, 8) + ], + a_10 = [new Among("a", -1, 18), + new Among("ja", 0, 17), new Among("d", -1, 16), + new Among("ad", 2, 13), new Among("ed", 2, 13), + new Among("od", 2, 13), new Among("\u00E1d", 2, 14), + new Among("\u00E9d", 2, 15), new Among("\u00F6d", 2, 13), + new Among("e", -1, 18), new Among("je", 9, 17), + new Among("nk", -1, 4), new Among("unk", 11, 1), + new Among("\u00E1nk", 11, 2), new Among("\u00E9nk", 11, 3), + new Among("\u00FCnk", 11, 1), new Among("uk", -1, 8), + new Among("juk", 16, 7), new Among("\u00E1juk", 17, 5), + new Among("\u00FCk", -1, 8), new Among("j\u00FCk", 19, 7), + new Among("\u00E9j\u00FCk", 20, 6), new Among("m", -1, 12), + new Among("am", 22, 9), new Among("em", 22, 9), + new Among("om", 22, 9), new Among("\u00E1m", 22, 10), + new Among("\u00E9m", 22, 11), new Among("o", -1, 18), + new Among("\u00E1", -1, 19), new Among("\u00E9", -1, 20) + ], + a_11 = [ + new Among("id", -1, 10), new Among("aid", 0, 9), + new Among("jaid", 1, 6), new Among("eid", 0, 9), + new Among("jeid", 3, 6), new Among("\u00E1id", 0, 7), + new Among("\u00E9id", 0, 8), new Among("i", -1, 15), + new Among("ai", 7, 14), new Among("jai", 8, 11), + new Among("ei", 7, 14), new Among("jei", 10, 11), + new Among("\u00E1i", 7, 12), new Among("\u00E9i", 7, 13), + new Among("itek", -1, 24), new Among("eitek", 14, 21), + new Among("jeitek", 15, 20), new Among("\u00E9itek", 14, 23), + new Among("ik", -1, 29), new Among("aik", 18, 26), + new Among("jaik", 19, 25), new Among("eik", 18, 26), + new Among("jeik", 21, 25), new Among("\u00E1ik", 18, 27), + new Among("\u00E9ik", 18, 28), new Among("ink", -1, 20), + new Among("aink", 25, 17), new Among("jaink", 26, 16), + new Among("eink", 25, 17), new Among("jeink", 28, 16), + new Among("\u00E1ink", 25, 18), new Among("\u00E9ink", 25, 19), + new Among("aitok", -1, 21), new Among("jaitok", 32, 20), + new Among("\u00E1itok", -1, 22), new Among("im", -1, 5), + new Among("aim", 35, 4), new Among("jaim", 36, 1), + new Among("eim", 35, 4), new Among("jeim", 38, 1), + new Among("\u00E1im", 35, 2), new Among("\u00E9im", 35, 3) + ], + g_v = [ + 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 52, 14 + ], + I_p1, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function r_mark_regions() { + var v_1 = sbp.cursor, + v_2; + I_p1 = sbp.limit; + if (sbp.in_grouping(g_v, 97, 252)) { + while (true) { + v_2 = sbp.cursor; + if (sbp.out_grouping(g_v, 97, 252)) { + sbp.cursor = v_2; + if (!sbp.find_among(a_0, 8)) { + sbp.cursor = v_2; + if (v_2 < sbp.limit) + sbp.cursor++; + } + I_p1 = sbp.cursor; + return; + } + sbp.cursor = v_2; + if (v_2 >= sbp.limit) { + I_p1 = v_2; + return; + } + sbp.cursor++; + } + } + sbp.cursor = v_1; + if (sbp.out_grouping(g_v, 97, 252)) { + while (!sbp.in_grouping(g_v, 97, 252)) { + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + I_p1 = sbp.cursor; + } + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_v_ending() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_1, 2); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + sbp.slice_from("a"); + break; + case 2: + sbp.slice_from("e"); + break; + } + } + } + } + + function r_double() { + var v_1 = sbp.limit - sbp.cursor; + if (!sbp.find_among_b(a_2, 23)) + return false; + sbp.cursor = sbp.limit - v_1; + return true; + } + + function r_undouble() { + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.ket = sbp.cursor; + var c = sbp.cursor - 1; + if (sbp.limit_backward <= c && c <= sbp.limit) { + sbp.cursor = c; + sbp.bra = c; + sbp.slice_del(); + } + } + } + + function r_instrum() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 2); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + if (among_var == 1 || among_var == 2) + if (!r_double()) + return; + sbp.slice_del(); + r_undouble(); + } + } + } + + function r_case() { + sbp.ket = sbp.cursor; + if (sbp.find_among_b(a_4, 44)) { + sbp.bra = sbp.cursor; + if (r_R1()) { + sbp.slice_del(); + r_v_ending(); + } + } + } + + function r_case_special() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_5, 3); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + sbp.slice_from("e"); + break; + case 2: + case 3: + sbp.slice_from("a"); + break; + } + } + } + } + + function r_case_other() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 6); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + case 2: + sbp.slice_del(); + break; + case 3: + sbp.slice_from("a"); + break; + case 4: + sbp.slice_from("e"); + break; + } + } + } + } + + function r_factive() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 2); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + if (among_var == 1 || among_var == 2) + if (!r_double()) + return; + sbp.slice_del(); + r_undouble() + } + } + } + + function r_plural() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_8, 7); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + sbp.slice_from("a"); + break; + case 2: + sbp.slice_from("e"); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + sbp.slice_del(); + break; + } + } + } + } + + function r_owned() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_9, 12); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + case 4: + case 7: + case 9: + sbp.slice_del(); + break; + case 2: + case 5: + case 8: + sbp.slice_from("e"); + break; + case 3: + case 6: + sbp.slice_from("a"); + break; + } + } + } + } + + function r_sing_owner() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_10, 31); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + case 4: + case 7: + case 8: + case 9: + case 12: + case 13: + case 16: + case 17: + case 18: + sbp.slice_del(); + break; + case 2: + case 5: + case 10: + case 14: + case 19: + sbp.slice_from("a"); + break; + case 3: + case 6: + case 11: + case 15: + case 20: + sbp.slice_from("e"); + break; + } + } + } + } + + function r_plur_owner() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_11, 42); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + case 4: + case 5: + case 6: + case 9: + case 10: + case 11: + case 14: + case 15: + case 16: + case 17: + case 20: + case 21: + case 24: + case 25: + case 26: + case 29: + sbp.slice_del(); + break; + case 2: + case 7: + case 12: + case 18: + case 22: + case 27: + sbp.slice_from("a"); + break; + case 3: + case 8: + case 13: + case 19: + case 23: + case 28: + sbp.slice_from("e"); + break; + } + } + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_instrum(); + sbp.cursor = sbp.limit; + r_case(); + sbp.cursor = sbp.limit; + r_case_special(); + sbp.cursor = sbp.limit; + r_case_other(); + sbp.cursor = sbp.limit; + r_factive(); + sbp.cursor = sbp.limit; + r_owned(); + sbp.cursor = sbp.limit; + r_sing_owner(); + sbp.cursor = sbp.limit; + r_plur_owner(); + sbp.cursor = sbp.limit; + r_plural(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.hu.stemmer, 'stemmer-hu'); + + /* stop word filter function */ + lunr.hu.stopWordFilter = function(token) { + if (lunr.hu.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.hu.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.hu.stopWordFilter.stopWords.length = 200; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.hu.stopWordFilter.stopWords.elements = ' a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra'.split(' '); + + lunr.Pipeline.registerFunction(lunr.hu.stopWordFilter, 'stopWordFilter-hu'); + }; +})) \ No newline at end of file diff --git a/js/lunr.hu.min.js b/js/lunr.hu.min.js new file mode 100644 index 0000000..2c556e5 --- /dev/null +++ b/js/lunr.hu.min.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(n){if(void 0===n)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===n.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,_,r;n.hu=function(){this.pipeline.reset(),this.pipeline.add(n.hu.trimmer,n.hu.stopWordFilter,n.hu.stemmer)},n.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",n.hu.trimmer=n.trimmerSupport.generateTrimmer(n.hu.wordCharacters),n.Pipeline.registerFunction(n.hu.trimmer,"trimmer-hu"),n.hu.stemmer=(e=n.stemmerSupport.Among,_=n.stemmerSupport.SnowballProgram,r=new function(){var r,i=[new e("cs",-1,-1),new e("dzs",-1,-1),new e("gy",-1,-1),new e("ly",-1,-1),new e("ny",-1,-1),new e("sz",-1,-1),new e("ty",-1,-1),new e("zs",-1,-1)],n=[new e("á",-1,1),new e("é",-1,2)],s=[new e("bb",-1,-1),new e("cc",-1,-1),new e("dd",-1,-1),new e("ff",-1,-1),new e("gg",-1,-1),new e("jj",-1,-1),new e("kk",-1,-1),new e("ll",-1,-1),new e("mm",-1,-1),new e("nn",-1,-1),new e("pp",-1,-1),new e("rr",-1,-1),new e("ccs",-1,-1),new e("ss",-1,-1),new e("zzs",-1,-1),new e("tt",-1,-1),new e("vv",-1,-1),new e("ggy",-1,-1),new e("lly",-1,-1),new e("nny",-1,-1),new e("tty",-1,-1),new e("ssz",-1,-1),new e("zz",-1,-1)],a=[new e("al",-1,1),new e("el",-1,2)],t=[new e("ba",-1,-1),new e("ra",-1,-1),new e("be",-1,-1),new e("re",-1,-1),new e("ig",-1,-1),new e("nak",-1,-1),new e("nek",-1,-1),new e("val",-1,-1),new e("vel",-1,-1),new e("ul",-1,-1),new e("nál",-1,-1),new e("nél",-1,-1),new e("ból",-1,-1),new e("ról",-1,-1),new e("tól",-1,-1),new e("bõl",-1,-1),new e("rõl",-1,-1),new e("tõl",-1,-1),new e("ül",-1,-1),new e("n",-1,-1),new e("an",19,-1),new e("ban",20,-1),new e("en",19,-1),new e("ben",22,-1),new e("képpen",22,-1),new e("on",19,-1),new e("ön",19,-1),new e("képp",-1,-1),new e("kor",-1,-1),new e("t",-1,-1),new e("at",29,-1),new e("et",29,-1),new e("ként",29,-1),new e("anként",32,-1),new e("enként",32,-1),new e("onként",32,-1),new e("ot",29,-1),new e("ért",29,-1),new e("öt",29,-1),new e("hez",-1,-1),new e("hoz",-1,-1),new e("höz",-1,-1),new e("vá",-1,-1),new e("vé",-1,-1)],o=[new e("án",-1,2),new e("én",-1,1),new e("ánként",-1,3)],w=[new e("stul",-1,2),new e("astul",0,1),new e("ástul",0,3),new e("stül",-1,2),new e("estül",3,1),new e("éstül",3,4)],c=[new e("á",-1,1),new e("é",-1,2)],l=[new e("k",-1,7),new e("ak",0,4),new e("ek",0,6),new e("ok",0,5),new e("ák",0,1),new e("ék",0,2),new e("ök",0,3)],m=[new e("éi",-1,7),new e("áéi",0,6),new e("ééi",0,5),new e("é",-1,9),new e("ké",3,4),new e("aké",4,1),new e("eké",4,1),new e("oké",4,1),new e("áké",4,3),new e("éké",4,2),new e("öké",4,1),new e("éé",3,8)],u=[new e("a",-1,18),new e("ja",0,17),new e("d",-1,16),new e("ad",2,13),new e("ed",2,13),new e("od",2,13),new e("ád",2,14),new e("éd",2,15),new e("öd",2,13),new e("e",-1,18),new e("je",9,17),new e("nk",-1,4),new e("unk",11,1),new e("ánk",11,2),new e("énk",11,3),new e("ünk",11,1),new e("uk",-1,8),new e("juk",16,7),new e("ájuk",17,5),new e("ük",-1,8),new e("jük",19,7),new e("éjük",20,6),new e("m",-1,12),new e("am",22,9),new e("em",22,9),new e("om",22,9),new e("ám",22,10),new e("ém",22,11),new e("o",-1,18),new e("á",-1,19),new e("é",-1,20)],k=[new e("id",-1,10),new e("aid",0,9),new e("jaid",1,6),new e("eid",0,9),new e("jeid",3,6),new e("áid",0,7),new e("éid",0,8),new e("i",-1,15),new e("ai",7,14),new e("jai",8,11),new e("ei",7,14),new e("jei",10,11),new e("ái",7,12),new e("éi",7,13),new e("itek",-1,24),new e("eitek",14,21),new e("jeitek",15,20),new e("éitek",14,23),new e("ik",-1,29),new e("aik",18,26),new e("jaik",19,25),new e("eik",18,26),new e("jeik",21,25),new e("áik",18,27),new e("éik",18,28),new e("ink",-1,20),new e("aink",25,17),new e("jaink",26,16),new e("eink",25,17),new e("jeink",28,16),new e("áink",25,18),new e("éink",25,19),new e("aitok",-1,21),new e("jaitok",32,20),new e("áitok",-1,22),new e("im",-1,5),new e("aim",35,4),new e("jaim",36,1),new e("eim",35,4),new e("jeim",38,1),new e("áim",35,2),new e("éim",35,3)],d=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],b=new _;function f(){return r<=b.cursor}function g(){var e=b.limit-b.cursor;return b.find_among_b(s,23)&&(b.cursor=b.limit-e,1)}function h(){var e;b.cursor>b.limit_backward&&(b.cursor--,b.ket=b.cursor,e=b.cursor-1,b.limit_backward<=e)&&e<=b.limit&&(b.cursor=e,b.bra=e,b.slice_del())}function p(){var e;if((b.ket=b.cursor,b.find_among_b(t,44))&&(b.bra=b.cursor,f()&&(b.slice_del(),b.ket=b.cursor,e=b.find_among_b(n,2))&&(b.bra=b.cursor,f())))switch(e){case 1:b.slice_from("a");break;case 2:b.slice_from("e")}}this.setCurrent=function(e){b.setCurrent(e)},this.getCurrent=function(){return b.getCurrent()},this.stem=function(){var e=b.cursor;if(!function(){var e,n=b.cursor;if(r=b.limit,b.in_grouping(d,97,252))for(;;){if(e=b.cursor,b.out_grouping(d,97,252))return b.cursor=e,b.find_among(i,8)||(b.cursor=e)=b.limit)return r=e;b.cursor++}if(b.cursor=n,b.out_grouping(d,97,252)){for(;!b.in_grouping(d,97,252);){if(b.cursor>=b.limit)return;b.cursor++}r=b.cursor}}(),b.limit_backward=e,b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(a,2))&&(b.bra=b.cursor,f())&&(1!=e&&2!=e||g())&&(b.slice_del(),h()),b.cursor=b.limit,p(),b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(o,3))&&(b.bra=b.cursor,f()))switch(e){case 1:b.slice_from("e");break;case 2:case 3:b.slice_from("a")}if(b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(w,6))&&(b.bra=b.cursor,f()))switch(e){case 1:case 2:b.slice_del();break;case 3:b.slice_from("a");break;case 4:b.slice_from("e")}if(b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(c,2))&&(b.bra=b.cursor,f())&&(1!=e&&2!=e||g())&&(b.slice_del(),h()),b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(m,12))&&(b.bra=b.cursor,f()))switch(e){case 1:case 4:case 7:case 9:b.slice_del();break;case 2:case 5:case 8:b.slice_from("e");break;case 3:case 6:b.slice_from("a")}if(b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(u,31))&&(b.bra=b.cursor,f()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:b.slice_del();break;case 2:case 5:case 10:case 14:case 19:b.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:b.slice_from("e")}if(b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(k,42))&&(b.bra=b.cursor,f()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:b.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:b.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:b.slice_from("e")}if(b.cursor=b.limit,b.ket=b.cursor,(e=b.find_among_b(l,7))&&(b.bra=b.cursor,f()))switch(e){case 1:b.slice_from("a");break;case 2:b.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:b.slice_del()}return!0}},function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}),n.Pipeline.registerFunction(n.hu.stemmer,"stemmer-hu"),n.hu.stopWordFilter=function(e){if(-1===n.hu.stopWordFilter.stopWords.indexOf(e))return e},n.hu.stopWordFilter.stopWords=new n.SortedSet,n.hu.stopWordFilter.stopWords.length=200,n.hu.stopWordFilter.stopWords.elements=" a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" "),n.Pipeline.registerFunction(n.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/js/lunr.it.js b/js/lunr.it.js new file mode 100644 index 0000000..91fc8bd --- /dev/null +++ b/js/lunr.it.js @@ -0,0 +1,612 @@ +/*! + * Lunr languages, `Italian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.it = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.it.trimmer, + lunr.it.stopWordFilter, + lunr.it.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.it.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.it.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.it.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.it.trimmer, 'trimmer-it'); + + /* lunr stemmer function */ + lunr.it.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function ItalianStemmer() { + var a_0 = [new Among("", -1, 7), new Among("qu", 0, 6), + new Among("\u00E1", 0, 1), new Among("\u00E9", 0, 2), + new Among("\u00ED", 0, 3), new Among("\u00F3", 0, 4), + new Among("\u00FA", 0, 5) + ], + a_1 = [new Among("", -1, 3), + new Among("I", 0, 1), new Among("U", 0, 2) + ], + a_2 = [ + new Among("la", -1, -1), new Among("cela", 0, -1), + new Among("gliela", 0, -1), new Among("mela", 0, -1), + new Among("tela", 0, -1), new Among("vela", 0, -1), + new Among("le", -1, -1), new Among("cele", 6, -1), + new Among("gliele", 6, -1), new Among("mele", 6, -1), + new Among("tele", 6, -1), new Among("vele", 6, -1), + new Among("ne", -1, -1), new Among("cene", 12, -1), + new Among("gliene", 12, -1), new Among("mene", 12, -1), + new Among("sene", 12, -1), new Among("tene", 12, -1), + new Among("vene", 12, -1), new Among("ci", -1, -1), + new Among("li", -1, -1), new Among("celi", 20, -1), + new Among("glieli", 20, -1), new Among("meli", 20, -1), + new Among("teli", 20, -1), new Among("veli", 20, -1), + new Among("gli", 20, -1), new Among("mi", -1, -1), + new Among("si", -1, -1), new Among("ti", -1, -1), + new Among("vi", -1, -1), new Among("lo", -1, -1), + new Among("celo", 31, -1), new Among("glielo", 31, -1), + new Among("melo", 31, -1), new Among("telo", 31, -1), + new Among("velo", 31, -1) + ], + a_3 = [new Among("ando", -1, 1), + new Among("endo", -1, 1), new Among("ar", -1, 2), + new Among("er", -1, 2), new Among("ir", -1, 2) + ], + a_4 = [ + new Among("ic", -1, -1), new Among("abil", -1, -1), + new Among("os", -1, -1), new Among("iv", -1, 1) + ], + a_5 = [ + new Among("ic", -1, 1), new Among("abil", -1, 1), + new Among("iv", -1, 1) + ], + a_6 = [new Among("ica", -1, 1), + new Among("logia", -1, 3), new Among("osa", -1, 1), + new Among("ista", -1, 1), new Among("iva", -1, 9), + new Among("anza", -1, 1), new Among("enza", -1, 5), + new Among("ice", -1, 1), new Among("atrice", 7, 1), + new Among("iche", -1, 1), new Among("logie", -1, 3), + new Among("abile", -1, 1), new Among("ibile", -1, 1), + new Among("usione", -1, 4), new Among("azione", -1, 2), + new Among("uzione", -1, 4), new Among("atore", -1, 2), + new Among("ose", -1, 1), new Among("ante", -1, 1), + new Among("mente", -1, 1), new Among("amente", 19, 7), + new Among("iste", -1, 1), new Among("ive", -1, 9), + new Among("anze", -1, 1), new Among("enze", -1, 5), + new Among("ici", -1, 1), new Among("atrici", 25, 1), + new Among("ichi", -1, 1), new Among("abili", -1, 1), + new Among("ibili", -1, 1), new Among("ismi", -1, 1), + new Among("usioni", -1, 4), new Among("azioni", -1, 2), + new Among("uzioni", -1, 4), new Among("atori", -1, 2), + new Among("osi", -1, 1), new Among("anti", -1, 1), + new Among("amenti", -1, 6), new Among("imenti", -1, 6), + new Among("isti", -1, 1), new Among("ivi", -1, 9), + new Among("ico", -1, 1), new Among("ismo", -1, 1), + new Among("oso", -1, 1), new Among("amento", -1, 6), + new Among("imento", -1, 6), new Among("ivo", -1, 9), + new Among("it\u00E0", -1, 8), new Among("ist\u00E0", -1, 1), + new Among("ist\u00E8", -1, 1), new Among("ist\u00EC", -1, 1) + ], + a_7 = [ + new Among("isca", -1, 1), new Among("enda", -1, 1), + new Among("ata", -1, 1), new Among("ita", -1, 1), + new Among("uta", -1, 1), new Among("ava", -1, 1), + new Among("eva", -1, 1), new Among("iva", -1, 1), + new Among("erebbe", -1, 1), new Among("irebbe", -1, 1), + new Among("isce", -1, 1), new Among("ende", -1, 1), + new Among("are", -1, 1), new Among("ere", -1, 1), + new Among("ire", -1, 1), new Among("asse", -1, 1), + new Among("ate", -1, 1), new Among("avate", 16, 1), + new Among("evate", 16, 1), new Among("ivate", 16, 1), + new Among("ete", -1, 1), new Among("erete", 20, 1), + new Among("irete", 20, 1), new Among("ite", -1, 1), + new Among("ereste", -1, 1), new Among("ireste", -1, 1), + new Among("ute", -1, 1), new Among("erai", -1, 1), + new Among("irai", -1, 1), new Among("isci", -1, 1), + new Among("endi", -1, 1), new Among("erei", -1, 1), + new Among("irei", -1, 1), new Among("assi", -1, 1), + new Among("ati", -1, 1), new Among("iti", -1, 1), + new Among("eresti", -1, 1), new Among("iresti", -1, 1), + new Among("uti", -1, 1), new Among("avi", -1, 1), + new Among("evi", -1, 1), new Among("ivi", -1, 1), + new Among("isco", -1, 1), new Among("ando", -1, 1), + new Among("endo", -1, 1), new Among("Yamo", -1, 1), + new Among("iamo", -1, 1), new Among("avamo", -1, 1), + new Among("evamo", -1, 1), new Among("ivamo", -1, 1), + new Among("eremo", -1, 1), new Among("iremo", -1, 1), + new Among("assimo", -1, 1), new Among("ammo", -1, 1), + new Among("emmo", -1, 1), new Among("eremmo", 54, 1), + new Among("iremmo", 54, 1), new Among("immo", -1, 1), + new Among("ano", -1, 1), new Among("iscano", 58, 1), + new Among("avano", 58, 1), new Among("evano", 58, 1), + new Among("ivano", 58, 1), new Among("eranno", -1, 1), + new Among("iranno", -1, 1), new Among("ono", -1, 1), + new Among("iscono", 65, 1), new Among("arono", 65, 1), + new Among("erono", 65, 1), new Among("irono", 65, 1), + new Among("erebbero", -1, 1), new Among("irebbero", -1, 1), + new Among("assero", -1, 1), new Among("essero", -1, 1), + new Among("issero", -1, 1), new Among("ato", -1, 1), + new Among("ito", -1, 1), new Among("uto", -1, 1), + new Among("avo", -1, 1), new Among("evo", -1, 1), + new Among("ivo", -1, 1), new Among("ar", -1, 1), + new Among("ir", -1, 1), new Among("er\u00E0", -1, 1), + new Among("ir\u00E0", -1, 1), new Among("er\u00F2", -1, 1), + new Among("ir\u00F2", -1, 1) + ], + g_v = [17, 65, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1 + ], + g_AEIO = [17, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2 + ], + g_CG = [17], + I_p2, I_p1, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function habr1(c1, c2, v_1) { + if (sbp.eq_s(1, c1)) { + sbp.ket = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 249)) { + sbp.slice_from(c2); + sbp.cursor = v_1; + return true; + } + } + return false; + } + + function r_prelude() { + var among_var, v_1 = sbp.cursor, + v_2, v_3, v_4; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_0, 7); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("\u00E0"); + continue; + case 2: + sbp.slice_from("\u00E8"); + continue; + case 3: + sbp.slice_from("\u00EC"); + continue; + case 4: + sbp.slice_from("\u00F2"); + continue; + case 5: + sbp.slice_from("\u00F9"); + continue; + case 6: + sbp.slice_from("qU"); + continue; + case 7: + if (sbp.cursor >= sbp.limit) + break; + sbp.cursor++; + continue; + } + } + break; + } + sbp.cursor = v_1; + while (true) { + v_2 = sbp.cursor; + while (true) { + v_3 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 249)) { + sbp.bra = sbp.cursor; + v_4 = sbp.cursor; + if (habr1("u", "U", v_3)) + break; + sbp.cursor = v_4; + if (habr1("i", "I", v_3)) + break; + } + sbp.cursor = v_3; + if (sbp.cursor >= sbp.limit) { + sbp.cursor = v_2; + return; + } + sbp.cursor++; + } + } + } + + function habr2(v_1) { + sbp.cursor = v_1; + if (!sbp.in_grouping(g_v, 97, 249)) + return false; + while (!sbp.out_grouping(g_v, 97, 249)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function habr3() { + if (sbp.in_grouping(g_v, 97, 249)) { + var v_1 = sbp.cursor; + if (sbp.out_grouping(g_v, 97, 249)) { + while (!sbp.in_grouping(g_v, 97, 249)) { + if (sbp.cursor >= sbp.limit) + return habr2(v_1); + sbp.cursor++; + } + return true; + } + return habr2(v_1); + } + return false; + } + + function habr4() { + var v_1 = sbp.cursor, + v_2; + if (!habr3()) { + sbp.cursor = v_1; + if (!sbp.out_grouping(g_v, 97, 249)) + return; + v_2 = sbp.cursor; + if (sbp.out_grouping(g_v, 97, 249)) { + while (!sbp.in_grouping(g_v, 97, 249)) { + if (sbp.cursor >= sbp.limit) { + sbp.cursor = v_2; + if (sbp.in_grouping(g_v, 97, 249) && sbp.cursor < sbp.limit) + sbp.cursor++; + return; + } + sbp.cursor++; + } + I_pV = sbp.cursor; + return; + } + sbp.cursor = v_2; + if (!sbp.in_grouping(g_v, 97, 249) || sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + I_pV = sbp.cursor; + } + + function habr5() { + while (!sbp.in_grouping(g_v, 97, 249)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 249)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function r_mark_regions() { + var v_1 = sbp.cursor; + I_pV = sbp.limit; + I_p1 = I_pV; + I_p2 = I_pV; + habr4(); + sbp.cursor = v_1; + if (habr5()) { + I_p1 = sbp.cursor; + if (habr5()) + I_p2 = sbp.cursor; + } + } + + function r_postlude() { + var among_var; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_1, 3); + if (!among_var) + break; + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("i"); + break; + case 2: + sbp.slice_from("u"); + break; + case 3: + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + break; + } + } + } + + function r_RV() { + return I_pV <= sbp.cursor; + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_attached_pronoun() { + var among_var; + sbp.ket = sbp.cursor; + if (sbp.find_among_b(a_2, 37)) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among_b(a_3, 5); + if (among_var && r_RV()) { + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + sbp.slice_from("e"); + break; + } + } + } + } + + function r_standard_suffix() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 51); + if (!among_var) + return false; + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) + return false; + sbp.slice_del(); + break; + case 2: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ic")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + break; + case 3: + if (!r_R2()) + return false; + sbp.slice_from("log"); + break; + case 4: + if (!r_R2()) + return false; + sbp.slice_from("u"); + break; + case 5: + if (!r_R2()) + return false; + sbp.slice_from("ente"); + break; + case 6: + if (!r_RV()) + return false; + sbp.slice_del(); + break; + case 7: + if (!r_R1()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 4); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2()) { + sbp.slice_del(); + if (among_var == 1) { + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + } + } + } + break; + case 8: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_5, 3); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) + if (r_R2()) + sbp.slice_del(); + } + break; + case 9: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "ic")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + } + } + break; + } + return true; + } + + function r_verb_suffix() { + var among_var, v_1; + if (sbp.cursor >= I_pV) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 87); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) + sbp.slice_del(); + } + sbp.limit_backward = v_1; + } + } + + function habr6() { + var v_1 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (sbp.in_grouping_b(g_AEIO, 97, 242)) { + sbp.bra = sbp.cursor; + if (r_RV()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "i")) { + sbp.bra = sbp.cursor; + if (r_RV()) { + sbp.slice_del(); + return; + } + } + } + } + sbp.cursor = sbp.limit - v_1; + } + + function r_vowel_suffix() { + habr6(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "h")) { + sbp.bra = sbp.cursor; + if (sbp.in_grouping_b(g_CG, 99, 103)) + if (r_RV()) + sbp.slice_del(); + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_prelude(); + sbp.cursor = v_1; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_attached_pronoun(); + sbp.cursor = sbp.limit; + if (!r_standard_suffix()) { + sbp.cursor = sbp.limit; + r_verb_suffix(); + } + sbp.cursor = sbp.limit; + r_vowel_suffix(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.it.stemmer, 'stemmer-it'); + + /* stop word filter function */ + lunr.it.stopWordFilter = function(token) { + if (lunr.it.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.it.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.it.stopWordFilter.stopWords.length = 280; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.it.stopWordFilter.stopWords.elements = ' a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è'.split(' '); + + lunr.Pipeline.registerFunction(lunr.it.stopWordFilter, 'stopWordFilter-it'); + }; +})) \ No newline at end of file diff --git a/js/lunr.it.min.js b/js/lunr.it.min.js new file mode 100644 index 0000000..f232c3f --- /dev/null +++ b/js/lunr.it.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,F,i;r.it=function(){this.pipeline.reset(),this.pipeline.add(r.it.trimmer,r.it.stopWordFilter,r.it.stemmer)},r.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.it.trimmer=r.trimmerSupport.generateTrimmer(r.it.wordCharacters),r.Pipeline.registerFunction(r.it.trimmer,"trimmer-it"),r.it.stemmer=(e=r.stemmerSupport.Among,F=r.stemmerSupport.SnowballProgram,i=new function(){var n,o,s,t=[new e("",-1,7),new e("qu",0,6),new e("á",0,1),new e("é",0,2),new e("í",0,3),new e("ó",0,4),new e("ú",0,5)],a=[new e("",-1,3),new e("I",0,1),new e("U",0,2)],u=[new e("la",-1,-1),new e("cela",0,-1),new e("gliela",0,-1),new e("mela",0,-1),new e("tela",0,-1),new e("vela",0,-1),new e("le",-1,-1),new e("cele",6,-1),new e("gliele",6,-1),new e("mele",6,-1),new e("tele",6,-1),new e("vele",6,-1),new e("ne",-1,-1),new e("cene",12,-1),new e("gliene",12,-1),new e("mene",12,-1),new e("sene",12,-1),new e("tene",12,-1),new e("vene",12,-1),new e("ci",-1,-1),new e("li",-1,-1),new e("celi",20,-1),new e("glieli",20,-1),new e("meli",20,-1),new e("teli",20,-1),new e("veli",20,-1),new e("gli",20,-1),new e("mi",-1,-1),new e("si",-1,-1),new e("ti",-1,-1),new e("vi",-1,-1),new e("lo",-1,-1),new e("celo",31,-1),new e("glielo",31,-1),new e("melo",31,-1),new e("telo",31,-1),new e("velo",31,-1)],c=[new e("ando",-1,1),new e("endo",-1,1),new e("ar",-1,2),new e("er",-1,2),new e("ir",-1,2)],r=[new e("ic",-1,-1),new e("abil",-1,-1),new e("os",-1,-1),new e("iv",-1,1)],i=[new e("ic",-1,1),new e("abil",-1,1),new e("iv",-1,1)],w=[new e("ica",-1,1),new e("logia",-1,3),new e("osa",-1,1),new e("ista",-1,1),new e("iva",-1,9),new e("anza",-1,1),new e("enza",-1,5),new e("ice",-1,1),new e("atrice",7,1),new e("iche",-1,1),new e("logie",-1,3),new e("abile",-1,1),new e("ibile",-1,1),new e("usione",-1,4),new e("azione",-1,2),new e("uzione",-1,4),new e("atore",-1,2),new e("ose",-1,1),new e("ante",-1,1),new e("mente",-1,1),new e("amente",19,7),new e("iste",-1,1),new e("ive",-1,9),new e("anze",-1,1),new e("enze",-1,5),new e("ici",-1,1),new e("atrici",25,1),new e("ichi",-1,1),new e("abili",-1,1),new e("ibili",-1,1),new e("ismi",-1,1),new e("usioni",-1,4),new e("azioni",-1,2),new e("uzioni",-1,4),new e("atori",-1,2),new e("osi",-1,1),new e("anti",-1,1),new e("amenti",-1,6),new e("imenti",-1,6),new e("isti",-1,1),new e("ivi",-1,9),new e("ico",-1,1),new e("ismo",-1,1),new e("oso",-1,1),new e("amento",-1,6),new e("imento",-1,6),new e("ivo",-1,9),new e("ità",-1,8),new e("istà",-1,1),new e("istè",-1,1),new e("istì",-1,1)],l=[new e("isca",-1,1),new e("enda",-1,1),new e("ata",-1,1),new e("ita",-1,1),new e("uta",-1,1),new e("ava",-1,1),new e("eva",-1,1),new e("iva",-1,1),new e("erebbe",-1,1),new e("irebbe",-1,1),new e("isce",-1,1),new e("ende",-1,1),new e("are",-1,1),new e("ere",-1,1),new e("ire",-1,1),new e("asse",-1,1),new e("ate",-1,1),new e("avate",16,1),new e("evate",16,1),new e("ivate",16,1),new e("ete",-1,1),new e("erete",20,1),new e("irete",20,1),new e("ite",-1,1),new e("ereste",-1,1),new e("ireste",-1,1),new e("ute",-1,1),new e("erai",-1,1),new e("irai",-1,1),new e("isci",-1,1),new e("endi",-1,1),new e("erei",-1,1),new e("irei",-1,1),new e("assi",-1,1),new e("ati",-1,1),new e("iti",-1,1),new e("eresti",-1,1),new e("iresti",-1,1),new e("uti",-1,1),new e("avi",-1,1),new e("evi",-1,1),new e("ivi",-1,1),new e("isco",-1,1),new e("ando",-1,1),new e("endo",-1,1),new e("Yamo",-1,1),new e("iamo",-1,1),new e("avamo",-1,1),new e("evamo",-1,1),new e("ivamo",-1,1),new e("eremo",-1,1),new e("iremo",-1,1),new e("assimo",-1,1),new e("ammo",-1,1),new e("emmo",-1,1),new e("eremmo",54,1),new e("iremmo",54,1),new e("immo",-1,1),new e("ano",-1,1),new e("iscano",58,1),new e("avano",58,1),new e("evano",58,1),new e("ivano",58,1),new e("eranno",-1,1),new e("iranno",-1,1),new e("ono",-1,1),new e("iscono",65,1),new e("arono",65,1),new e("erono",65,1),new e("irono",65,1),new e("erebbero",-1,1),new e("irebbero",-1,1),new e("assero",-1,1),new e("essero",-1,1),new e("issero",-1,1),new e("ato",-1,1),new e("ito",-1,1),new e("uto",-1,1),new e("avo",-1,1),new e("evo",-1,1),new e("ivo",-1,1),new e("ar",-1,1),new e("ir",-1,1),new e("erà",-1,1),new e("irà",-1,1),new e("erò",-1,1),new e("irò",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],f=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],v=[17],b=new F;function d(e,r,i){return b.eq_s(1,e)&&(b.ket=b.cursor,b.in_grouping(m,97,249))&&(b.slice_from(r),b.cursor=i,1)}function _(e){if(b.cursor=e,!b.in_grouping(m,97,249))return!1;for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function g(){var e,r=b.cursor;if(!function(){if(b.in_grouping(m,97,249)){var e=b.cursor;if(b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return _(e);b.cursor++}return 1}return _(e)}}()){if(b.cursor=r,!b.out_grouping(m,97,249))return;if(e=b.cursor,b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return b.cursor=e,void(b.in_grouping(m,97,249)&&b.cursor=b.limit)return;b.cursor++}s=b.cursor}function p(){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return;b.cursor++}for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return;b.cursor++}return 1}function k(){return s<=b.cursor}function h(){return n<=b.cursor}function q(){var e;if(b.ket=b.cursor,e=b.find_among_b(w,51)){switch(b.bra=b.cursor,e){case 1:if(!h())return;b.slice_del();break;case 2:if(!h())return;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic")&&(b.bra=b.cursor,h())&&b.slice_del();break;case 3:if(!h())return;b.slice_from("log");break;case 4:if(!h())return;b.slice_from("u");break;case 5:if(!h())return;b.slice_from("ente");break;case 6:if(!k())return;b.slice_del();break;case 7:if(!(o<=b.cursor))return;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(r,4))&&(b.bra=b.cursor,h())&&(b.slice_del(),1==e)&&(b.ket=b.cursor,b.eq_s_b(2,"at"))&&(b.bra=b.cursor,h())&&b.slice_del();break;case 8:if(!h())return;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(i,3))&&(b.bra=b.cursor,1==e)&&h()&&b.slice_del();break;case 9:if(!h())return;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"at")&&(b.bra=b.cursor,h())&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic"))&&(b.bra=b.cursor,h())&&b.slice_del()}return 1}}function W(){var e;e=b.limit-b.cursor,b.ket=b.cursor,b.in_grouping_b(f,97,242)&&(b.bra=b.cursor,k())&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(1,"i"))&&(b.bra=b.cursor,k())?b.slice_del():b.cursor=b.limit-e,b.ket=b.cursor,b.eq_s_b(1,"h")&&(b.bra=b.cursor,b.in_grouping_b(v,99,103))&&k()&&b.slice_del()}this.setCurrent=function(e){b.setCurrent(e)},this.getCurrent=function(){return b.getCurrent()},this.stem=function(){var e,r,i=b.cursor;if(!function(){for(var e,r,i,n,o=b.cursor;;){if(b.bra=b.cursor,e=b.find_among(t,7))switch(b.ket=b.cursor,e){case 1:b.slice_from("à");continue;case 2:b.slice_from("è");continue;case 3:b.slice_from("ì");continue;case 4:b.slice_from("ò");continue;case 5:b.slice_from("ù");continue;case 6:b.slice_from("qU");continue;case 7:if(!(b.cursor>=b.limit)){b.cursor++;continue}}break}for(b.cursor=o;;)for(r=b.cursor;;){if(i=b.cursor,b.in_grouping(m,97,249)){if(b.bra=b.cursor,n=b.cursor,d("u","U",i))break;if(b.cursor=n,d("i","I",i))break}if(b.cursor=i,b.cursor>=b.limit)return b.cursor=r;b.cursor++}}(),b.cursor=i,r=b.cursor,s=b.limit,n=o=s,g(),b.cursor=r,p()&&(o=b.cursor,p())&&(n=b.cursor),b.limit_backward=i,b.cursor=b.limit,b.ket=b.cursor,b.find_among_b(u,37)&&(b.bra=b.cursor,e=b.find_among_b(c,5))&&k())switch(e){case 1:b.slice_del();break;case 2:b.slice_from("e")}return b.cursor=b.limit,q()||(b.cursor=b.limit,b.cursor>=s&&(r=b.limit_backward,b.limit_backward=s,b.ket=b.cursor,(i=b.find_among_b(l,87))&&(b.bra=b.cursor,1==i)&&b.slice_del(),b.limit_backward=r)),b.cursor=b.limit,W(),b.cursor=b.limit_backward,function(){for(var e;b.bra=b.cursor,e=b.find_among(a,3);)switch(b.ket=b.cursor,e){case 1:b.slice_from("i");break;case 2:b.slice_from("u");break;case 3:if(b.cursor>=b.limit)return;b.cursor++}}(),!0}},function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}),r.Pipeline.registerFunction(r.it.stemmer,"stemmer-it"),r.it.stopWordFilter=function(e){if(-1===r.it.stopWordFilter.stopWords.indexOf(e))return e},r.it.stopWordFilter.stopWords=new r.SortedSet,r.it.stopWordFilter.stopWords.length=280,r.it.stopWordFilter.stopWords.elements=" a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" "),r.Pipeline.registerFunction(r.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/js/lunr.jp.js b/js/lunr.jp.js new file mode 100644 index 0000000..4dcdc43 --- /dev/null +++ b/js/lunr.jp.js @@ -0,0 +1,118 @@ +/*! + * Lunr languages, `Japanese` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Chad Liu + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.jp = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.jp.stopWordFilter, + lunr.jp.stemmer + ); + // change the tokenizer for japanese one + lunr.tokenizer = lunr.jp.tokenizer; + }; + var segmenter = new TinySegmenter(); // インスタンス生成 + + lunr.jp.tokenizer = function (obj) { + if (!arguments.length || obj == null || obj == undefined) return [] + if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() }) + + var str = obj.toString().replace(/^\s+/, '') + + for (var i = str.length - 1; i >= 0; i--) { + if (/\S/.test(str.charAt(i))) { + str = str.substring(0, i + 1) + break + } + } + + + var segs = segmenter.segment(str); // 単語の配列が返る + return segs.filter(function (token) { + return !!token + }) + .map(function (token) { + return token + }) + } + + /* lunr stemmer function */ + lunr.jp.stemmer = (function() { + + /* TODO japanese stemmer */ + return function(word) { + return word; + } + })(); + + lunr.Pipeline.registerFunction(lunr.jp.stemmer, 'stemmer-jp'); + + /* stop word filter function */ + lunr.jp.stopWordFilter = function(token) { + if (lunr.jp.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.jp.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.jp.stopWordFilter.stopWords.length = 45; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + // stopword for japanese is from http://www.ranks.nl/stopwords/japanese + lunr.jp.stopWordFilter.stopWords.elements = ' これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし'.split(' '); + lunr.Pipeline.registerFunction(lunr.jp.stopWordFilter, 'stopWordFilter-jp'); + }; +})) \ No newline at end of file diff --git a/js/lunr.jp.min.js b/js/lunr.jp.min.js new file mode 100644 index 0000000..b70d9ee --- /dev/null +++ b/js/lunr.jp.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.jp=function(){this.pipeline.reset(),this.pipeline.add(r.jp.stopWordFilter,r.jp.stemmer),r.tokenizer=r.jp.tokenizer};var n=new TinySegmenter;r.jp.tokenizer=function(e){if(!arguments.length||null==e)return[];if(Array.isArray(e))return e.map(function(e){return e.toLowerCase()});for(var r=e.toString().replace(/^\s+/,""),t=r.length-1;0<=t;t--)if(/\S/.test(r.charAt(t))){r=r.substring(0,t+1);break}return n.segment(r).filter(function(e){return!!e}).map(function(e){return e})},r.jp.stemmer=function(e){return e},r.Pipeline.registerFunction(r.jp.stemmer,"stemmer-jp"),r.jp.stopWordFilter=function(e){if(-1===r.jp.stopWordFilter.stopWords.indexOf(e))return e},r.jp.stopWordFilter.stopWords=new r.SortedSet,r.jp.stopWordFilter.stopWords.length=45,r.jp.stopWordFilter.stopWords.elements=" これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" "),r.Pipeline.registerFunction(r.jp.stopWordFilter,"stopWordFilter-jp")}}); \ No newline at end of file diff --git a/js/lunr.no.js b/js/lunr.no.js new file mode 100644 index 0000000..acaa024 --- /dev/null +++ b/js/lunr.no.js @@ -0,0 +1,253 @@ +/*! + * Lunr languages, `Norwegian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.no = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.no.trimmer, + lunr.no.stopWordFilter, + lunr.no.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.no.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.no.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.no.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.no.trimmer, 'trimmer-no'); + + /* lunr stemmer function */ + lunr.no.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function NorwegianStemmer() { + var a_0 = [new Among("a", -1, 1), new Among("e", -1, 1), + new Among("ede", 1, 1), new Among("ande", 1, 1), + new Among("ende", 1, 1), new Among("ane", 1, 1), + new Among("ene", 1, 1), new Among("hetene", 6, 1), + new Among("erte", 1, 3), new Among("en", -1, 1), + new Among("heten", 9, 1), new Among("ar", -1, 1), + new Among("er", -1, 1), new Among("heter", 12, 1), + new Among("s", -1, 2), new Among("as", 14, 1), + new Among("es", 14, 1), new Among("edes", 16, 1), + new Among("endes", 16, 1), new Among("enes", 16, 1), + new Among("hetenes", 19, 1), new Among("ens", 14, 1), + new Among("hetens", 21, 1), new Among("ers", 14, 1), + new Among("ets", 14, 1), new Among("et", -1, 1), + new Among("het", 25, 1), new Among("ert", -1, 3), + new Among("ast", -1, 1) + ], + a_1 = [new Among("dt", -1, -1), + new Among("vt", -1, -1) + ], + a_2 = [new Among("leg", -1, 1), + new Among("eleg", 0, 1), new Among("ig", -1, 1), + new Among("eig", 2, 1), new Among("lig", 2, 1), + new Among("elig", 4, 1), new Among("els", -1, 1), + new Among("lov", -1, 1), new Among("elov", 7, 1), + new Among("slov", 7, 1), new Among("hetslov", 9, 1) + ], + g_v = [17, + 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 + ], + g_s_ending = [ + 119, 125, 149, 1 + ], + I_x, I_p1, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function r_mark_regions() { + var v_1, c = sbp.cursor + 3; + I_p1 = sbp.limit; + if (0 <= c || c <= sbp.limit) { + I_x = c; + while (true) { + v_1 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 248)) { + sbp.cursor = v_1; + break; + } + if (v_1 >= sbp.limit) + return; + sbp.cursor = v_1 + 1; + } + while (!sbp.out_grouping(g_v, 97, 248)) { + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + I_p1 = sbp.cursor; + if (I_p1 < I_x) + I_p1 = I_x; + } + } + + function r_main_suffix() { + var among_var, v_1, v_2; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_0, 29); + sbp.limit_backward = v_1; + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + v_2 = sbp.limit - sbp.cursor; + if (sbp.in_grouping_b(g_s_ending, 98, 122)) + sbp.slice_del(); + else { + sbp.cursor = sbp.limit - v_2; + if (sbp.eq_s_b(1, "k") && sbp.out_grouping_b(g_v, 97, 248)) + sbp.slice_del(); + } + break; + case 3: + sbp.slice_from("er"); + break; + } + } + } + } + + function r_consonant_pair() { + var v_1 = sbp.limit - sbp.cursor, + v_2; + if (sbp.cursor >= I_p1) { + v_2 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + if (sbp.find_among_b(a_1, 2)) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_2; + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + } else + sbp.limit_backward = v_2; + } + } + + function r_other_suffix() { + var among_var, v_1; + if (sbp.cursor >= I_p1) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 11); + if (among_var) { + sbp.bra = sbp.cursor; + sbp.limit_backward = v_1; + if (among_var == 1) + sbp.slice_del(); + } else + sbp.limit_backward = v_1; + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_main_suffix(); + sbp.cursor = sbp.limit; + r_consonant_pair(); + sbp.cursor = sbp.limit; + r_other_suffix(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.no.stemmer, 'stemmer-no'); + + /* stop word filter function */ + lunr.no.stopWordFilter = function(token) { + if (lunr.no.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.no.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.no.stopWordFilter.stopWords.length = 177; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.no.stopWordFilter.stopWords.elements = ' alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å'.split(' '); + + lunr.Pipeline.registerFunction(lunr.no.stopWordFilter, 'stopWordFilter-no'); + }; +})) \ No newline at end of file diff --git a/js/lunr.no.min.js b/js/lunr.no.min.js new file mode 100644 index 0000000..ac91e96 --- /dev/null +++ b/js/lunr.no.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,n,i;r.no=function(){this.pipeline.reset(),this.pipeline.add(r.no.trimmer,r.no.stopWordFilter,r.no.stemmer)},r.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.no.trimmer=r.trimmerSupport.generateTrimmer(r.no.wordCharacters),r.Pipeline.registerFunction(r.no.trimmer,"trimmer-no"),r.no.stemmer=(e=r.stemmerSupport.Among,n=r.stemmerSupport.SnowballProgram,i=new function(){var t,o,s=[new e("a",-1,1),new e("e",-1,1),new e("ede",1,1),new e("ande",1,1),new e("ende",1,1),new e("ane",1,1),new e("ene",1,1),new e("hetene",6,1),new e("erte",1,3),new e("en",-1,1),new e("heten",9,1),new e("ar",-1,1),new e("er",-1,1),new e("heter",12,1),new e("s",-1,2),new e("as",14,1),new e("es",14,1),new e("edes",16,1),new e("endes",16,1),new e("enes",16,1),new e("hetenes",19,1),new e("ens",14,1),new e("hetens",21,1),new e("ers",14,1),new e("ets",14,1),new e("et",-1,1),new e("het",25,1),new e("ert",-1,3),new e("ast",-1,1)],m=[new e("dt",-1,-1),new e("vt",-1,-1)],a=[new e("leg",-1,1),new e("eleg",0,1),new e("ig",-1,1),new e("eig",2,1),new e("lig",2,1),new e("elig",4,1),new e("els",-1,1),new e("lov",-1,1),new e("elov",7,1),new e("slov",7,1),new e("hetslov",9,1)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],d=[119,125,149,1],u=new n;this.setCurrent=function(e){u.setCurrent(e)},this.getCurrent=function(){return u.getCurrent()},this.stem=function(){var e,r,n,i=u.cursor;if(!function(){var e,r=u.cursor+3;if(o=u.limit,0<=r||r<=u.limit){for(t=r;;){if(e=u.cursor,u.in_grouping(l,97,248)){u.cursor=e;break}if(e>=u.limit)return;u.cursor=e+1}for(;!u.out_grouping(l,97,248);){if(u.cursor>=u.limit)return;u.cursor++}(o=u.cursor)=o&&(i=u.limit_backward,u.limit_backward=o,u.ket=u.cursor,r=u.find_among_b(s,29),u.limit_backward=i,r))switch(u.bra=u.cursor,r){case 1:u.slice_del();break;case 2:e=u.limit-u.cursor,(u.in_grouping_b(d,98,122)||(u.cursor=u.limit-e,u.eq_s_b(1,"k")&&u.out_grouping_b(l,97,248)))&&u.slice_del();break;case 3:u.slice_from("er")}return u.cursor=u.limit,i=u.limit-u.cursor,u.cursor>=o&&(r=u.limit_backward,u.limit_backward=o,u.ket=u.cursor,u.find_among_b(m,2)?(u.bra=u.cursor,u.limit_backward=r,u.cursor=u.limit-i,u.cursor>u.limit_backward&&(u.cursor--,u.bra=u.cursor,u.slice_del())):u.limit_backward=r),u.cursor=u.limit,u.cursor>=o&&(i=u.limit_backward,u.limit_backward=o,u.ket=u.cursor,(n=u.find_among_b(a,11))?(u.bra=u.cursor,u.limit_backward=i,1==n&&u.slice_del()):u.limit_backward=i),!0}},function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}),r.Pipeline.registerFunction(r.no.stemmer,"stemmer-no"),r.no.stopWordFilter=function(e){if(-1===r.no.stopWordFilter.stopWords.indexOf(e))return e},r.no.stopWordFilter.stopWords=new r.SortedSet,r.no.stopWordFilter.stopWords.length=177,r.no.stopWordFilter.stopWords.elements=" alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" "),r.Pipeline.registerFunction(r.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/js/lunr.pt.js b/js/lunr.pt.js new file mode 100644 index 0000000..b340325 --- /dev/null +++ b/js/lunr.pt.js @@ -0,0 +1,566 @@ +/*! + * Lunr languages, `Portuguese` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.pt = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.pt.trimmer, + lunr.pt.stopWordFilter, + lunr.pt.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.pt.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.pt.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.pt.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.pt.trimmer, 'trimmer-pt'); + + /* lunr stemmer function */ + lunr.pt.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function PortugueseStemmer() { + var a_0 = [new Among("", -1, 3), new Among("\u00E3", 0, 1), + new Among("\u00F5", 0, 2) + ], + a_1 = [new Among("", -1, 3), + new Among("a~", 0, 1), new Among("o~", 0, 2) + ], + a_2 = [ + new Among("ic", -1, -1), new Among("ad", -1, -1), + new Among("os", -1, -1), new Among("iv", -1, 1) + ], + a_3 = [ + new Among("ante", -1, 1), new Among("avel", -1, 1), + new Among("\u00EDvel", -1, 1) + ], + a_4 = [new Among("ic", -1, 1), + new Among("abil", -1, 1), new Among("iv", -1, 1) + ], + a_5 = [ + new Among("ica", -1, 1), new Among("\u00E2ncia", -1, 1), + new Among("\u00EAncia", -1, 4), new Among("ira", -1, 9), + new Among("adora", -1, 1), new Among("osa", -1, 1), + new Among("ista", -1, 1), new Among("iva", -1, 8), + new Among("eza", -1, 1), new Among("log\u00EDa", -1, 2), + new Among("idade", -1, 7), new Among("ante", -1, 1), + new Among("mente", -1, 6), new Among("amente", 12, 5), + new Among("\u00E1vel", -1, 1), new Among("\u00EDvel", -1, 1), + new Among("uci\u00F3n", -1, 3), new Among("ico", -1, 1), + new Among("ismo", -1, 1), new Among("oso", -1, 1), + new Among("amento", -1, 1), new Among("imento", -1, 1), + new Among("ivo", -1, 8), new Among("a\u00E7a~o", -1, 1), + new Among("ador", -1, 1), new Among("icas", -1, 1), + new Among("\u00EAncias", -1, 4), new Among("iras", -1, 9), + new Among("adoras", -1, 1), new Among("osas", -1, 1), + new Among("istas", -1, 1), new Among("ivas", -1, 8), + new Among("ezas", -1, 1), new Among("log\u00EDas", -1, 2), + new Among("idades", -1, 7), new Among("uciones", -1, 3), + new Among("adores", -1, 1), new Among("antes", -1, 1), + new Among("a\u00E7o~es", -1, 1), new Among("icos", -1, 1), + new Among("ismos", -1, 1), new Among("osos", -1, 1), + new Among("amentos", -1, 1), new Among("imentos", -1, 1), + new Among("ivos", -1, 8) + ], + a_6 = [new Among("ada", -1, 1), + new Among("ida", -1, 1), new Among("ia", -1, 1), + new Among("aria", 2, 1), new Among("eria", 2, 1), + new Among("iria", 2, 1), new Among("ara", -1, 1), + new Among("era", -1, 1), new Among("ira", -1, 1), + new Among("ava", -1, 1), new Among("asse", -1, 1), + new Among("esse", -1, 1), new Among("isse", -1, 1), + new Among("aste", -1, 1), new Among("este", -1, 1), + new Among("iste", -1, 1), new Among("ei", -1, 1), + new Among("arei", 16, 1), new Among("erei", 16, 1), + new Among("irei", 16, 1), new Among("am", -1, 1), + new Among("iam", 20, 1), new Among("ariam", 21, 1), + new Among("eriam", 21, 1), new Among("iriam", 21, 1), + new Among("aram", 20, 1), new Among("eram", 20, 1), + new Among("iram", 20, 1), new Among("avam", 20, 1), + new Among("em", -1, 1), new Among("arem", 29, 1), + new Among("erem", 29, 1), new Among("irem", 29, 1), + new Among("assem", 29, 1), new Among("essem", 29, 1), + new Among("issem", 29, 1), new Among("ado", -1, 1), + new Among("ido", -1, 1), new Among("ando", -1, 1), + new Among("endo", -1, 1), new Among("indo", -1, 1), + new Among("ara~o", -1, 1), new Among("era~o", -1, 1), + new Among("ira~o", -1, 1), new Among("ar", -1, 1), + new Among("er", -1, 1), new Among("ir", -1, 1), + new Among("as", -1, 1), new Among("adas", 47, 1), + new Among("idas", 47, 1), new Among("ias", 47, 1), + new Among("arias", 50, 1), new Among("erias", 50, 1), + new Among("irias", 50, 1), new Among("aras", 47, 1), + new Among("eras", 47, 1), new Among("iras", 47, 1), + new Among("avas", 47, 1), new Among("es", -1, 1), + new Among("ardes", 58, 1), new Among("erdes", 58, 1), + new Among("irdes", 58, 1), new Among("ares", 58, 1), + new Among("eres", 58, 1), new Among("ires", 58, 1), + new Among("asses", 58, 1), new Among("esses", 58, 1), + new Among("isses", 58, 1), new Among("astes", 58, 1), + new Among("estes", 58, 1), new Among("istes", 58, 1), + new Among("is", -1, 1), new Among("ais", 71, 1), + new Among("eis", 71, 1), new Among("areis", 73, 1), + new Among("ereis", 73, 1), new Among("ireis", 73, 1), + new Among("\u00E1reis", 73, 1), new Among("\u00E9reis", 73, 1), + new Among("\u00EDreis", 73, 1), new Among("\u00E1sseis", 73, 1), + new Among("\u00E9sseis", 73, 1), new Among("\u00EDsseis", 73, 1), + new Among("\u00E1veis", 73, 1), new Among("\u00EDeis", 73, 1), + new Among("ar\u00EDeis", 84, 1), new Among("er\u00EDeis", 84, 1), + new Among("ir\u00EDeis", 84, 1), new Among("ados", -1, 1), + new Among("idos", -1, 1), new Among("amos", -1, 1), + new Among("\u00E1ramos", 90, 1), new Among("\u00E9ramos", 90, 1), + new Among("\u00EDramos", 90, 1), new Among("\u00E1vamos", 90, 1), + new Among("\u00EDamos", 90, 1), new Among("ar\u00EDamos", 95, 1), + new Among("er\u00EDamos", 95, 1), new Among("ir\u00EDamos", 95, 1), + new Among("emos", -1, 1), new Among("aremos", 99, 1), + new Among("eremos", 99, 1), new Among("iremos", 99, 1), + new Among("\u00E1ssemos", 99, 1), new Among("\u00EAssemos", 99, 1), + new Among("\u00EDssemos", 99, 1), new Among("imos", -1, 1), + new Among("armos", -1, 1), new Among("ermos", -1, 1), + new Among("irmos", -1, 1), new Among("\u00E1mos", -1, 1), + new Among("ar\u00E1s", -1, 1), new Among("er\u00E1s", -1, 1), + new Among("ir\u00E1s", -1, 1), new Among("eu", -1, 1), + new Among("iu", -1, 1), new Among("ou", -1, 1), + new Among("ar\u00E1", -1, 1), new Among("er\u00E1", -1, 1), + new Among("ir\u00E1", -1, 1) + ], + a_7 = [new Among("a", -1, 1), + new Among("i", -1, 1), new Among("o", -1, 1), + new Among("os", -1, 1), new Among("\u00E1", -1, 1), + new Among("\u00ED", -1, 1), new Among("\u00F3", -1, 1) + ], + a_8 = [ + new Among("e", -1, 1), new Among("\u00E7", -1, 2), + new Among("\u00E9", -1, 1), new Among("\u00EA", -1, 1) + ], + g_v = [17, + 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2 + ], + I_p2, I_p1, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function r_prelude() { + var among_var; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_0, 3); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("a~"); + continue; + case 2: + sbp.slice_from("o~"); + continue; + case 3: + if (sbp.cursor >= sbp.limit) + break; + sbp.cursor++; + continue; + } + } + break; + } + } + + function habr2() { + if (sbp.out_grouping(g_v, 97, 250)) { + while (!sbp.in_grouping(g_v, 97, 250)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + return true; + } + + function habr3() { + if (sbp.in_grouping(g_v, 97, 250)) { + while (!sbp.out_grouping(g_v, 97, 250)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + } + I_pV = sbp.cursor; + return true; + } + + function habr4() { + var v_1 = sbp.cursor, + v_2, v_3; + if (sbp.in_grouping(g_v, 97, 250)) { + v_2 = sbp.cursor; + if (habr2()) { + sbp.cursor = v_2; + if (habr3()) + return; + } else + I_pV = sbp.cursor; + } + sbp.cursor = v_1; + if (sbp.out_grouping(g_v, 97, 250)) { + v_3 = sbp.cursor; + if (habr2()) { + sbp.cursor = v_3; + if (!sbp.in_grouping(g_v, 97, 250) || sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + I_pV = sbp.cursor; + } + } + + function habr5() { + while (!sbp.in_grouping(g_v, 97, 250)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 250)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function r_mark_regions() { + var v_1 = sbp.cursor; + I_pV = sbp.limit; + I_p1 = I_pV; + I_p2 = I_pV; + habr4(); + sbp.cursor = v_1; + if (habr5()) { + I_p1 = sbp.cursor; + if (habr5()) + I_p2 = sbp.cursor; + } + } + + function r_postlude() { + var among_var; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_1, 3); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("\u00E3"); + continue; + case 2: + sbp.slice_from("\u00F5"); + continue; + case 3: + if (sbp.cursor >= sbp.limit) + break; + sbp.cursor++; + continue; + } + } + break; + } + } + + function r_RV() { + return I_pV <= sbp.cursor; + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_standard_suffix() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_5, 45); + if (!among_var) + return false; + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (!r_R2()) + return false; + sbp.slice_del(); + break; + case 2: + if (!r_R2()) + return false; + sbp.slice_from("log"); + break; + case 3: + if (!r_R2()) + return false; + sbp.slice_from("u"); + break; + case 4: + if (!r_R2()) + return false; + sbp.slice_from("ente"); + break; + case 5: + if (!r_R1()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 4); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2()) { + sbp.slice_del(); + if (among_var == 1) { + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + } + } + } + break; + case 6: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 3); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) + if (r_R2()) + sbp.slice_del(); + } + break; + case 7: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 3); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) + if (r_R2()) + sbp.slice_del(); + } + break; + case 8: + if (!r_R2()) + return false; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(2, "at")) { + sbp.bra = sbp.cursor; + if (r_R2()) + sbp.slice_del(); + } + break; + case 9: + if (!r_RV() || !sbp.eq_s_b(1, "e")) + return false; + sbp.slice_from("ir"); + break; + } + return true; + } + + function r_verb_suffix() { + var among_var, v_1; + if (sbp.cursor >= I_pV) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 120); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) + sbp.slice_del(); + sbp.limit_backward = v_1; + return true; + } + sbp.limit_backward = v_1; + } + return false; + } + + function r_residual_suffix() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 7); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) + if (r_RV()) + sbp.slice_del(); + } + } + + function habr6(c1, c2) { + if (sbp.eq_s_b(1, c1)) { + sbp.bra = sbp.cursor; + var v_1 = sbp.limit - sbp.cursor; + if (sbp.eq_s_b(1, c2)) { + sbp.cursor = sbp.limit - v_1; + if (r_RV()) + sbp.slice_del(); + return false; + } + } + return true; + } + + function r_residual_form() { + var among_var, v_1, v_2, v_3; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_8, 4); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + if (r_RV()) { + sbp.slice_del(); + sbp.ket = sbp.cursor; + v_1 = sbp.limit - sbp.cursor; + if (habr6("u", "g")) + habr6("i", "c") + } + break; + case 2: + sbp.slice_from("c"); + break; + } + } + } + + function habr1() { + if (!r_standard_suffix()) { + sbp.cursor = sbp.limit; + if (!r_verb_suffix()) { + sbp.cursor = sbp.limit; + r_residual_suffix(); + return; + } + } + sbp.cursor = sbp.limit; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "i")) { + sbp.bra = sbp.cursor; + if (sbp.eq_s_b(1, "c")) { + sbp.cursor = sbp.limit; + if (r_RV()) + sbp.slice_del(); + } + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_prelude(); + sbp.cursor = v_1; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + habr1(); + sbp.cursor = sbp.limit; + r_residual_form(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.pt.stemmer, 'stemmer-pt'); + + /* stop word filter function */ + lunr.pt.stopWordFilter = function(token) { + if (lunr.pt.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.pt.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.pt.stopWordFilter.stopWords.length = 204; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.pt.stopWordFilter.stopWords.elements = ' a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos'.split(' '); + + lunr.Pipeline.registerFunction(lunr.pt.stopWordFilter, 'stopWordFilter-pt'); + }; +})) \ No newline at end of file diff --git a/js/lunr.pt.min.js b/js/lunr.pt.min.js new file mode 100644 index 0000000..c82fed6 --- /dev/null +++ b/js/lunr.pt.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,W,s;r.pt=function(){this.pipeline.reset(),this.pipeline.add(r.pt.trimmer,r.pt.stopWordFilter,r.pt.stemmer)},r.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.pt.trimmer=r.trimmerSupport.generateTrimmer(r.pt.wordCharacters),r.Pipeline.registerFunction(r.pt.trimmer,"trimmer-pt"),r.pt.stemmer=(e=r.stemmerSupport.Among,W=r.stemmerSupport.SnowballProgram,s=new function(){var o,i,t,a=[new e("",-1,3),new e("ã",0,1),new e("õ",0,2)],u=[new e("",-1,3),new e("a~",0,1),new e("o~",0,2)],r=[new e("ic",-1,-1),new e("ad",-1,-1),new e("os",-1,-1),new e("iv",-1,1)],s=[new e("ante",-1,1),new e("avel",-1,1),new e("ível",-1,1)],n=[new e("ic",-1,1),new e("abil",-1,1),new e("iv",-1,1)],w=[new e("ica",-1,1),new e("ância",-1,1),new e("ência",-1,4),new e("ira",-1,9),new e("adora",-1,1),new e("osa",-1,1),new e("ista",-1,1),new e("iva",-1,8),new e("eza",-1,1),new e("logía",-1,2),new e("idade",-1,7),new e("ante",-1,1),new e("mente",-1,6),new e("amente",12,5),new e("ável",-1,1),new e("ível",-1,1),new e("ución",-1,3),new e("ico",-1,1),new e("ismo",-1,1),new e("oso",-1,1),new e("amento",-1,1),new e("imento",-1,1),new e("ivo",-1,8),new e("aça~o",-1,1),new e("ador",-1,1),new e("icas",-1,1),new e("ências",-1,4),new e("iras",-1,9),new e("adoras",-1,1),new e("osas",-1,1),new e("istas",-1,1),new e("ivas",-1,8),new e("ezas",-1,1),new e("logías",-1,2),new e("idades",-1,7),new e("uciones",-1,3),new e("adores",-1,1),new e("antes",-1,1),new e("aço~es",-1,1),new e("icos",-1,1),new e("ismos",-1,1),new e("osos",-1,1),new e("amentos",-1,1),new e("imentos",-1,1),new e("ivos",-1,8)],m=[new e("ada",-1,1),new e("ida",-1,1),new e("ia",-1,1),new e("aria",2,1),new e("eria",2,1),new e("iria",2,1),new e("ara",-1,1),new e("era",-1,1),new e("ira",-1,1),new e("ava",-1,1),new e("asse",-1,1),new e("esse",-1,1),new e("isse",-1,1),new e("aste",-1,1),new e("este",-1,1),new e("iste",-1,1),new e("ei",-1,1),new e("arei",16,1),new e("erei",16,1),new e("irei",16,1),new e("am",-1,1),new e("iam",20,1),new e("ariam",21,1),new e("eriam",21,1),new e("iriam",21,1),new e("aram",20,1),new e("eram",20,1),new e("iram",20,1),new e("avam",20,1),new e("em",-1,1),new e("arem",29,1),new e("erem",29,1),new e("irem",29,1),new e("assem",29,1),new e("essem",29,1),new e("issem",29,1),new e("ado",-1,1),new e("ido",-1,1),new e("ando",-1,1),new e("endo",-1,1),new e("indo",-1,1),new e("ara~o",-1,1),new e("era~o",-1,1),new e("ira~o",-1,1),new e("ar",-1,1),new e("er",-1,1),new e("ir",-1,1),new e("as",-1,1),new e("adas",47,1),new e("idas",47,1),new e("ias",47,1),new e("arias",50,1),new e("erias",50,1),new e("irias",50,1),new e("aras",47,1),new e("eras",47,1),new e("iras",47,1),new e("avas",47,1),new e("es",-1,1),new e("ardes",58,1),new e("erdes",58,1),new e("irdes",58,1),new e("ares",58,1),new e("eres",58,1),new e("ires",58,1),new e("asses",58,1),new e("esses",58,1),new e("isses",58,1),new e("astes",58,1),new e("estes",58,1),new e("istes",58,1),new e("is",-1,1),new e("ais",71,1),new e("eis",71,1),new e("areis",73,1),new e("ereis",73,1),new e("ireis",73,1),new e("áreis",73,1),new e("éreis",73,1),new e("íreis",73,1),new e("ásseis",73,1),new e("ésseis",73,1),new e("ísseis",73,1),new e("áveis",73,1),new e("íeis",73,1),new e("aríeis",84,1),new e("eríeis",84,1),new e("iríeis",84,1),new e("ados",-1,1),new e("idos",-1,1),new e("amos",-1,1),new e("áramos",90,1),new e("éramos",90,1),new e("íramos",90,1),new e("ávamos",90,1),new e("íamos",90,1),new e("aríamos",95,1),new e("eríamos",95,1),new e("iríamos",95,1),new e("emos",-1,1),new e("aremos",99,1),new e("eremos",99,1),new e("iremos",99,1),new e("ássemos",99,1),new e("êssemos",99,1),new e("íssemos",99,1),new e("imos",-1,1),new e("armos",-1,1),new e("ermos",-1,1),new e("irmos",-1,1),new e("ámos",-1,1),new e("arás",-1,1),new e("erás",-1,1),new e("irás",-1,1),new e("eu",-1,1),new e("iu",-1,1),new e("ou",-1,1),new e("ará",-1,1),new e("erá",-1,1),new e("irá",-1,1)],c=[new e("a",-1,1),new e("i",-1,1),new e("o",-1,1),new e("os",-1,1),new e("á",-1,1),new e("í",-1,1),new e("ó",-1,1)],l=[new e("e",-1,1),new e("ç",-1,2),new e("é",-1,1),new e("ê",-1,1)],f=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],d=new W;function p(){if(!d.out_grouping(f,97,250))return 1;for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return 1;d.cursor++}}function v(){var e,r=d.cursor;if(d.in_grouping(f,97,250))if(e=d.cursor,p()){if(d.cursor=e,function(){if(d.in_grouping(f,97,250))for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return;d.cursor++}return t=d.cursor,1}())return}else t=d.cursor;if(d.cursor=r,d.out_grouping(f,97,250)){if(e=d.cursor,p()){if(d.cursor=e,!d.in_grouping(f,97,250)||d.cursor>=d.limit)return;d.cursor++}t=d.cursor}}function _(){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return;d.cursor++}for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return;d.cursor++}return 1}function h(){return t<=d.cursor}function b(){return o<=d.cursor}function g(){var e;if(d.ket=d.cursor,e=d.find_among_b(w,45)){switch(d.bra=d.cursor,e){case 1:if(!b())return;d.slice_del();break;case 2:if(!b())return;d.slice_from("log");break;case 3:if(!b())return;d.slice_from("u");break;case 4:if(!b())return;d.slice_from("ente");break;case 5:if(!(i<=d.cursor))return;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(r,4))&&(d.bra=d.cursor,b())&&(d.slice_del(),1==e)&&(d.ket=d.cursor,d.eq_s_b(2,"at"))&&(d.bra=d.cursor,b())&&d.slice_del();break;case 6:if(!b())return;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(s,3))&&(d.bra=d.cursor,1==e)&&b()&&d.slice_del();break;case 7:if(!b())return;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(n,3))&&(d.bra=d.cursor,1==e)&&b()&&d.slice_del();break;case 8:if(!b())return;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,b())&&d.slice_del();break;case 9:if(!h()||!d.eq_s_b(1,"e"))return;d.slice_from("ir")}return 1}}function k(e,r){if(d.eq_s_b(1,e)){d.bra=d.cursor;e=d.limit-d.cursor;if(d.eq_s_b(1,r))return d.cursor=d.limit-e,void(h()&&d.slice_del())}return 1}function q(){var e;g()||(d.cursor=d.limit,function(){var e,r;if(d.cursor>=t){if(r=d.limit_backward,d.limit_backward=t,d.ket=d.cursor,e=d.find_among_b(m,120))return d.bra=d.cursor,1==e&&d.slice_del(),d.limit_backward=r,1;d.limit_backward=r}}())?(d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,"i")&&(d.bra=d.cursor,d.eq_s_b(1,"c"))&&(d.cursor=d.limit,h())&&d.slice_del()):(d.cursor=d.limit,d.ket=d.cursor,(e=d.find_among_b(c,7))&&(d.bra=d.cursor,1==e)&&h()&&d.slice_del())}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){for(var e,r,s,n=d.cursor;;){if(d.bra=d.cursor,e=d.find_among(a,3))switch(d.ket=d.cursor,e){case 1:d.slice_from("a~");continue;case 2:d.slice_from("o~");continue;case 3:if(!(d.cursor>=d.limit)){d.cursor++;continue}}break}if(d.cursor=n,r=d.cursor,t=d.limit,o=i=t,v(),d.cursor=r,_()&&(i=d.cursor,_())&&(o=d.cursor),d.limit_backward=n,d.cursor=d.limit,q(),d.cursor=d.limit,d.ket=d.cursor,r=d.find_among_b(l,4))switch(d.bra=d.cursor,r){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.limit,d.cursor,k("u","g"))&&k("i","c");break;case 2:d.slice_from("c")}for(d.cursor=d.limit_backward;;){if(d.bra=d.cursor,s=d.find_among(u,3))switch(d.ket=d.cursor,s){case 1:d.slice_from("ã");continue;case 2:d.slice_from("õ");continue;case 3:if(!(d.cursor>=d.limit)){d.cursor++;continue}}break}return!0}},function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}),r.Pipeline.registerFunction(r.pt.stemmer,"stemmer-pt"),r.pt.stopWordFilter=function(e){if(-1===r.pt.stopWordFilter.stopWords.indexOf(e))return e},r.pt.stopWordFilter.stopWords=new r.SortedSet,r.pt.stopWordFilter.stopWords.length=204,r.pt.stopWordFilter.stopWords.elements=" a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" "),r.Pipeline.registerFunction(r.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/js/lunr.ro.js b/js/lunr.ro.js new file mode 100644 index 0000000..845497f --- /dev/null +++ b/js/lunr.ro.js @@ -0,0 +1,554 @@ +/*! + * Lunr languages, `Romanian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.ro = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.ro.trimmer, + lunr.ro.stopWordFilter, + lunr.ro.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.ro.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.ro.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ro.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.ro.trimmer, 'trimmer-ro'); + + /* lunr stemmer function */ + lunr.ro.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function RomanianStemmer() { + var a_0 = [new Among("", -1, 3), new Among("I", 0, 1), new Among("U", 0, 2)], + a_1 = [ + new Among("ea", -1, 3), new Among("a\u0163ia", -1, 7), + new Among("aua", -1, 2), new Among("iua", -1, 4), + new Among("a\u0163ie", -1, 7), new Among("ele", -1, 3), + new Among("ile", -1, 5), new Among("iile", 6, 4), + new Among("iei", -1, 4), new Among("atei", -1, 6), + new Among("ii", -1, 4), new Among("ului", -1, 1), + new Among("ul", -1, 1), new Among("elor", -1, 3), + new Among("ilor", -1, 4), new Among("iilor", 14, 4) + ], + a_2 = [ + new Among("icala", -1, 4), new Among("iciva", -1, 4), + new Among("ativa", -1, 5), new Among("itiva", -1, 6), + new Among("icale", -1, 4), new Among("a\u0163iune", -1, 5), + new Among("i\u0163iune", -1, 6), new Among("atoare", -1, 5), + new Among("itoare", -1, 6), new Among("\u0103toare", -1, 5), + new Among("icitate", -1, 4), new Among("abilitate", -1, 1), + new Among("ibilitate", -1, 2), new Among("ivitate", -1, 3), + new Among("icive", -1, 4), new Among("ative", -1, 5), + new Among("itive", -1, 6), new Among("icali", -1, 4), + new Among("atori", -1, 5), new Among("icatori", 18, 4), + new Among("itori", -1, 6), new Among("\u0103tori", -1, 5), + new Among("icitati", -1, 4), new Among("abilitati", -1, 1), + new Among("ivitati", -1, 3), new Among("icivi", -1, 4), + new Among("ativi", -1, 5), new Among("itivi", -1, 6), + new Among("icit\u0103i", -1, 4), new Among("abilit\u0103i", -1, 1), + new Among("ivit\u0103i", -1, 3), + new Among("icit\u0103\u0163i", -1, 4), + new Among("abilit\u0103\u0163i", -1, 1), + new Among("ivit\u0103\u0163i", -1, 3), new Among("ical", -1, 4), + new Among("ator", -1, 5), new Among("icator", 35, 4), + new Among("itor", -1, 6), new Among("\u0103tor", -1, 5), + new Among("iciv", -1, 4), new Among("ativ", -1, 5), + new Among("itiv", -1, 6), new Among("ical\u0103", -1, 4), + new Among("iciv\u0103", -1, 4), new Among("ativ\u0103", -1, 5), + new Among("itiv\u0103", -1, 6) + ], + a_3 = [new Among("ica", -1, 1), + new Among("abila", -1, 1), new Among("ibila", -1, 1), + new Among("oasa", -1, 1), new Among("ata", -1, 1), + new Among("ita", -1, 1), new Among("anta", -1, 1), + new Among("ista", -1, 3), new Among("uta", -1, 1), + new Among("iva", -1, 1), new Among("ic", -1, 1), + new Among("ice", -1, 1), new Among("abile", -1, 1), + new Among("ibile", -1, 1), new Among("isme", -1, 3), + new Among("iune", -1, 2), new Among("oase", -1, 1), + new Among("ate", -1, 1), new Among("itate", 17, 1), + new Among("ite", -1, 1), new Among("ante", -1, 1), + new Among("iste", -1, 3), new Among("ute", -1, 1), + new Among("ive", -1, 1), new Among("ici", -1, 1), + new Among("abili", -1, 1), new Among("ibili", -1, 1), + new Among("iuni", -1, 2), new Among("atori", -1, 1), + new Among("osi", -1, 1), new Among("ati", -1, 1), + new Among("itati", 30, 1), new Among("iti", -1, 1), + new Among("anti", -1, 1), new Among("isti", -1, 3), + new Among("uti", -1, 1), new Among("i\u015Fti", -1, 3), + new Among("ivi", -1, 1), new Among("it\u0103i", -1, 1), + new Among("o\u015Fi", -1, 1), new Among("it\u0103\u0163i", -1, 1), + new Among("abil", -1, 1), new Among("ibil", -1, 1), + new Among("ism", -1, 3), new Among("ator", -1, 1), + new Among("os", -1, 1), new Among("at", -1, 1), + new Among("it", -1, 1), new Among("ant", -1, 1), + new Among("ist", -1, 3), new Among("ut", -1, 1), + new Among("iv", -1, 1), new Among("ic\u0103", -1, 1), + new Among("abil\u0103", -1, 1), new Among("ibil\u0103", -1, 1), + new Among("oas\u0103", -1, 1), new Among("at\u0103", -1, 1), + new Among("it\u0103", -1, 1), new Among("ant\u0103", -1, 1), + new Among("ist\u0103", -1, 3), new Among("ut\u0103", -1, 1), + new Among("iv\u0103", -1, 1) + ], + a_4 = [new Among("ea", -1, 1), + new Among("ia", -1, 1), new Among("esc", -1, 1), + new Among("\u0103sc", -1, 1), new Among("ind", -1, 1), + new Among("\u00E2nd", -1, 1), new Among("are", -1, 1), + new Among("ere", -1, 1), new Among("ire", -1, 1), + new Among("\u00E2re", -1, 1), new Among("se", -1, 2), + new Among("ase", 10, 1), new Among("sese", 10, 2), + new Among("ise", 10, 1), new Among("use", 10, 1), + new Among("\u00E2se", 10, 1), new Among("e\u015Fte", -1, 1), + new Among("\u0103\u015Fte", -1, 1), new Among("eze", -1, 1), + new Among("ai", -1, 1), new Among("eai", 19, 1), + new Among("iai", 19, 1), new Among("sei", -1, 2), + new Among("e\u015Fti", -1, 1), new Among("\u0103\u015Fti", -1, 1), + new Among("ui", -1, 1), new Among("ezi", -1, 1), + new Among("\u00E2i", -1, 1), new Among("a\u015Fi", -1, 1), + new Among("se\u015Fi", -1, 2), new Among("ase\u015Fi", 29, 1), + new Among("sese\u015Fi", 29, 2), new Among("ise\u015Fi", 29, 1), + new Among("use\u015Fi", 29, 1), + new Among("\u00E2se\u015Fi", 29, 1), new Among("i\u015Fi", -1, 1), + new Among("u\u015Fi", -1, 1), new Among("\u00E2\u015Fi", -1, 1), + new Among("a\u0163i", -1, 2), new Among("ea\u0163i", 38, 1), + new Among("ia\u0163i", 38, 1), new Among("e\u0163i", -1, 2), + new Among("i\u0163i", -1, 2), new Among("\u00E2\u0163i", -1, 2), + new Among("ar\u0103\u0163i", -1, 1), + new Among("ser\u0103\u0163i", -1, 2), + new Among("aser\u0103\u0163i", 45, 1), + new Among("seser\u0103\u0163i", 45, 2), + new Among("iser\u0103\u0163i", 45, 1), + new Among("user\u0103\u0163i", 45, 1), + new Among("\u00E2ser\u0103\u0163i", 45, 1), + new Among("ir\u0103\u0163i", -1, 1), + new Among("ur\u0103\u0163i", -1, 1), + new Among("\u00E2r\u0103\u0163i", -1, 1), new Among("am", -1, 1), + new Among("eam", 54, 1), new Among("iam", 54, 1), + new Among("em", -1, 2), new Among("asem", 57, 1), + new Among("sesem", 57, 2), new Among("isem", 57, 1), + new Among("usem", 57, 1), new Among("\u00E2sem", 57, 1), + new Among("im", -1, 2), new Among("\u00E2m", -1, 2), + new Among("\u0103m", -1, 2), new Among("ar\u0103m", 65, 1), + new Among("ser\u0103m", 65, 2), new Among("aser\u0103m", 67, 1), + new Among("seser\u0103m", 67, 2), new Among("iser\u0103m", 67, 1), + new Among("user\u0103m", 67, 1), + new Among("\u00E2ser\u0103m", 67, 1), + new Among("ir\u0103m", 65, 1), new Among("ur\u0103m", 65, 1), + new Among("\u00E2r\u0103m", 65, 1), new Among("au", -1, 1), + new Among("eau", 76, 1), new Among("iau", 76, 1), + new Among("indu", -1, 1), new Among("\u00E2ndu", -1, 1), + new Among("ez", -1, 1), new Among("easc\u0103", -1, 1), + new Among("ar\u0103", -1, 1), new Among("ser\u0103", -1, 2), + new Among("aser\u0103", 84, 1), new Among("seser\u0103", 84, 2), + new Among("iser\u0103", 84, 1), new Among("user\u0103", 84, 1), + new Among("\u00E2ser\u0103", 84, 1), new Among("ir\u0103", -1, 1), + new Among("ur\u0103", -1, 1), new Among("\u00E2r\u0103", -1, 1), + new Among("eaz\u0103", -1, 1) + ], + a_5 = [new Among("a", -1, 1), + new Among("e", -1, 1), new Among("ie", 1, 1), + new Among("i", -1, 1), new Among("\u0103", -1, 1) + ], + g_v = [17, 65, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 4 + ], + B_standard_suffix_removed, I_p2, I_p1, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function habr1(c1, c2) { + if (sbp.eq_s(1, c1)) { + sbp.ket = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 259)) + sbp.slice_from(c2); + } + } + + function r_prelude() { + var v_1, v_2; + while (true) { + v_1 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 259)) { + v_2 = sbp.cursor; + sbp.bra = v_2; + habr1("u", "U"); + sbp.cursor = v_2; + habr1("i", "I"); + } + sbp.cursor = v_1; + if (sbp.cursor >= sbp.limit) { + break; + } + sbp.cursor++; + } + } + + function habr2() { + if (sbp.out_grouping(g_v, 97, 259)) { + while (!sbp.in_grouping(g_v, 97, 259)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + return false; + } + return true; + } + + function habr3() { + if (sbp.in_grouping(g_v, 97, 259)) { + while (!sbp.out_grouping(g_v, 97, 259)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + } + return false; + } + + function habr4() { + var v_1 = sbp.cursor, + v_2, v_3; + if (sbp.in_grouping(g_v, 97, 259)) { + v_2 = sbp.cursor; + if (habr2()) { + sbp.cursor = v_2; + if (!habr3()) { + I_pV = sbp.cursor; + return; + } + } else { + I_pV = sbp.cursor; + return; + } + } + sbp.cursor = v_1; + if (sbp.out_grouping(g_v, 97, 259)) { + v_3 = sbp.cursor; + if (habr2()) { + sbp.cursor = v_3; + if (sbp.in_grouping(g_v, 97, 259) && sbp.cursor < sbp.limit) + sbp.cursor++; + } + I_pV = sbp.cursor; + } + } + + function habr5() { + while (!sbp.in_grouping(g_v, 97, 259)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 259)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function r_mark_regions() { + var v_1 = sbp.cursor; + I_pV = sbp.limit; + I_p1 = I_pV; + I_p2 = I_pV; + habr4(); + sbp.cursor = v_1; + if (habr5()) { + I_p1 = sbp.cursor; + if (habr5()) + I_p2 = sbp.cursor; + } + } + + function r_postlude() { + var among_var; + while (true) { + sbp.bra = sbp.cursor; + among_var = sbp.find_among(a_0, 3); + if (among_var) { + sbp.ket = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("i"); + continue; + case 2: + sbp.slice_from("u"); + continue; + case 3: + if (sbp.cursor >= sbp.limit) + break; + sbp.cursor++; + continue; + } + } + break; + } + } + + function r_RV() { + return I_pV <= sbp.cursor; + } + + function r_R1() { + return I_p1 <= sbp.cursor; + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function r_step_0() { + var among_var, v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_1, 16); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + sbp.slice_from("a"); + break; + case 3: + sbp.slice_from("e"); + break; + case 4: + sbp.slice_from("i"); + break; + case 5: + v_1 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(2, "ab")) { + sbp.cursor = sbp.limit - v_1; + sbp.slice_from("i"); + } + break; + case 6: + sbp.slice_from("at"); + break; + case 7: + sbp.slice_from("a\u0163i"); + break; + } + } + } + } + + function r_combo_suffix() { + var among_var, v_1 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 46); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R1()) { + switch (among_var) { + case 1: + sbp.slice_from("abil"); + break; + case 2: + sbp.slice_from("ibil"); + break; + case 3: + sbp.slice_from("iv"); + break; + case 4: + sbp.slice_from("ic"); + break; + case 5: + sbp.slice_from("at"); + break; + case 6: + sbp.slice_from("it"); + break; + } + B_standard_suffix_removed = true; + sbp.cursor = sbp.limit - v_1; + return true; + } + } + return false; + } + + function r_standard_suffix() { + var among_var, v_1; + B_standard_suffix_removed = false; + while (true) { + v_1 = sbp.limit - sbp.cursor; + if (!r_combo_suffix()) { + sbp.cursor = sbp.limit - v_1; + break; + } + } + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_3, 62); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2()) { + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + if (sbp.eq_s_b(1, "\u0163")) { + sbp.bra = sbp.cursor; + sbp.slice_from("t"); + } + break; + case 3: + sbp.slice_from("ist"); + break; + } + B_standard_suffix_removed = true; + } + } + } + + function r_verb_suffix() { + var among_var, v_1, v_2; + if (sbp.cursor >= I_pV) { + v_1 = sbp.limit_backward; + sbp.limit_backward = I_pV; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_4, 94); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + v_2 = sbp.limit - sbp.cursor; + if (!sbp.out_grouping_b(g_v, 97, 259)) { + sbp.cursor = sbp.limit - v_2; + if (!sbp.eq_s_b(1, "u")) + break; + } + case 2: + sbp.slice_del(); + break; + } + } + sbp.limit_backward = v_1; + } + } + + function r_vowel_suffix() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_5, 5); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_RV() && among_var == 1) + sbp.slice_del(); + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_prelude(); + sbp.cursor = v_1; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_step_0(); + sbp.cursor = sbp.limit; + r_standard_suffix(); + sbp.cursor = sbp.limit; + if (!B_standard_suffix_removed) { + sbp.cursor = sbp.limit; + r_verb_suffix(); + sbp.cursor = sbp.limit; + } + r_vowel_suffix(); + sbp.cursor = sbp.limit_backward; + r_postlude(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.ro.stemmer, 'stemmer-ro'); + + /* stop word filter function */ + lunr.ro.stopWordFilter = function(token) { + if (lunr.ro.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.ro.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.ro.stopWordFilter.stopWords.length = 282; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.ro.stopWordFilter.stopWords.elements = ' acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie'.split(' '); + + lunr.Pipeline.registerFunction(lunr.ro.stopWordFilter, 'stopWordFilter-ro'); + }; +})) \ No newline at end of file diff --git a/js/lunr.ro.min.js b/js/lunr.ro.min.js new file mode 100644 index 0000000..0f38816 --- /dev/null +++ b/js/lunr.ro.min.js @@ -0,0 +1 @@ +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,a,r;i.ro=function(){this.pipeline.reset(),this.pipeline.add(i.ro.trimmer,i.ro.stopWordFilter,i.ro.stemmer)},i.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.ro.trimmer=i.trimmerSupport.generateTrimmer(i.ro.wordCharacters),i.Pipeline.registerFunction(i.ro.trimmer,"trimmer-ro"),i.ro.stemmer=(e=i.stemmerSupport.Among,a=i.stemmerSupport.SnowballProgram,r=new function(){var s,c,u,w,m=[new e("",-1,3),new e("I",0,1),new e("U",0,2)],l=[new e("ea",-1,3),new e("aţia",-1,7),new e("aua",-1,2),new e("iua",-1,4),new e("aţie",-1,7),new e("ele",-1,3),new e("ile",-1,5),new e("iile",6,4),new e("iei",-1,4),new e("atei",-1,6),new e("ii",-1,4),new e("ului",-1,1),new e("ul",-1,1),new e("elor",-1,3),new e("ilor",-1,4),new e("iilor",14,4)],r=[new e("icala",-1,4),new e("iciva",-1,4),new e("ativa",-1,5),new e("itiva",-1,6),new e("icale",-1,4),new e("aţiune",-1,5),new e("iţiune",-1,6),new e("atoare",-1,5),new e("itoare",-1,6),new e("ătoare",-1,5),new e("icitate",-1,4),new e("abilitate",-1,1),new e("ibilitate",-1,2),new e("ivitate",-1,3),new e("icive",-1,4),new e("ative",-1,5),new e("itive",-1,6),new e("icali",-1,4),new e("atori",-1,5),new e("icatori",18,4),new e("itori",-1,6),new e("ători",-1,5),new e("icitati",-1,4),new e("abilitati",-1,1),new e("ivitati",-1,3),new e("icivi",-1,4),new e("ativi",-1,5),new e("itivi",-1,6),new e("icităi",-1,4),new e("abilităi",-1,1),new e("ivităi",-1,3),new e("icităţi",-1,4),new e("abilităţi",-1,1),new e("ivităţi",-1,3),new e("ical",-1,4),new e("ator",-1,5),new e("icator",35,4),new e("itor",-1,6),new e("ător",-1,5),new e("iciv",-1,4),new e("ativ",-1,5),new e("itiv",-1,6),new e("icală",-1,4),new e("icivă",-1,4),new e("ativă",-1,5),new e("itivă",-1,6)],n=[new e("ica",-1,1),new e("abila",-1,1),new e("ibila",-1,1),new e("oasa",-1,1),new e("ata",-1,1),new e("ita",-1,1),new e("anta",-1,1),new e("ista",-1,3),new e("uta",-1,1),new e("iva",-1,1),new e("ic",-1,1),new e("ice",-1,1),new e("abile",-1,1),new e("ibile",-1,1),new e("isme",-1,3),new e("iune",-1,2),new e("oase",-1,1),new e("ate",-1,1),new e("itate",17,1),new e("ite",-1,1),new e("ante",-1,1),new e("iste",-1,3),new e("ute",-1,1),new e("ive",-1,1),new e("ici",-1,1),new e("abili",-1,1),new e("ibili",-1,1),new e("iuni",-1,2),new e("atori",-1,1),new e("osi",-1,1),new e("ati",-1,1),new e("itati",30,1),new e("iti",-1,1),new e("anti",-1,1),new e("isti",-1,3),new e("uti",-1,1),new e("işti",-1,3),new e("ivi",-1,1),new e("ităi",-1,1),new e("oşi",-1,1),new e("ităţi",-1,1),new e("abil",-1,1),new e("ibil",-1,1),new e("ism",-1,3),new e("ator",-1,1),new e("os",-1,1),new e("at",-1,1),new e("it",-1,1),new e("ant",-1,1),new e("ist",-1,3),new e("ut",-1,1),new e("iv",-1,1),new e("ică",-1,1),new e("abilă",-1,1),new e("ibilă",-1,1),new e("oasă",-1,1),new e("ată",-1,1),new e("ită",-1,1),new e("antă",-1,1),new e("istă",-1,3),new e("ută",-1,1),new e("ivă",-1,1)],f=[new e("ea",-1,1),new e("ia",-1,1),new e("esc",-1,1),new e("ăsc",-1,1),new e("ind",-1,1),new e("ând",-1,1),new e("are",-1,1),new e("ere",-1,1),new e("ire",-1,1),new e("âre",-1,1),new e("se",-1,2),new e("ase",10,1),new e("sese",10,2),new e("ise",10,1),new e("use",10,1),new e("âse",10,1),new e("eşte",-1,1),new e("ăşte",-1,1),new e("eze",-1,1),new e("ai",-1,1),new e("eai",19,1),new e("iai",19,1),new e("sei",-1,2),new e("eşti",-1,1),new e("ăşti",-1,1),new e("ui",-1,1),new e("ezi",-1,1),new e("âi",-1,1),new e("aşi",-1,1),new e("seşi",-1,2),new e("aseşi",29,1),new e("seseşi",29,2),new e("iseşi",29,1),new e("useşi",29,1),new e("âseşi",29,1),new e("işi",-1,1),new e("uşi",-1,1),new e("âşi",-1,1),new e("aţi",-1,2),new e("eaţi",38,1),new e("iaţi",38,1),new e("eţi",-1,2),new e("iţi",-1,2),new e("âţi",-1,2),new e("arăţi",-1,1),new e("serăţi",-1,2),new e("aserăţi",45,1),new e("seserăţi",45,2),new e("iserăţi",45,1),new e("userăţi",45,1),new e("âserăţi",45,1),new e("irăţi",-1,1),new e("urăţi",-1,1),new e("ârăţi",-1,1),new e("am",-1,1),new e("eam",54,1),new e("iam",54,1),new e("em",-1,2),new e("asem",57,1),new e("sesem",57,2),new e("isem",57,1),new e("usem",57,1),new e("âsem",57,1),new e("im",-1,2),new e("âm",-1,2),new e("ăm",-1,2),new e("arăm",65,1),new e("serăm",65,2),new e("aserăm",67,1),new e("seserăm",67,2),new e("iserăm",67,1),new e("userăm",67,1),new e("âserăm",67,1),new e("irăm",65,1),new e("urăm",65,1),new e("ârăm",65,1),new e("au",-1,1),new e("eau",76,1),new e("iau",76,1),new e("indu",-1,1),new e("ându",-1,1),new e("ez",-1,1),new e("ească",-1,1),new e("ară",-1,1),new e("seră",-1,2),new e("aseră",84,1),new e("seseră",84,2),new e("iseră",84,1),new e("useră",84,1),new e("âseră",84,1),new e("iră",-1,1),new e("ură",-1,1),new e("âră",-1,1),new e("ează",-1,1)],i=[new e("a",-1,1),new e("e",-1,1),new e("ie",1,1),new e("i",-1,1),new e("ă",-1,1)],d=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],p=new a;function b(e,i){p.eq_s(1,e)&&(p.ket=p.cursor,p.in_grouping(d,97,259))&&p.slice_from(i)}function t(){if(!p.out_grouping(d,97,259))return 1;for(;!p.in_grouping(d,97,259);){if(p.cursor>=p.limit)return 1;p.cursor++}}function v(){var e,i=p.cursor;if(p.in_grouping(d,97,259)){if(e=p.cursor,!t())return void(w=p.cursor);if(p.cursor=e,!function(){if(p.in_grouping(d,97,259))for(;!p.out_grouping(d,97,259);){if(p.cursor>=p.limit)return 1;p.cursor++}}())return void(w=p.cursor)}p.cursor=i,p.out_grouping(d,97,259)&&(e=p.cursor,t()&&(p.cursor=e,p.in_grouping(d,97,259))&&p.cursor=p.limit)return;p.cursor++}for(;!p.out_grouping(d,97,259);){if(p.cursor>=p.limit)return;p.cursor++}return 1}function g(){return u<=p.cursor}function k(){var e,i;for(s=!1;;)if(i=p.limit-p.cursor,!function(){var e,i=p.limit-p.cursor;if(p.ket=p.cursor,(e=p.find_among_b(r,46))&&(p.bra=p.cursor,g())){switch(e){case 1:p.slice_from("abil");break;case 2:p.slice_from("ibil");break;case 3:p.slice_from("iv");break;case 4:p.slice_from("ic");break;case 5:p.slice_from("at");break;case 6:p.slice_from("it")}return s=!0,p.cursor=p.limit-i,1}}()){p.cursor=p.limit-i;break}if(p.ket=p.cursor,(e=p.find_among_b(n,62))&&(p.bra=p.cursor,c<=p.cursor)){switch(e){case 1:p.slice_del();break;case 2:p.eq_s_b(1,"ţ")&&(p.bra=p.cursor,p.slice_from("t"));break;case 3:p.slice_from("ist")}s=!0}}function h(){var e;p.ket=p.cursor,(e=p.find_among_b(i,5))&&(p.bra=p.cursor,w<=p.cursor)&&1==e&&p.slice_del()}this.setCurrent=function(e){p.setCurrent(e)},this.getCurrent=function(){return p.getCurrent()},this.stem=function(){for(var e,i,r,n,t,a,o=p.cursor;e=p.cursor,p.in_grouping(d,97,259)&&(i=p.cursor,p.bra=i,b("u","U"),p.cursor=i,b("i","I")),p.cursor=e,!(p.cursor>=p.limit);)p.cursor++;if(p.cursor=o,n=p.cursor,w=p.limit,c=u=w,v(),p.cursor=n,_()&&(u=p.cursor,_())&&(c=p.cursor),p.limit_backward=o,p.cursor=p.limit,p.ket=p.cursor,(n=p.find_among_b(l,16))&&(p.bra=p.cursor,g()))switch(n){case 1:p.slice_del();break;case 2:p.slice_from("a");break;case 3:p.slice_from("e");break;case 4:p.slice_from("i");break;case 5:r=p.limit-p.cursor,p.eq_s_b(2,"ab")||(p.cursor=p.limit-r,p.slice_from("i"));break;case 6:p.slice_from("at");break;case 7:p.slice_from("aţi")}if(p.cursor=p.limit,k(),p.cursor=p.limit,!s){if(p.cursor=p.limit,p.cursor>=w){if(o=p.limit_backward,p.limit_backward=w,p.ket=p.cursor,n=p.find_among_b(f,94))switch(p.bra=p.cursor,n){case 1:if(t=p.limit-p.cursor,!p.out_grouping_b(d,97,259)&&(p.cursor=p.limit-t,!p.eq_s_b(1,"u")))break;case 2:p.slice_del()}p.limit_backward=o}p.cursor=p.limit}for(h(),p.cursor=p.limit_backward;;){if(p.bra=p.cursor,a=p.find_among(m,3))switch(p.ket=p.cursor,a){case 1:p.slice_from("i");continue;case 2:p.slice_from("u");continue;case 3:if(!(p.cursor>=p.limit)){p.cursor++;continue}}break}return!0}},function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}),i.Pipeline.registerFunction(i.ro.stemmer,"stemmer-ro"),i.ro.stopWordFilter=function(e){if(-1===i.ro.stopWordFilter.stopWords.indexOf(e))return e},i.ro.stopWordFilter.stopWords=new i.SortedSet,i.ro.stopWordFilter.stopWords.length=282,i.ro.stopWordFilter.stopWords.elements=" acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" "),i.Pipeline.registerFunction(i.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/js/lunr.ru.js b/js/lunr.ru.js new file mode 100644 index 0000000..7d57236 --- /dev/null +++ b/js/lunr.ru.js @@ -0,0 +1,387 @@ +/*! + * Lunr languages, `Russian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.ru = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.ru.trimmer, + lunr.ru.stopWordFilter, + lunr.ru.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.ru.wordCharacters = "\u0400-\u0484\u0487-\u052F\u1D2B\u1D78\u2DE0-\u2DFF\uA640-\uA69F\uFE2E\uFE2F"; + lunr.ru.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ru.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.ru.trimmer, 'trimmer-ru'); + + /* lunr stemmer function */ + lunr.ru.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function RussianStemmer() { + var a_0 = [new Among("\u0432", -1, 1), new Among("\u0438\u0432", 0, 2), + new Among("\u044B\u0432", 0, 2), + new Among("\u0432\u0448\u0438", -1, 1), + new Among("\u0438\u0432\u0448\u0438", 3, 2), + new Among("\u044B\u0432\u0448\u0438", 3, 2), + new Among("\u0432\u0448\u0438\u0441\u044C", -1, 1), + new Among("\u0438\u0432\u0448\u0438\u0441\u044C", 6, 2), + new Among("\u044B\u0432\u0448\u0438\u0441\u044C", 6, 2) + ], + a_1 = [ + new Among("\u0435\u0435", -1, 1), new Among("\u0438\u0435", -1, 1), + new Among("\u043E\u0435", -1, 1), new Among("\u044B\u0435", -1, 1), + new Among("\u0438\u043C\u0438", -1, 1), + new Among("\u044B\u043C\u0438", -1, 1), + new Among("\u0435\u0439", -1, 1), new Among("\u0438\u0439", -1, 1), + new Among("\u043E\u0439", -1, 1), new Among("\u044B\u0439", -1, 1), + new Among("\u0435\u043C", -1, 1), new Among("\u0438\u043C", -1, 1), + new Among("\u043E\u043C", -1, 1), new Among("\u044B\u043C", -1, 1), + new Among("\u0435\u0433\u043E", -1, 1), + new Among("\u043E\u0433\u043E", -1, 1), + new Among("\u0435\u043C\u0443", -1, 1), + new Among("\u043E\u043C\u0443", -1, 1), + new Among("\u0438\u0445", -1, 1), new Among("\u044B\u0445", -1, 1), + new Among("\u0435\u044E", -1, 1), new Among("\u043E\u044E", -1, 1), + new Among("\u0443\u044E", -1, 1), new Among("\u044E\u044E", -1, 1), + new Among("\u0430\u044F", -1, 1), new Among("\u044F\u044F", -1, 1) + ], + a_2 = [ + new Among("\u0435\u043C", -1, 1), new Among("\u043D\u043D", -1, 1), + new Among("\u0432\u0448", -1, 1), + new Among("\u0438\u0432\u0448", 2, 2), + new Among("\u044B\u0432\u0448", 2, 2), new Among("\u0449", -1, 1), + new Among("\u044E\u0449", 5, 1), + new Among("\u0443\u044E\u0449", 6, 2) + ], + a_3 = [ + new Among("\u0441\u044C", -1, 1), new Among("\u0441\u044F", -1, 1) + ], + a_4 = [ + new Among("\u043B\u0430", -1, 1), + new Among("\u0438\u043B\u0430", 0, 2), + new Among("\u044B\u043B\u0430", 0, 2), + new Among("\u043D\u0430", -1, 1), + new Among("\u0435\u043D\u0430", 3, 2), + new Among("\u0435\u0442\u0435", -1, 1), + new Among("\u0438\u0442\u0435", -1, 2), + new Among("\u0439\u0442\u0435", -1, 1), + new Among("\u0435\u0439\u0442\u0435", 7, 2), + new Among("\u0443\u0439\u0442\u0435", 7, 2), + new Among("\u043B\u0438", -1, 1), + new Among("\u0438\u043B\u0438", 10, 2), + new Among("\u044B\u043B\u0438", 10, 2), new Among("\u0439", -1, 1), + new Among("\u0435\u0439", 13, 2), new Among("\u0443\u0439", 13, 2), + new Among("\u043B", -1, 1), new Among("\u0438\u043B", 16, 2), + new Among("\u044B\u043B", 16, 2), new Among("\u0435\u043C", -1, 1), + new Among("\u0438\u043C", -1, 2), new Among("\u044B\u043C", -1, 2), + new Among("\u043D", -1, 1), new Among("\u0435\u043D", 22, 2), + new Among("\u043B\u043E", -1, 1), + new Among("\u0438\u043B\u043E", 24, 2), + new Among("\u044B\u043B\u043E", 24, 2), + new Among("\u043D\u043E", -1, 1), + new Among("\u0435\u043D\u043E", 27, 2), + new Among("\u043D\u043D\u043E", 27, 1), + new Among("\u0435\u0442", -1, 1), + new Among("\u0443\u0435\u0442", 30, 2), + new Among("\u0438\u0442", -1, 2), new Among("\u044B\u0442", -1, 2), + new Among("\u044E\u0442", -1, 1), + new Among("\u0443\u044E\u0442", 34, 2), + new Among("\u044F\u0442", -1, 2), new Among("\u043D\u044B", -1, 1), + new Among("\u0435\u043D\u044B", 37, 2), + new Among("\u0442\u044C", -1, 1), + new Among("\u0438\u0442\u044C", 39, 2), + new Among("\u044B\u0442\u044C", 39, 2), + new Among("\u0435\u0448\u044C", -1, 1), + new Among("\u0438\u0448\u044C", -1, 2), new Among("\u044E", -1, 2), + new Among("\u0443\u044E", 44, 2) + ], + a_5 = [ + new Among("\u0430", -1, 1), new Among("\u0435\u0432", -1, 1), + new Among("\u043E\u0432", -1, 1), new Among("\u0435", -1, 1), + new Among("\u0438\u0435", 3, 1), new Among("\u044C\u0435", 3, 1), + new Among("\u0438", -1, 1), new Among("\u0435\u0438", 6, 1), + new Among("\u0438\u0438", 6, 1), + new Among("\u0430\u043C\u0438", 6, 1), + new Among("\u044F\u043C\u0438", 6, 1), + new Among("\u0438\u044F\u043C\u0438", 10, 1), + new Among("\u0439", -1, 1), new Among("\u0435\u0439", 12, 1), + new Among("\u0438\u0435\u0439", 13, 1), + new Among("\u0438\u0439", 12, 1), new Among("\u043E\u0439", 12, 1), + new Among("\u0430\u043C", -1, 1), new Among("\u0435\u043C", -1, 1), + new Among("\u0438\u0435\u043C", 18, 1), + new Among("\u043E\u043C", -1, 1), new Among("\u044F\u043C", -1, 1), + new Among("\u0438\u044F\u043C", 21, 1), new Among("\u043E", -1, 1), + new Among("\u0443", -1, 1), new Among("\u0430\u0445", -1, 1), + new Among("\u044F\u0445", -1, 1), + new Among("\u0438\u044F\u0445", 26, 1), new Among("\u044B", -1, 1), + new Among("\u044C", -1, 1), new Among("\u044E", -1, 1), + new Among("\u0438\u044E", 30, 1), new Among("\u044C\u044E", 30, 1), + new Among("\u044F", -1, 1), new Among("\u0438\u044F", 33, 1), + new Among("\u044C\u044F", 33, 1) + ], + a_6 = [ + new Among("\u043E\u0441\u0442", -1, 1), + new Among("\u043E\u0441\u0442\u044C", -1, 1) + ], + a_7 = [ + new Among("\u0435\u0439\u0448\u0435", -1, 1), + new Among("\u043D", -1, 2), new Among("\u0435\u0439\u0448", -1, 1), + new Among("\u044C", -1, 3) + ], + g_v = [33, 65, 8, 232], + I_p2, I_pV, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function habr3() { + while (!sbp.in_grouping(g_v, 1072, 1103)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function habr4() { + while (!sbp.out_grouping(g_v, 1072, 1103)) { + if (sbp.cursor >= sbp.limit) + return false; + sbp.cursor++; + } + return true; + } + + function r_mark_regions() { + I_pV = sbp.limit; + I_p2 = I_pV; + if (habr3()) { + I_pV = sbp.cursor; + if (habr4()) + if (habr3()) + if (habr4()) + I_p2 = sbp.cursor; + } + } + + function r_R2() { + return I_p2 <= sbp.cursor; + } + + function habr2(a, n) { + var among_var, v_1; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a, n); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + v_1 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "\u0430")) { + sbp.cursor = sbp.limit - v_1; + if (!sbp.eq_s_b(1, "\u044F")) + return false; + } + case 2: + sbp.slice_del(); + break; + } + return true; + } + return false; + } + + function r_perfective_gerund() { + return habr2(a_0, 9); + } + + function habr1(a, n) { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a, n); + if (among_var) { + sbp.bra = sbp.cursor; + if (among_var == 1) + sbp.slice_del(); + return true; + } + return false; + } + + function r_adjective() { + return habr1(a_1, 26); + } + + function r_adjectival() { + var among_var; + if (r_adjective()) { + habr2(a_2, 8); + return true; + } + return false; + } + + function r_reflexive() { + return habr1(a_3, 2); + } + + function r_verb() { + return habr2(a_4, 46); + } + + function r_noun() { + habr1(a_5, 36); + } + + function r_derivational() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_6, 2); + if (among_var) { + sbp.bra = sbp.cursor; + if (r_R2() && among_var == 1) + sbp.slice_del(); + } + } + + function r_tidy_up() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_7, 4); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (!sbp.eq_s_b(1, "\u043D")) + break; + sbp.bra = sbp.cursor; + case 2: + if (!sbp.eq_s_b(1, "\u043D")) + break; + case 3: + sbp.slice_del(); + break; + } + } + } + this.stem = function() { + r_mark_regions(); + sbp.cursor = sbp.limit; + if (sbp.cursor < I_pV) + return false; + sbp.limit_backward = I_pV; + if (!r_perfective_gerund()) { + sbp.cursor = sbp.limit; + if (!r_reflexive()) + sbp.cursor = sbp.limit; + if (!r_adjectival()) { + sbp.cursor = sbp.limit; + if (!r_verb()) { + sbp.cursor = sbp.limit; + r_noun(); + } + } + } + sbp.cursor = sbp.limit; + sbp.ket = sbp.cursor; + if (sbp.eq_s_b(1, "\u0438")) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + } else + sbp.cursor = sbp.limit; + r_derivational(); + sbp.cursor = sbp.limit; + r_tidy_up(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.ru.stemmer, 'stemmer-ru'); + + /* stop word filter function */ + lunr.ru.stopWordFilter = function(token) { + if (lunr.ru.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.ru.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.ru.stopWordFilter.stopWords.length = 422; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.ru.stopWordFilter.stopWords.elements = ' алло без близко более больше будем будет будете будешь будто буду будут будь бы бывает бывь был была были было быть в важная важное важные важный вам вами вас ваш ваша ваше ваши вверх вдали вдруг ведь везде весь вниз внизу во вокруг вон восемнадцатый восемнадцать восемь восьмой вот впрочем времени время все всегда всего всем всеми всему всех всею всю всюду вся всё второй вы г где говорил говорит год года году да давно даже далеко дальше даром два двадцатый двадцать две двенадцатый двенадцать двух девятнадцатый девятнадцать девятый девять действительно дел день десятый десять для до довольно долго должно другая другие других друго другое другой е его ее ей ему если есть еще ещё ею её ж же жизнь за занят занята занято заняты затем зато зачем здесь значит и из или им именно иметь ими имя иногда их к каждая каждое каждые каждый кажется как какая какой кем когда кого ком кому конечно которая которого которой которые который которых кроме кругом кто куда лет ли лишь лучше люди м мало между меля менее меньше меня миллионов мимо мира мне много многочисленная многочисленное многочисленные многочисленный мной мною мог могут мож может можно можхо мои мой мор мочь моя моё мы на наверху над надо назад наиболее наконец нам нами нас начала наш наша наше наши не него недавно недалеко нее ней нельзя нем немного нему непрерывно нередко несколько нет нею неё ни нибудь ниже низко никогда никуда ними них ничего но ну нужно нх о об оба обычно один одиннадцатый одиннадцать однажды однако одного одной около он она они оно опять особенно от отовсюду отсюда очень первый перед по под пожалуйста позже пока пор пора после посреди потом потому почему почти прекрасно при про просто против процентов пятнадцатый пятнадцать пятый пять раз разве рано раньше рядом с сам сама сами самим самими самих само самого самой самом самому саму свое своего своей свои своих свою сеаой себе себя сегодня седьмой сейчас семнадцатый семнадцать семь сих сказал сказала сказать сколько слишком сначала снова со собой собою совсем спасибо стал суть т та так такая также такие такое такой там твой твоя твоё те тебе тебя тем теми теперь тех то тобой тобою тогда того тоже только том тому тот тою третий три тринадцатый тринадцать ту туда тут ты тысяч у уж уже уметь хорошо хотеть хоть хотя хочешь часто чаще чего человек чем чему через четвертый четыре четырнадцатый четырнадцать что чтоб чтобы чуть шестнадцатый шестнадцать шестой шесть эта эти этим этими этих это этого этой этом этому этот эту я а'.split(' '); + + lunr.Pipeline.registerFunction(lunr.ru.stopWordFilter, 'stopWordFilter-ru'); + }; +})) \ No newline at end of file diff --git a/js/lunr.ru.min.js b/js/lunr.ru.min.js new file mode 100644 index 0000000..717c438 --- /dev/null +++ b/js/lunr.ru.min.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(n){if(void 0===n)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===n.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var g,h,r;n.ru=function(){this.pipeline.reset(),this.pipeline.add(n.ru.trimmer,n.ru.stopWordFilter,n.ru.stemmer)},n.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",n.ru.trimmer=n.trimmerSupport.generateTrimmer(n.ru.wordCharacters),n.Pipeline.registerFunction(n.ru.trimmer,"trimmer-ru"),n.ru.stemmer=(g=n.stemmerSupport.Among,h=n.stemmerSupport.SnowballProgram,r=new function(){var n,r,w=[new g("в",-1,1),new g("ив",0,2),new g("ыв",0,2),new g("вши",-1,1),new g("ивши",3,2),new g("ывши",3,2),new g("вшись",-1,1),new g("ившись",6,2),new g("ывшись",6,2)],e=[new g("ее",-1,1),new g("ие",-1,1),new g("ое",-1,1),new g("ые",-1,1),new g("ими",-1,1),new g("ыми",-1,1),new g("ей",-1,1),new g("ий",-1,1),new g("ой",-1,1),new g("ый",-1,1),new g("ем",-1,1),new g("им",-1,1),new g("ом",-1,1),new g("ым",-1,1),new g("его",-1,1),new g("ого",-1,1),new g("ему",-1,1),new g("ому",-1,1),new g("их",-1,1),new g("ых",-1,1),new g("ею",-1,1),new g("ою",-1,1),new g("ую",-1,1),new g("юю",-1,1),new g("ая",-1,1),new g("яя",-1,1)],t=[new g("ем",-1,1),new g("нн",-1,1),new g("вш",-1,1),new g("ивш",2,2),new g("ывш",2,2),new g("щ",-1,1),new g("ющ",5,1),new g("ующ",6,2)],i=[new g("сь",-1,1),new g("ся",-1,1)],o=[new g("ла",-1,1),new g("ила",0,2),new g("ыла",0,2),new g("на",-1,1),new g("ена",3,2),new g("ете",-1,1),new g("ите",-1,2),new g("йте",-1,1),new g("ейте",7,2),new g("уйте",7,2),new g("ли",-1,1),new g("или",10,2),new g("ыли",10,2),new g("й",-1,1),new g("ей",13,2),new g("уй",13,2),new g("л",-1,1),new g("ил",16,2),new g("ыл",16,2),new g("ем",-1,1),new g("им",-1,2),new g("ым",-1,2),new g("н",-1,1),new g("ен",22,2),new g("ло",-1,1),new g("ило",24,2),new g("ыло",24,2),new g("но",-1,1),new g("ено",27,2),new g("нно",27,1),new g("ет",-1,1),new g("ует",30,2),new g("ит",-1,2),new g("ыт",-1,2),new g("ют",-1,1),new g("уют",34,2),new g("ят",-1,2),new g("ны",-1,1),new g("ены",37,2),new g("ть",-1,1),new g("ить",39,2),new g("ыть",39,2),new g("ешь",-1,1),new g("ишь",-1,2),new g("ю",-1,2),new g("ую",44,2)],u=[new g("а",-1,1),new g("ев",-1,1),new g("ов",-1,1),new g("е",-1,1),new g("ие",3,1),new g("ье",3,1),new g("и",-1,1),new g("еи",6,1),new g("ии",6,1),new g("ами",6,1),new g("ями",6,1),new g("иями",10,1),new g("й",-1,1),new g("ей",12,1),new g("ией",13,1),new g("ий",12,1),new g("ой",12,1),new g("ам",-1,1),new g("ем",-1,1),new g("ием",18,1),new g("ом",-1,1),new g("ям",-1,1),new g("иям",21,1),new g("о",-1,1),new g("у",-1,1),new g("ах",-1,1),new g("ях",-1,1),new g("иях",26,1),new g("ы",-1,1),new g("ь",-1,1),new g("ю",-1,1),new g("ию",30,1),new g("ью",30,1),new g("я",-1,1),new g("ия",33,1),new g("ья",33,1)],s=[new g("ост",-1,1),new g("ость",-1,1)],c=[new g("ейше",-1,1),new g("н",-1,2),new g("ейш",-1,1),new g("ь",-1,3)],m=[33,65,8,232],l=new h;function f(){for(;!l.in_grouping(m,1072,1103);){if(l.cursor>=l.limit)return;l.cursor++}return 1}function p(){for(;!l.out_grouping(m,1072,1103);){if(l.cursor>=l.limit)return;l.cursor++}return 1}function d(e,n){var r;if(l.ket=l.cursor,e=l.find_among_b(e,n)){switch(l.bra=l.cursor,e){case 1:if(r=l.limit-l.cursor,!l.eq_s_b(1,"а")&&(l.cursor=l.limit-r,!l.eq_s_b(1,"я")))return!1;case 2:l.slice_del()}return!0}return!1}function a(e,n){return l.ket=l.cursor,!!(e=l.find_among_b(e,n))&&(l.bra=l.cursor,1==e&&l.slice_del(),!0)}function _(){return a(e,26)&&(d(t,8),1)}function b(){var e;l.ket=l.cursor,(e=l.find_among_b(s,2))&&(l.bra=l.cursor,n<=l.cursor)&&1==e&&l.slice_del()}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){if(r=l.limit,n=r,f()&&(r=l.cursor,p())&&f()&&p()&&(n=l.cursor),l.cursor=l.limit,l.cursor= min) { + ch -= min; + if (s[ch >> 3] & (0X1 << (ch & 0X7))) { + this.cursor++; + return true; + } + } + } + return false; + }, + in_grouping_b : function(s, min, max) { + if (this.cursor > this.limit_backward) { + var ch = current.charCodeAt(this.cursor - 1); + if (ch <= max && ch >= min) { + ch -= min; + if (s[ch >> 3] & (0X1 << (ch & 0X7))) { + this.cursor--; + return true; + } + } + } + return false; + }, + out_grouping : function(s, min, max) { + if (this.cursor < this.limit) { + var ch = current.charCodeAt(this.cursor); + if (ch > max || ch < min) { + this.cursor++; + return true; + } + ch -= min; + if (!(s[ch >> 3] & (0X1 << (ch & 0X7)))) { + this.cursor++; + return true; + } + } + return false; + }, + out_grouping_b : function(s, min, max) { + if (this.cursor > this.limit_backward) { + var ch = current.charCodeAt(this.cursor - 1); + if (ch > max || ch < min) { + this.cursor--; + return true; + } + ch -= min; + if (!(s[ch >> 3] & (0X1 << (ch & 0X7)))) { + this.cursor--; + return true; + } + } + return false; + }, + eq_s : function(s_size, s) { + if (this.limit - this.cursor < s_size) + return false; + for (var i = 0; i < s_size; i++) + if (current.charCodeAt(this.cursor + i) != s.charCodeAt(i)) + return false; + this.cursor += s_size; + return true; + }, + eq_s_b : function(s_size, s) { + if (this.cursor - this.limit_backward < s_size) + return false; + for (var i = 0; i < s_size; i++) + if (current.charCodeAt(this.cursor - s_size + i) != s + .charCodeAt(i)) + return false; + this.cursor -= s_size; + return true; + }, + find_among : function(v, v_size) { + var i = 0, j = v_size, c = this.cursor, l = this.limit, common_i = 0, common_j = 0, first_key_inspected = false; + while (true) { + var k = i + ((j - i) >> 1), diff = 0, common = common_i < common_j + ? common_i + : common_j, w = v[k]; + for (var i2 = common; i2 < w.s_size; i2++) { + if (c + common == l) { + diff = -1; + break; + } + diff = current.charCodeAt(c + common) - w.s[i2]; + if (diff) + break; + common++; + } + if (diff < 0) { + j = k; + common_j = common; + } else { + i = k; + common_i = common; + } + if (j - i <= 1) { + if (i > 0 || j == i || first_key_inspected) + break; + first_key_inspected = true; + } + } + while (true) { + var w = v[i]; + if (common_i >= w.s_size) { + this.cursor = c + w.s_size; + if (!w.method) + return w.result; + var res = w.method(); + this.cursor = c + w.s_size; + if (res) + return w.result; + } + i = w.substring_i; + if (i < 0) + return 0; + } + }, + find_among_b : function(v, v_size) { + var i = 0, j = v_size, c = this.cursor, lb = this.limit_backward, common_i = 0, common_j = 0, first_key_inspected = false; + while (true) { + var k = i + ((j - i) >> 1), diff = 0, common = common_i < common_j + ? common_i + : common_j, w = v[k]; + for (var i2 = w.s_size - 1 - common; i2 >= 0; i2--) { + if (c - common == lb) { + diff = -1; + break; + } + diff = current.charCodeAt(c - 1 - common) - w.s[i2]; + if (diff) + break; + common++; + } + if (diff < 0) { + j = k; + common_j = common; + } else { + i = k; + common_i = common; + } + if (j - i <= 1) { + if (i > 0 || j == i || first_key_inspected) + break; + first_key_inspected = true; + } + } + while (true) { + var w = v[i]; + if (common_i >= w.s_size) { + this.cursor = c - w.s_size; + if (!w.method) + return w.result; + var res = w.method(); + this.cursor = c - w.s_size; + if (res) + return w.result; + } + i = w.substring_i; + if (i < 0) + return 0; + } + }, + replace_s : function(c_bra, c_ket, s) { + var adjustment = s.length - (c_ket - c_bra), left = current + .substring(0, c_bra), right = current.substring(c_ket); + current = left + s + right; + this.limit += adjustment; + if (this.cursor >= c_ket) + this.cursor += adjustment; + else if (this.cursor > c_bra) + this.cursor = c_bra; + return adjustment; + }, + slice_check : function() { + if (this.bra < 0 || this.bra > this.ket || this.ket > this.limit + || this.limit > current.length) + throw ("faulty slice operation"); + }, + slice_from : function(s) { + this.slice_check(); + this.replace_s(this.bra, this.ket, s); + }, + slice_del : function() { + this.slice_from(""); + }, + insert : function(c_bra, c_ket, s) { + var adjustment = this.replace_s(c_bra, c_ket, s); + if (c_bra <= this.bra) + this.bra += adjustment; + if (c_bra <= this.ket) + this.ket += adjustment; + }, + slice_to : function() { + this.slice_check(); + return current.substring(this.bra, this.ket); + }, + eq_v_b : function(s) { + return this.eq_s_b(s.length, s); + } + }; + } + }; + + lunr.trimmerSupport = { + generateTrimmer: function(wordCharacters) { + var startRegex = new RegExp("^[^" + wordCharacters + "]+") + var endRegex = new RegExp("[^" + wordCharacters + "]+$") + + return function(token) { + return token + .replace(startRegex, '') + .replace(endRegex, ''); + }; + } + } + } +})); diff --git a/js/lunr.stemmer.support.min.js b/js/lunr.stemmer.support.min.js new file mode 100644 index 0000000..3ffdbd6 --- /dev/null +++ b/js/lunr.stemmer.support.min.js @@ -0,0 +1 @@ +!function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s>3]&1<<(7&s))return this.cursor++,!0}return!1},in_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(s<=i&&t<=s&&r[(s-=t)>>3]&1<<(7&s))return this.cursor--,!0}return!1},out_grouping:function(r,t,i){if(this.cursor>3]&1<<(7&s)))return this.cursor++,!0}return!1},out_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(i>3]&1<<(7&s)))return this.cursor--,!0}return!1},eq_s:function(r,t){if(this.limit-this.cursor>1),f=0,a=u=(l=r[i]).s_size){if(this.cursor=e+l.s_size,!l.method)return l.result;var m=l.method();if(this.cursor=e+l.s_size,m)return l.result}if((i=l.substring_i)<0)return 0}},find_among_b:function(r,t){for(var i=0,s=t,e=this.cursor,n=this.limit_backward,u=0,o=0,h=!1;;){for(var c,f=i+(s-i>>1),a=0,l=u=(c=r[i]).s_size){if(this.cursor=e-c.s_size,!c.method)return c.result;var m=c.method();if(this.cursor=e-c.s_size,m)return c.result}if((i=c.substring_i)<0)return 0}},replace_s:function(r,t,i){var s=i.length-(t-r);return b=b.substring(0,r)+i+b.substring(t),this.limit+=s,this.cursor>=t?this.cursor+=s:this.cursor>r&&(this.cursor=r),s},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>b.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){t=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=t),r<=this.ket&&(this.ket+=t)},slice_to:function(){return this.slice_check(),b.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/js/lunr.sv.js b/js/lunr.sv.js new file mode 100644 index 0000000..d48ea4a --- /dev/null +++ b/js/lunr.sv.js @@ -0,0 +1,252 @@ +/*! + * Lunr languages, `Swedish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.sv = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.sv.trimmer, + lunr.sv.stopWordFilter, + lunr.sv.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.sv.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.sv.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.sv.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.sv.trimmer, 'trimmer-sv'); + + /* lunr stemmer function */ + lunr.sv.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function SwedishStemmer() { + var a_0 = [new Among("a", -1, 1), new Among("arna", 0, 1), + new Among("erna", 0, 1), new Among("heterna", 2, 1), + new Among("orna", 0, 1), new Among("ad", -1, 1), + new Among("e", -1, 1), new Among("ade", 6, 1), + new Among("ande", 6, 1), new Among("arne", 6, 1), + new Among("are", 6, 1), new Among("aste", 6, 1), + new Among("en", -1, 1), new Among("anden", 12, 1), + new Among("aren", 12, 1), new Among("heten", 12, 1), + new Among("ern", -1, 1), new Among("ar", -1, 1), + new Among("er", -1, 1), new Among("heter", 18, 1), + new Among("or", -1, 1), new Among("s", -1, 2), + new Among("as", 21, 1), new Among("arnas", 22, 1), + new Among("ernas", 22, 1), new Among("ornas", 22, 1), + new Among("es", 21, 1), new Among("ades", 26, 1), + new Among("andes", 26, 1), new Among("ens", 21, 1), + new Among("arens", 29, 1), new Among("hetens", 29, 1), + new Among("erns", 21, 1), new Among("at", -1, 1), + new Among("andet", -1, 1), new Among("het", -1, 1), + new Among("ast", -1, 1) + ], + a_1 = [new Among("dd", -1, -1), + new Among("gd", -1, -1), new Among("nn", -1, -1), + new Among("dt", -1, -1), new Among("gt", -1, -1), + new Among("kt", -1, -1), new Among("tt", -1, -1) + ], + a_2 = [ + new Among("ig", -1, 1), new Among("lig", 0, 1), + new Among("els", -1, 1), new Among("fullt", -1, 3), + new Among("l\u00F6st", -1, 2) + ], + g_v = [17, 65, 16, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32 + ], + g_s_ending = [119, 127, 149], + I_x, I_p1, sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function r_mark_regions() { + var v_1, c = sbp.cursor + 3; + I_p1 = sbp.limit; + if (0 <= c || c <= sbp.limit) { + I_x = c; + while (true) { + v_1 = sbp.cursor; + if (sbp.in_grouping(g_v, 97, 246)) { + sbp.cursor = v_1; + break; + } + sbp.cursor = v_1; + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + while (!sbp.out_grouping(g_v, 97, 246)) { + if (sbp.cursor >= sbp.limit) + return; + sbp.cursor++; + } + I_p1 = sbp.cursor; + if (I_p1 < I_x) + I_p1 = I_x; + } + } + + function r_main_suffix() { + var among_var, v_2 = sbp.limit_backward; + if (sbp.cursor >= I_p1) { + sbp.limit_backward = I_p1; + sbp.cursor = sbp.limit; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_0, 37); + sbp.limit_backward = v_2; + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + if (sbp.in_grouping_b(g_s_ending, 98, 121)) + sbp.slice_del(); + break; + } + } + } + } + + function r_consonant_pair() { + var v_1 = sbp.limit_backward; + if (sbp.cursor >= I_p1) { + sbp.limit_backward = I_p1; + sbp.cursor = sbp.limit; + if (sbp.find_among_b(a_1, 7)) { + sbp.cursor = sbp.limit; + sbp.ket = sbp.cursor; + if (sbp.cursor > sbp.limit_backward) { + sbp.bra = --sbp.cursor; + sbp.slice_del(); + } + } + sbp.limit_backward = v_1; + } + } + + function r_other_suffix() { + var among_var, v_2; + if (sbp.cursor >= I_p1) { + v_2 = sbp.limit_backward; + sbp.limit_backward = I_p1; + sbp.cursor = sbp.limit; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_2, 5); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_del(); + break; + case 2: + sbp.slice_from("l\u00F6s"); + break; + case 3: + sbp.slice_from("full"); + break; + } + } + sbp.limit_backward = v_2; + } + } + this.stem = function() { + var v_1 = sbp.cursor; + r_mark_regions(); + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_main_suffix(); + sbp.cursor = sbp.limit; + r_consonant_pair(); + sbp.cursor = sbp.limit; + r_other_suffix(); + return true; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.sv.stemmer, 'stemmer-sv'); + + /* stop word filter function */ + lunr.sv.stopWordFilter = function(token) { + if (lunr.sv.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.sv.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.sv.stopWordFilter.stopWords.length = 115; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.sv.stopWordFilter.stopWords.elements = ' alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över'.split(' '); + + lunr.Pipeline.registerFunction(lunr.sv.stopWordFilter, 'stopWordFilter-sv'); + }; +})) \ No newline at end of file diff --git a/js/lunr.sv.min.js b/js/lunr.sv.min.js new file mode 100644 index 0000000..835f98b --- /dev/null +++ b/js/lunr.sv.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var e,d,n;r.sv=function(){this.pipeline.reset(),this.pipeline.add(r.sv.trimmer,r.sv.stopWordFilter,r.sv.stemmer)},r.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.sv.trimmer=r.trimmerSupport.generateTrimmer(r.sv.wordCharacters),r.Pipeline.registerFunction(r.sv.trimmer,"trimmer-sv"),r.sv.stemmer=(e=r.stemmerSupport.Among,d=r.stemmerSupport.SnowballProgram,n=new function(){var n,t,i=[new e("a",-1,1),new e("arna",0,1),new e("erna",0,1),new e("heterna",2,1),new e("orna",0,1),new e("ad",-1,1),new e("e",-1,1),new e("ade",6,1),new e("ande",6,1),new e("arne",6,1),new e("are",6,1),new e("aste",6,1),new e("en",-1,1),new e("anden",12,1),new e("aren",12,1),new e("heten",12,1),new e("ern",-1,1),new e("ar",-1,1),new e("er",-1,1),new e("heter",18,1),new e("or",-1,1),new e("s",-1,2),new e("as",21,1),new e("arnas",22,1),new e("ernas",22,1),new e("ornas",22,1),new e("es",21,1),new e("ades",26,1),new e("andes",26,1),new e("ens",21,1),new e("arens",29,1),new e("hetens",29,1),new e("erns",21,1),new e("at",-1,1),new e("andet",-1,1),new e("het",-1,1),new e("ast",-1,1)],s=[new e("dd",-1,-1),new e("gd",-1,-1),new e("nn",-1,-1),new e("dt",-1,-1),new e("gt",-1,-1),new e("kt",-1,-1),new e("tt",-1,-1)],a=[new e("ig",-1,1),new e("lig",0,1),new e("els",-1,1),new e("fullt",-1,3),new e("löst",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],l=new d;this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var e=l.cursor;!function(){var e,r=l.cursor+3;if(t=l.limit,0<=r||r<=l.limit){for(n=r;;){if(e=l.cursor,l.in_grouping(o,97,246)){l.cursor=e;break}if(l.cursor=e,l.cursor>=l.limit)return;l.cursor++}for(;!l.out_grouping(o,97,246);){if(l.cursor>=l.limit)return;l.cursor++}(t=l.cursor)=t&&(l.limit_backward=t,l.cursor=l.limit,l.ket=l.cursor,r=l.find_among_b(i,37),l.limit_backward=e,r))switch(l.bra=l.cursor,r){case 1:l.slice_del();break;case 2:l.in_grouping_b(u,98,121)&&l.slice_del()}if(l.cursor=l.limit,e=l.limit_backward,l.cursor>=t&&(l.limit_backward=t,l.cursor=l.limit,l.find_among_b(s,7)&&(l.cursor=l.limit,l.ket=l.cursor,l.cursor>l.limit_backward)&&(l.bra=--l.cursor,l.slice_del()),l.limit_backward=e),l.cursor=l.limit,l.cursor>=t){if(r=l.limit_backward,l.limit_backward=t,l.cursor=l.limit,l.ket=l.cursor,e=l.find_among_b(a,5))switch(l.bra=l.cursor,e){case 1:l.slice_del();break;case 2:l.slice_from("lös");break;case 3:l.slice_from("full")}l.limit_backward=r}return!0}},function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}),r.Pipeline.registerFunction(r.sv.stemmer,"stemmer-sv"),r.sv.stopWordFilter=function(e){if(-1===r.sv.stopWordFilter.stopWords.indexOf(e))return e},r.sv.stopWordFilter.stopWords=new r.SortedSet,r.sv.stopWordFilter.stopWords.length=115,r.sv.stopWordFilter.stopWords.elements=" alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" "),r.Pipeline.registerFunction(r.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/js/lunr.tr.js b/js/lunr.tr.js new file mode 100644 index 0000000..1e5d8da --- /dev/null +++ b/js/lunr.tr.js @@ -0,0 +1,1070 @@ +/*! + * Lunr languages, `Turkish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +; +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function() { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return function(lunr) { + /* throw error if lunr is not yet included */ + if ('undefined' === typeof lunr) { + throw new Error('Lunr is not present. Please include / require Lunr before this script.'); + } + + /* throw error if lunr stemmer support is not yet included */ + if ('undefined' === typeof lunr.stemmerSupport) { + throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.'); + } + + /* register specific locale function */ + lunr.tr = function() { + this.pipeline.reset(); + this.pipeline.add( + lunr.tr.trimmer, + lunr.tr.stopWordFilter, + lunr.tr.stemmer + ); + }; + + /* lunr trimmer function */ + lunr.tr.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A"; + lunr.tr.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.tr.wordCharacters); + + lunr.Pipeline.registerFunction(lunr.tr.trimmer, 'trimmer-tr'); + + /* lunr stemmer function */ + lunr.tr.stemmer = (function() { + /* create the wrapped stemmer object */ + var Among = lunr.stemmerSupport.Among, + SnowballProgram = lunr.stemmerSupport.SnowballProgram, + st = new function TurkishStemmer() { + var a_0 = [new Among("m", -1, -1), new Among("n", -1, -1), + new Among("miz", -1, -1), new Among("niz", -1, -1), + new Among("muz", -1, -1), new Among("nuz", -1, -1), + new Among("m\u00FCz", -1, -1), new Among("n\u00FCz", -1, -1), + new Among("m\u0131z", -1, -1), new Among("n\u0131z", -1, -1) + ], + a_1 = [ + new Among("leri", -1, -1), new Among("lar\u0131", -1, -1) + ], + a_2 = [ + new Among("ni", -1, -1), new Among("nu", -1, -1), + new Among("n\u00FC", -1, -1), new Among("n\u0131", -1, -1) + ], + a_3 = [ + new Among("in", -1, -1), new Among("un", -1, -1), + new Among("\u00FCn", -1, -1), new Among("\u0131n", -1, -1) + ], + a_4 = [ + new Among("a", -1, -1), new Among("e", -1, -1) + ], + a_5 = [ + new Among("na", -1, -1), new Among("ne", -1, -1) + ], + a_6 = [ + new Among("da", -1, -1), new Among("ta", -1, -1), + new Among("de", -1, -1), new Among("te", -1, -1) + ], + a_7 = [ + new Among("nda", -1, -1), new Among("nde", -1, -1) + ], + a_8 = [ + new Among("dan", -1, -1), new Among("tan", -1, -1), + new Among("den", -1, -1), new Among("ten", -1, -1) + ], + a_9 = [ + new Among("ndan", -1, -1), new Among("nden", -1, -1) + ], + a_10 = [ + new Among("la", -1, -1), new Among("le", -1, -1) + ], + a_11 = [ + new Among("ca", -1, -1), new Among("ce", -1, -1) + ], + a_12 = [ + new Among("im", -1, -1), new Among("um", -1, -1), + new Among("\u00FCm", -1, -1), new Among("\u0131m", -1, -1) + ], + a_13 = [ + new Among("sin", -1, -1), new Among("sun", -1, -1), + new Among("s\u00FCn", -1, -1), new Among("s\u0131n", -1, -1) + ], + a_14 = [ + new Among("iz", -1, -1), new Among("uz", -1, -1), + new Among("\u00FCz", -1, -1), new Among("\u0131z", -1, -1) + ], + a_15 = [ + new Among("siniz", -1, -1), new Among("sunuz", -1, -1), + new Among("s\u00FCn\u00FCz", -1, -1), + new Among("s\u0131n\u0131z", -1, -1) + ], + a_16 = [ + new Among("lar", -1, -1), new Among("ler", -1, -1) + ], + a_17 = [ + new Among("niz", -1, -1), new Among("nuz", -1, -1), + new Among("n\u00FCz", -1, -1), new Among("n\u0131z", -1, -1) + ], + a_18 = [ + new Among("dir", -1, -1), new Among("tir", -1, -1), + new Among("dur", -1, -1), new Among("tur", -1, -1), + new Among("d\u00FCr", -1, -1), new Among("t\u00FCr", -1, -1), + new Among("d\u0131r", -1, -1), new Among("t\u0131r", -1, -1) + ], + a_19 = [ + new Among("cas\u0131na", -1, -1), new Among("cesine", -1, -1) + ], + a_20 = [ + new Among("di", -1, -1), new Among("ti", -1, -1), + new Among("dik", -1, -1), new Among("tik", -1, -1), + new Among("duk", -1, -1), new Among("tuk", -1, -1), + new Among("d\u00FCk", -1, -1), new Among("t\u00FCk", -1, -1), + new Among("d\u0131k", -1, -1), new Among("t\u0131k", -1, -1), + new Among("dim", -1, -1), new Among("tim", -1, -1), + new Among("dum", -1, -1), new Among("tum", -1, -1), + new Among("d\u00FCm", -1, -1), new Among("t\u00FCm", -1, -1), + new Among("d\u0131m", -1, -1), new Among("t\u0131m", -1, -1), + new Among("din", -1, -1), new Among("tin", -1, -1), + new Among("dun", -1, -1), new Among("tun", -1, -1), + new Among("d\u00FCn", -1, -1), new Among("t\u00FCn", -1, -1), + new Among("d\u0131n", -1, -1), new Among("t\u0131n", -1, -1), + new Among("du", -1, -1), new Among("tu", -1, -1), + new Among("d\u00FC", -1, -1), new Among("t\u00FC", -1, -1), + new Among("d\u0131", -1, -1), new Among("t\u0131", -1, -1) + ], + a_21 = [ + new Among("sa", -1, -1), new Among("se", -1, -1), + new Among("sak", -1, -1), new Among("sek", -1, -1), + new Among("sam", -1, -1), new Among("sem", -1, -1), + new Among("san", -1, -1), new Among("sen", -1, -1) + ], + a_22 = [ + new Among("mi\u015F", -1, -1), new Among("mu\u015F", -1, -1), + new Among("m\u00FC\u015F", -1, -1), + new Among("m\u0131\u015F", -1, -1) + ], + a_23 = [new Among("b", -1, 1), + new Among("c", -1, 2), new Among("d", -1, 3), + new Among("\u011F", -1, 4) + ], + g_vowel = [17, 65, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 0, 0, 0, 1 + ], + g_U = [ + 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 1 + ], + g_vowel1 = [1, 64, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + ], + g_vowel2 = [17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130 + ], + g_vowel3 = [1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1 + ], + g_vowel4 = [17], + g_vowel5 = [65], + g_vowel6 = [65], + B_c_s_n_s, I_strlen, g_habr = [ + ["a", g_vowel1, 97, 305], + ["e", g_vowel2, 101, 252], + ["\u0131", g_vowel3, 97, 305], + ["i", g_vowel4, 101, 105], + ["o", g_vowel5, 111, 117], + ["\u00F6", g_vowel6, 246, 252], + ["u", g_vowel5, 111, 117] + ], + sbp = new SnowballProgram(); + this.setCurrent = function(word) { + sbp.setCurrent(word); + }; + this.getCurrent = function() { + return sbp.getCurrent(); + }; + + function habr1(g_v, n1, n2) { + while (true) { + var v_1 = sbp.limit - sbp.cursor; + if (sbp.in_grouping_b(g_v, n1, n2)) { + sbp.cursor = sbp.limit - v_1; + break; + } + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor <= sbp.limit_backward) + return false; + sbp.cursor--; + } + return true; + } + + function r_check_vowel_harmony() { + var v_1, v_2; + v_1 = sbp.limit - sbp.cursor; + habr1(g_vowel, 97, 305); + for (var i = 0; i < g_habr.length; i++) { + v_2 = sbp.limit - sbp.cursor; + var habr = g_habr[i]; + if (sbp.eq_s_b(1, habr[0]) && habr1(habr[1], habr[2], habr[3])) { + sbp.cursor = sbp.limit - v_1; + return true; + } + sbp.cursor = sbp.limit - v_2; + } + sbp.cursor = sbp.limit - v_2; + if (!sbp.eq_s_b(1, "\u00FC") || !habr1(g_vowel6, 246, 252)) + return false; + sbp.cursor = sbp.limit - v_1; + return true; + } + + function habr2(f1, f2) { + var v_1 = sbp.limit - sbp.cursor, + v_2; + if (f1()) { + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor > sbp.limit_backward) { + sbp.cursor--; + v_2 = sbp.limit - sbp.cursor; + if (f2()) { + sbp.cursor = sbp.limit - v_2; + return true; + } + } + } + sbp.cursor = sbp.limit - v_1; + if (f1()) { + sbp.cursor = sbp.limit - v_1; + return false; + } + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor <= sbp.limit_backward) + return false; + sbp.cursor--; + if (!f2()) + return false; + sbp.cursor = sbp.limit - v_1; + return true; + } + + function habr3(f1) { + return habr2(f1, function() { + return sbp.in_grouping_b(g_vowel, 97, 305); + }); + } + + function r_mark_suffix_with_optional_n_consonant() { + return habr3(function() { + return sbp.eq_s_b(1, "n"); + }); + } + + function r_mark_suffix_with_optional_s_consonant() { + return habr3(function() { + return sbp.eq_s_b(1, "s"); + }); + } + + function r_mark_suffix_with_optional_y_consonant() { + return habr3(function() { + return sbp.eq_s_b(1, "y"); + }); + } + + function r_mark_suffix_with_optional_U_vowel() { + return habr2(function() { + return sbp.in_grouping_b(g_U, 105, 305); + }, function() { + return sbp.out_grouping_b(g_vowel, 97, 305); + }); + } + + function r_mark_possessives() { + return sbp.find_among_b(a_0, 10) && r_mark_suffix_with_optional_U_vowel(); + } + + function r_mark_sU() { + return r_check_vowel_harmony() && sbp.in_grouping_b(g_U, 105, 305) && r_mark_suffix_with_optional_s_consonant(); + } + + function r_mark_lArI() { + return sbp.find_among_b(a_1, 2); + } + + function r_mark_yU() { + return r_check_vowel_harmony() && sbp.in_grouping_b(g_U, 105, 305) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_nU() { + return r_check_vowel_harmony() && sbp.find_among_b(a_2, 4); + } + + function r_mark_nUn() { + return r_check_vowel_harmony() && sbp.find_among_b(a_3, 4) && r_mark_suffix_with_optional_n_consonant(); + } + + function r_mark_yA() { + return r_check_vowel_harmony() && sbp.find_among_b(a_4, 2) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_nA() { + return r_check_vowel_harmony() && sbp.find_among_b(a_5, 2); + } + + function r_mark_DA() { + return r_check_vowel_harmony() && sbp.find_among_b(a_6, 4); + } + + function r_mark_ndA() { + return r_check_vowel_harmony() && sbp.find_among_b(a_7, 2); + } + + function r_mark_DAn() { + return r_check_vowel_harmony() && sbp.find_among_b(a_8, 4); + } + + function r_mark_ndAn() { + return r_check_vowel_harmony() && sbp.find_among_b(a_9, 2); + } + + function r_mark_ylA() { + return r_check_vowel_harmony() && sbp.find_among_b(a_10, 2) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_ki() { + return sbp.eq_s_b(2, "ki"); + } + + function r_mark_ncA() { + return r_check_vowel_harmony() && sbp.find_among_b(a_11, 2) && r_mark_suffix_with_optional_n_consonant(); + } + + function r_mark_yUm() { + return r_check_vowel_harmony() && sbp.find_among_b(a_12, 4) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_sUn() { + return r_check_vowel_harmony() && sbp.find_among_b(a_13, 4); + } + + function r_mark_yUz() { + return r_check_vowel_harmony() && sbp.find_among_b(a_14, 4) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_sUnUz() { + return sbp.find_among_b(a_15, 4); + } + + function r_mark_lAr() { + return r_check_vowel_harmony() && sbp.find_among_b(a_16, 2); + } + + function r_mark_nUz() { + return r_check_vowel_harmony() && sbp.find_among_b(a_17, 4); + } + + function r_mark_DUr() { + return r_check_vowel_harmony() && sbp.find_among_b(a_18, 8); + } + + function r_mark_cAsInA() { + return sbp.find_among_b(a_19, 2); + } + + function r_mark_yDU() { + return r_check_vowel_harmony() && sbp.find_among_b(a_20, 32) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_ysA() { + return sbp.find_among_b(a_21, 8) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_ymUs_() { + return r_check_vowel_harmony() && sbp.find_among_b(a_22, 4) && r_mark_suffix_with_optional_y_consonant(); + } + + function r_mark_yken() { + return sbp.eq_s_b(3, "ken") && r_mark_suffix_with_optional_y_consonant(); + } + + function habr4() { + var v_1 = sbp.limit - sbp.cursor; + if (!r_mark_ymUs_()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yDU()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_ysA()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yken()) + return true; + } + } + } + return false; + } + + function habr5() { + if (r_mark_cAsInA()) { + var v_1 = sbp.limit - sbp.cursor; + if (!r_mark_sUnUz()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_lAr()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yUm()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_sUn()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yUz()) + sbp.cursor = sbp.limit - v_1; + } + } + } + } + if (r_mark_ymUs_()) + return false; + } + return true; + } + + function habr6() { + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + var v_1 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (!r_mark_DUr()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yDU()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_ysA()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_ymUs_()) + sbp.cursor = sbp.limit - v_1; + } + } + } + B_c_s_n_s = false; + return false; + } + return true; + } + + function habr7() { + if (!r_mark_nUz()) + return true; + var v_1 = sbp.limit - sbp.cursor; + if (!r_mark_yDU()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_ysA()) + return true; + } + return false; + } + + function habr8() { + var v_1 = sbp.limit - sbp.cursor, + v_2; + if (!r_mark_sUnUz()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yUz()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_sUn()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yUm()) + return true; + } + } + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + v_2 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (!r_mark_ymUs_()) + sbp.cursor = sbp.limit - v_2; + return false; + } + + function r_stem_nominal_verb_suffixes() { + var v_1 = sbp.limit - sbp.cursor, + v_2; + sbp.ket = sbp.cursor; + B_c_s_n_s = true; + if (habr4()) { + sbp.cursor = sbp.limit - v_1; + if (habr5()) { + sbp.cursor = sbp.limit - v_1; + if (habr6()) { + sbp.cursor = sbp.limit - v_1; + if (habr7()) { + sbp.cursor = sbp.limit - v_1; + if (habr8()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_DUr()) + return; + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + v_2 = sbp.limit - sbp.cursor; + if (!r_mark_sUnUz()) { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_lAr()) { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_yUm()) { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_sUn()) { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_yUz()) + sbp.cursor = sbp.limit - v_2; + } + } + } + } + if (!r_mark_ymUs_()) + sbp.cursor = sbp.limit - v_2; + } + } + } + } + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + } + + function r_stem_suffix_chain_before_ki() { + var v_1, v_2, v_3, v_4; + sbp.ket = sbp.cursor; + if (r_mark_ki()) { + v_1 = sbp.limit - sbp.cursor; + if (r_mark_DA()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + v_2 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } else { + sbp.cursor = sbp.limit - v_2; + if (r_mark_possessives()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + } + } + return true; + } + sbp.cursor = sbp.limit - v_1; + if (r_mark_nUn()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + v_3 = sbp.limit - sbp.cursor; + if (r_mark_lArI()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + } else { + sbp.cursor = sbp.limit - v_3; + sbp.ket = sbp.cursor; + if (!r_mark_possessives()) { + sbp.cursor = sbp.limit - v_3; + if (!r_mark_sU()) { + sbp.cursor = sbp.limit - v_3; + if (!r_stem_suffix_chain_before_ki()) + return true; + } + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki() + } + } + return true; + } + sbp.cursor = sbp.limit - v_1; + if (r_mark_ndA()) { + v_4 = sbp.limit - sbp.cursor; + if (r_mark_lArI()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + } else { + sbp.cursor = sbp.limit - v_4; + if (r_mark_sU()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + } else { + sbp.cursor = sbp.limit - v_4; + if (!r_stem_suffix_chain_before_ki()) + return false; + } + } + return true; + } + } + return false; + } + + function habr9(v_1) { + sbp.ket = sbp.cursor; + if (!r_mark_ndA()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_nA()) + return false; + } + var v_2 = sbp.limit - sbp.cursor; + if (r_mark_lArI()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + } else { + sbp.cursor = sbp.limit - v_2; + if (r_mark_sU()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + } else { + sbp.cursor = sbp.limit - v_2; + if (!r_stem_suffix_chain_before_ki()) + return false; + } + } + return true; + } + + function habr10(v_1) { + sbp.ket = sbp.cursor; + if (!r_mark_ndAn()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_nU()) + return false; + } + var v_2 = sbp.limit - sbp.cursor; + if (!r_mark_sU()) { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_lArI()) + return false; + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + return true; + } + + function habr11() { + var v_1 = sbp.limit - sbp.cursor, + v_2; + sbp.ket = sbp.cursor; + if (!r_mark_nUn()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_ylA()) + return false; + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + v_2 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + if (r_stem_suffix_chain_before_ki()) + return true; + } + sbp.cursor = sbp.limit - v_2; + sbp.ket = sbp.cursor; + if (!r_mark_possessives()) { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_sU()) { + sbp.cursor = sbp.limit - v_2; + if (!r_stem_suffix_chain_before_ki()) + return true; + } + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + return true; + } + + function habr12() { + var v_1 = sbp.limit - sbp.cursor, + v_2, v_3; + sbp.ket = sbp.cursor; + if (!r_mark_DA()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yU()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_yA()) + return false; + } + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + v_2 = sbp.limit - sbp.cursor; + if (r_mark_possessives()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + v_3 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (!r_mark_lAr()) + sbp.cursor = sbp.limit - v_3; + } else { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_lAr()) + return true; + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + r_stem_suffix_chain_before_ki(); + return true; + } + + function r_stem_noun_suffixes() { + var v_1 = sbp.limit - sbp.cursor, + v_2, v_3; + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + return; + } + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + if (r_mark_ncA()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + v_2 = sbp.limit - sbp.cursor; + sbp.ket = sbp.cursor; + if (r_mark_lArI()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + } else { + sbp.cursor = sbp.limit - v_2; + sbp.ket = sbp.cursor; + if (!r_mark_possessives()) { + sbp.cursor = sbp.limit - v_2; + if (!r_mark_sU()) { + sbp.cursor = sbp.limit - v_2; + sbp.ket = sbp.cursor; + if (!r_mark_lAr()) + return; + sbp.bra = sbp.cursor; + sbp.slice_del(); + if (!r_stem_suffix_chain_before_ki()) + return; + } + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + } + return; + } + sbp.cursor = sbp.limit - v_1; + if (habr9(v_1)) + return; + sbp.cursor = sbp.limit - v_1; + if (habr10(v_1)) + return; + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + if (r_mark_DAn()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + v_3 = sbp.limit - sbp.cursor; + if (r_mark_possessives()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + } else { + sbp.cursor = sbp.limit - v_3; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } else { + sbp.cursor = sbp.limit - v_3; + r_stem_suffix_chain_before_ki(); + } + } + return; + } + sbp.cursor = sbp.limit - v_1; + if (habr11()) + return; + sbp.cursor = sbp.limit - v_1; + if (r_mark_lArI()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + return; + } + sbp.cursor = sbp.limit - v_1; + if (r_stem_suffix_chain_before_ki()) + return; + sbp.cursor = sbp.limit - v_1; + if (habr12()) + return; + sbp.cursor = sbp.limit - v_1; + sbp.ket = sbp.cursor; + if (!r_mark_possessives()) { + sbp.cursor = sbp.limit - v_1; + if (!r_mark_sU()) + return; + } + sbp.bra = sbp.cursor; + sbp.slice_del(); + sbp.ket = sbp.cursor; + if (r_mark_lAr()) { + sbp.bra = sbp.cursor; + sbp.slice_del(); + r_stem_suffix_chain_before_ki(); + } + } + + function r_post_process_last_consonants() { + var among_var; + sbp.ket = sbp.cursor; + among_var = sbp.find_among_b(a_23, 4); + if (among_var) { + sbp.bra = sbp.cursor; + switch (among_var) { + case 1: + sbp.slice_from("p"); + break; + case 2: + sbp.slice_from("\u00E7"); + break; + case 3: + sbp.slice_from("t"); + break; + case 4: + sbp.slice_from("k"); + break; + } + } + } + + function habr13() { + while (true) { + var v_1 = sbp.limit - sbp.cursor; + if (sbp.in_grouping_b(g_vowel, 97, 305)) { + sbp.cursor = sbp.limit - v_1; + break; + } + sbp.cursor = sbp.limit - v_1; + if (sbp.cursor <= sbp.limit_backward) + return false; + sbp.cursor--; + } + return true; + } + + function habr14(v_1, c1, c2) { + sbp.cursor = sbp.limit - v_1; + if (habr13()) { + var v_2 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, c1)) { + sbp.cursor = sbp.limit - v_2; + if (!sbp.eq_s_b(1, c2)) + return true; + } + sbp.cursor = sbp.limit - v_1; + var c = sbp.cursor; + sbp.insert(sbp.cursor, sbp.cursor, c2); + sbp.cursor = c; + return false; + } + return true; + } + + function r_append_U_to_stems_ending_with_d_or_g() { + var v_1 = sbp.limit - sbp.cursor; + if (!sbp.eq_s_b(1, "d")) { + sbp.cursor = sbp.limit - v_1; + if (!sbp.eq_s_b(1, "g")) + return; + } + if (habr14(v_1, "a", "\u0131")) + if (habr14(v_1, "e", "i")) + if (habr14(v_1, "o", "u")) + habr14(v_1, "\u00F6", "\u00FC") + } + + function r_more_than_one_syllable_word() { + var v_1 = sbp.cursor, + v_2 = 2, + v_3; + while (true) { + v_3 = sbp.cursor; + while (!sbp.in_grouping(g_vowel, 97, 305)) { + if (sbp.cursor >= sbp.limit) { + sbp.cursor = v_3; + if (v_2 > 0) + return false; + sbp.cursor = v_1; + return true; + } + sbp.cursor++; + } + v_2--; + } + } + + function habr15(v_1, n1, c1) { + while (!sbp.eq_s(n1, c1)) { + if (sbp.cursor >= sbp.limit) + return true; + sbp.cursor++; + } + I_strlen = n1; + if (I_strlen != sbp.limit) + return true; + sbp.cursor = v_1; + return false; + } + + function r_is_reserved_word() { + var v_1 = sbp.cursor; + if (habr15(v_1, 2, "ad")) { + sbp.cursor = v_1; + if (habr15(v_1, 5, "soyad")) + return false; + } + return true; + } + + function r_postlude() { + var v_1 = sbp.cursor; + if (r_is_reserved_word()) + return false; + sbp.limit_backward = v_1; + sbp.cursor = sbp.limit; + r_append_U_to_stems_ending_with_d_or_g(); + sbp.cursor = sbp.limit; + r_post_process_last_consonants(); + return true; + } + this.stem = function() { + if (r_more_than_one_syllable_word()) { + sbp.limit_backward = sbp.cursor; + sbp.cursor = sbp.limit; + r_stem_nominal_verb_suffixes(); + sbp.cursor = sbp.limit; + if (B_c_s_n_s) { + r_stem_noun_suffixes(); + sbp.cursor = sbp.limit_backward; + if (r_postlude()) + return true; + } + } + return false; + } + }; + + /* and return a function that stems a word for the current locale */ + return function(word) { + st.setCurrent(word); + st.stem(); + return st.getCurrent(); + } + })(); + + lunr.Pipeline.registerFunction(lunr.tr.stemmer, 'stemmer-tr'); + + /* stop word filter function */ + lunr.tr.stopWordFilter = function(token) { + if (lunr.tr.stopWordFilter.stopWords.indexOf(token) === -1) { + return token; + } + }; + + lunr.tr.stopWordFilter.stopWords = new lunr.SortedSet(); + lunr.tr.stopWordFilter.stopWords.length = 210; + + // The space at the beginning is crucial: It marks the empty string + // as a stop word. lunr.js crashes during search when documents + // processed by the pipeline still contain the empty string. + lunr.tr.stopWordFilter.stopWords.elements = ' acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle'.split(' '); + + lunr.Pipeline.registerFunction(lunr.tr.stopWordFilter, 'stopWordFilter-tr'); + }; +})) \ No newline at end of file diff --git a/js/lunr.tr.min.js b/js/lunr.tr.min.js new file mode 100644 index 0000000..54adb6d --- /dev/null +++ b/js/lunr.tr.min.js @@ -0,0 +1 @@ +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var mr,dr,e;i.tr=function(){this.pipeline.reset(),this.pipeline.add(i.tr.trimmer,i.tr.stopWordFilter,i.tr.stemmer)},i.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.tr.trimmer=i.trimmerSupport.generateTrimmer(i.tr.wordCharacters),i.Pipeline.registerFunction(i.tr.trimmer,"trimmer-tr"),i.tr.stemmer=(mr=i.stemmerSupport.Among,dr=i.stemmerSupport.SnowballProgram,e=new function(){var i,r=[new mr("m",-1,-1),new mr("n",-1,-1),new mr("miz",-1,-1),new mr("niz",-1,-1),new mr("muz",-1,-1),new mr("nuz",-1,-1),new mr("müz",-1,-1),new mr("nüz",-1,-1),new mr("mız",-1,-1),new mr("nız",-1,-1)],e=[new mr("leri",-1,-1),new mr("ları",-1,-1)],n=[new mr("ni",-1,-1),new mr("nu",-1,-1),new mr("nü",-1,-1),new mr("nı",-1,-1)],t=[new mr("in",-1,-1),new mr("un",-1,-1),new mr("ün",-1,-1),new mr("ın",-1,-1)],u=[new mr("a",-1,-1),new mr("e",-1,-1)],T=[new mr("na",-1,-1),new mr("ne",-1,-1)],Z=[new mr("da",-1,-1),new mr("ta",-1,-1),new mr("de",-1,-1),new mr("te",-1,-1)],B=[new mr("nda",-1,-1),new mr("nde",-1,-1)],D=[new mr("dan",-1,-1),new mr("tan",-1,-1),new mr("den",-1,-1),new mr("ten",-1,-1)],G=[new mr("ndan",-1,-1),new mr("nden",-1,-1)],H=[new mr("la",-1,-1),new mr("le",-1,-1)],I=[new mr("ca",-1,-1),new mr("ce",-1,-1)],J=[new mr("im",-1,-1),new mr("um",-1,-1),new mr("üm",-1,-1),new mr("ım",-1,-1)],K=[new mr("sin",-1,-1),new mr("sun",-1,-1),new mr("sün",-1,-1),new mr("sın",-1,-1)],M=[new mr("iz",-1,-1),new mr("uz",-1,-1),new mr("üz",-1,-1),new mr("ız",-1,-1)],N=[new mr("siniz",-1,-1),new mr("sunuz",-1,-1),new mr("sünüz",-1,-1),new mr("sınız",-1,-1)],Q=[new mr("lar",-1,-1),new mr("ler",-1,-1)],R=[new mr("niz",-1,-1),new mr("nuz",-1,-1),new mr("nüz",-1,-1),new mr("nız",-1,-1)],U=[new mr("dir",-1,-1),new mr("tir",-1,-1),new mr("dur",-1,-1),new mr("tur",-1,-1),new mr("dür",-1,-1),new mr("tür",-1,-1),new mr("dır",-1,-1),new mr("tır",-1,-1)],V=[new mr("casına",-1,-1),new mr("cesine",-1,-1)],X=[new mr("di",-1,-1),new mr("ti",-1,-1),new mr("dik",-1,-1),new mr("tik",-1,-1),new mr("duk",-1,-1),new mr("tuk",-1,-1),new mr("dük",-1,-1),new mr("tük",-1,-1),new mr("dık",-1,-1),new mr("tık",-1,-1),new mr("dim",-1,-1),new mr("tim",-1,-1),new mr("dum",-1,-1),new mr("tum",-1,-1),new mr("düm",-1,-1),new mr("tüm",-1,-1),new mr("dım",-1,-1),new mr("tım",-1,-1),new mr("din",-1,-1),new mr("tin",-1,-1),new mr("dun",-1,-1),new mr("tun",-1,-1),new mr("dün",-1,-1),new mr("tün",-1,-1),new mr("dın",-1,-1),new mr("tın",-1,-1),new mr("du",-1,-1),new mr("tu",-1,-1),new mr("dü",-1,-1),new mr("tü",-1,-1),new mr("dı",-1,-1),new mr("tı",-1,-1)],Y=[new mr("sa",-1,-1),new mr("se",-1,-1),new mr("sak",-1,-1),new mr("sek",-1,-1),new mr("sam",-1,-1),new mr("sem",-1,-1),new mr("san",-1,-1),new mr("sen",-1,-1)],$=[new mr("miş",-1,-1),new mr("muş",-1,-1),new mr("müş",-1,-1),new mr("mış",-1,-1)],rr=[new mr("b",-1,1),new mr("c",-1,2),new mr("d",-1,3),new mr("ğ",-1,4)],o=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],s=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],c=[65],l=[65],a=[["a",[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["e",[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],101,252],["ı",[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["i",[17],101,105],["o",c,111,117],["ö",l,246,252],["u",c,111,117]],m=new dr;function d(r,i,e){for(;;){var n=m.limit-m.cursor;if(m.in_grouping_b(r,i,e)){m.cursor=m.limit-n;break}if(m.cursor=m.limit-n,m.cursor<=m.limit_backward)return;m.cursor--}return 1}function f(){var r=m.limit-m.cursor;d(o,97,305);for(var i=0;im.limit_backward)&&(m.cursor--,e=m.limit-m.cursor,i()))m.cursor=m.limit-e;else{if(m.cursor=m.limit-n,r())return m.cursor=m.limit-n,!1;if(m.cursor=m.limit-n,m.cursor<=m.limit_backward)return!1;if(m.cursor--,!i())return!1;m.cursor=m.limit-n}return!0}function w(r){return b(r,function(){return m.in_grouping_b(o,97,305)})}function _(){return w(function(){return m.eq_s_b(1,"n")})}function k(){return w(function(){return m.eq_s_b(1,"y")})}function p(){return m.find_among_b(r,10)&&b(function(){return m.in_grouping_b(s,105,305)},function(){return m.out_grouping_b(o,97,305)})}function g(){return f()&&m.in_grouping_b(s,105,305)&&w(function(){return m.eq_s_b(1,"s")})}function y(){return m.find_among_b(e,2)}function z(){return f()&&m.find_among_b(t,4)&&_()}function h(){return f()&&m.find_among_b(Z,4)}function v(){return f()&&m.find_among_b(B,2)}function q(){return f()&&m.find_among_b(J,4)&&k()}function W(){return f()&&m.find_among_b(K,4)}function F(){return f()&&m.find_among_b(M,4)&&k()}function C(){return m.find_among_b(N,4)}function S(){return f()&&m.find_among_b(Q,2)}function P(){return f()&&m.find_among_b(U,8)}function L(){return f()&&m.find_among_b(X,32)&&k()}function x(){return m.find_among_b(Y,8)&&k()}function A(){return f()&&m.find_among_b($,4)&&k()}function ir(){var r=m.limit-m.cursor;return!(A()||(m.cursor=m.limit-r,L())||(m.cursor=m.limit-r,x())||(m.cursor=m.limit-r,m.eq_s_b(3,"ken")&&k()))}function er(){if(m.find_among_b(V,2)){var r=m.limit-m.cursor;if(C()||(m.cursor=m.limit-r,S())||(m.cursor=m.limit-r,q())||(m.cursor=m.limit-r,W())||(m.cursor=m.limit-r,F())||(m.cursor=m.limit-r),A())return}return 1}function nr(){var r;return!(f()&&m.find_among_b(R,4)&&(r=m.limit-m.cursor,L()||(m.cursor=m.limit-r,x())))}function tr(){var r=m.limit-m.cursor;if(m.ket=m.cursor,i=!0,ir()&&(m.cursor=m.limit-r,er())&&(m.cursor=m.limit-r,function(){var r;if(!S())return 1;m.bra=m.cursor,m.slice_del(),r=m.limit-m.cursor,m.ket=m.cursor,P()||(m.cursor=m.limit-r,L())||(m.cursor=m.limit-r,x())||(m.cursor=m.limit-r,A())||(m.cursor=m.limit-r),i=!1}())&&(m.cursor=m.limit-r,nr())&&(m.cursor=m.limit-r,function(){var r=m.limit-m.cursor;if(!(C()||(m.cursor=m.limit-r,F())||(m.cursor=m.limit-r,W())||(m.cursor=m.limit-r,q())))return 1;m.bra=m.cursor,m.slice_del(),r=m.limit-m.cursor,m.ket=m.cursor,A()||(m.cursor=m.limit-r)}())){if(m.cursor=m.limit-r,!P())return;m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,r=m.limit-m.cursor,C()||(m.cursor=m.limit-r,S())||(m.cursor=m.limit-r,q())||(m.cursor=m.limit-r,W())||(m.cursor=m.limit-r,F())||(m.cursor=m.limit-r),A()||(m.cursor=m.limit-r)}m.bra=m.cursor,m.slice_del()}function E(){var r,i;if(m.ket=m.cursor,m.eq_s_b(2,"ki")){if(r=m.limit-m.cursor,h())return m.bra=m.cursor,m.slice_del(),i=m.limit-m.cursor,m.ket=m.cursor,(S()||(m.cursor=m.limit-i,p()&&(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S())))&&(m.bra=m.cursor,m.slice_del(),E()),1;if(m.cursor=m.limit-r,z()){if(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,i=m.limit-m.cursor,y())m.bra=m.cursor,m.slice_del();else{if(m.cursor=m.limit-i,m.ket=m.cursor,!p()&&(m.cursor=m.limit-i,!g())&&(m.cursor=m.limit-i,!E()))return 1;m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S()&&(m.bra=m.cursor,m.slice_del(),E())}return 1}if(m.cursor=m.limit-r,v()){if(i=m.limit-m.cursor,y())m.bra=m.cursor,m.slice_del();else if(m.cursor=m.limit-i,g())m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S()&&(m.bra=m.cursor,m.slice_del(),E());else if(m.cursor=m.limit-i,!E())return;return 1}}}function ur(r){if(m.ket=m.cursor,v()||(m.cursor=m.limit-r,f()&&m.find_among_b(T,2))){r=m.limit-m.cursor;if(y())m.bra=m.cursor,m.slice_del();else if(m.cursor=m.limit-r,g())m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S()&&(m.bra=m.cursor,m.slice_del(),E());else if(m.cursor=m.limit-r,!E())return;return 1}}function or(r){if(m.ket=m.cursor,f()&&m.find_among_b(G,2)||(m.cursor=m.limit-r,f()&&m.find_among_b(n,4)))return r=m.limit-m.cursor,g()||(m.cursor=m.limit-r,y())?(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S()&&(m.bra=m.cursor,m.slice_del(),E()),1):void 0}function sr(){var r=m.limit-m.cursor;return m.ket=m.cursor,(z()||(m.cursor=m.limit-r,f()&&m.find_among_b(H,2)&&k()))&&(m.bra=m.cursor,m.slice_del(),r=m.limit-m.cursor,m.ket=m.cursor,S()&&(m.bra=m.cursor,m.slice_del(),E())||(m.cursor=m.limit-r,m.ket=m.cursor,(p()||(m.cursor=m.limit-r,g())||(m.cursor=m.limit-r,E()))&&(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S())&&(m.bra=m.cursor,m.slice_del(),E())),1)}function cr(){var r,i=m.limit-m.cursor;if(m.ket=m.cursor,h()||(m.cursor=m.limit-i,f()&&m.in_grouping_b(s,105,305)&&k())||(m.cursor=m.limit-i,f()&&m.find_among_b(u,2)&&k())){if(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,i=m.limit-m.cursor,p())m.bra=m.cursor,m.slice_del(),r=m.limit-m.cursor,m.ket=m.cursor,S()||(m.cursor=m.limit-r);else if(m.cursor=m.limit-i,!S())return 1;return m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,E(),1}}function lr(){var r,i=m.limit-m.cursor;if(m.ket=m.cursor,S())m.bra=m.cursor,m.slice_del(),E();else if(m.cursor=m.limit-i,m.ket=m.cursor,f()&&m.find_among_b(I,2)&&_())if(m.bra=m.cursor,m.slice_del(),r=m.limit-m.cursor,m.ket=m.cursor,y())m.bra=m.cursor,m.slice_del();else{if(m.cursor=m.limit-r,m.ket=m.cursor,!p()&&(m.cursor=m.limit-r,!g())){if(m.cursor=m.limit-r,m.ket=m.cursor,!S())return;if(m.bra=m.cursor,m.slice_del(),!E())return}m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S()&&(m.bra=m.cursor,m.slice_del(),E())}else m.cursor=m.limit-i,ur(i)||(m.cursor=m.limit-i,or(i))||(m.cursor=m.limit-i,m.ket=m.cursor,f()&&m.find_among_b(D,4)?(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,r=m.limit-m.cursor,p()?(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S()&&(m.bra=m.cursor,m.slice_del(),E())):(m.cursor=m.limit-r,S()?(m.bra=m.cursor,m.slice_del()):m.cursor=m.limit-r,E())):(m.cursor=m.limit-i,sr()||(m.cursor=m.limit-i,y()?(m.bra=m.cursor,m.slice_del()):(m.cursor=m.limit-i,E()||(m.cursor=m.limit-i,cr())||(m.cursor=m.limit-i,m.ket=m.cursor,(p()||(m.cursor=m.limit-i,g()))&&(m.bra=m.cursor,m.slice_del(),m.ket=m.cursor,S())&&(m.bra=m.cursor,m.slice_del(),E()))))))}function j(r,i,e){if(m.cursor=m.limit-r,!function(){for(;;){var r=m.limit-m.cursor;if(m.in_grouping_b(o,97,305)){m.cursor=m.limit-r;break}if(m.cursor=m.limit-r,m.cursor<=m.limit_backward)return;m.cursor--}return 1}())return 1;var n=m.limit-m.cursor;if(!m.eq_s_b(1,i)&&(m.cursor=m.limit-n,!m.eq_s_b(1,e)))return 1;m.cursor=m.limit-r;i=m.cursor;m.insert(m.cursor,m.cursor,e),m.cursor=i}function O(r,i,e){for(;!m.eq_s(i,e);){if(m.cursor>=m.limit)return 1;m.cursor++}if(i!=m.limit)return 1;m.cursor=r}function ar(){var r,i=m.cursor;if(O(r=m.cursor,2,"ad")&&O(m.cursor=r,5,"soyad")){if(m.limit_backward=i,m.cursor=m.limit,r=m.limit-m.cursor,(m.eq_s_b(1,"d")||(m.cursor=m.limit-r,m.eq_s_b(1,"g")))&&j(r,"a","ı")&&j(r,"e","i")&&j(r,"o","u")&&j(r,"ö","ü"),m.cursor=m.limit,m.ket=m.cursor,i=m.find_among_b(rr,4))switch(m.bra=m.cursor,i){case 1:m.slice_from("p");break;case 2:m.slice_from("ç");break;case 3:m.slice_from("t");break;case 4:m.slice_from("k")}return 1}}this.setCurrent=function(r){m.setCurrent(r)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){return!!(function(){for(var r,i=m.cursor,e=2;;){for(r=m.cursor;!m.in_grouping(o,97,305);){if(m.cursor>=m.limit)return m.cursor=r,!(0 1.0.0 + this.tokenizerFn = lunr.zh.tokenizer; + } + } + }; + + lunr.zh.tokenizer = function(obj) { + if (!arguments.length || obj == null || obj == undefined) return [] + if (Array.isArray(obj)) return obj.map(function(t) { + return isLunr2 ? new lunr.Token(t.toLowerCase()) : t.toLowerCase() + }) + + nodejiebaDictJson && nodejieba.load(nodejiebaDictJson) + + var str = obj.toString().trim().toLowerCase(); + var tokens = []; + + nodejieba.cut(str, true).forEach(function(seg) { + tokens = tokens.concat(seg.split(' ')) + }) + + tokens = tokens.filter(function(token) { + return !!token; + }); + + var fromIndex = 0 + + return tokens.map(function(token, index) { + if (isLunr2) { + var start = str.indexOf(token, fromIndex) + + var tokenMetadata = {} + tokenMetadata["position"] = [start, token.length] + tokenMetadata["index"] = index + + fromIndex = start + + return new lunr.Token(token, tokenMetadata); + } else { + return token + } + }); + } + + /* lunr trimmer function */ + lunr.zh.wordCharacters = "\\w\u4e00-\u9fa5"; + lunr.zh.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.zh.wordCharacters); + lunr.Pipeline.registerFunction(lunr.zh.trimmer, 'trimmer-zh'); + + /* lunr stemmer function */ + lunr.zh.stemmer = (function() { + + /* TODO Chinese stemmer */ + return function(word) { + return word; + } + })(); + lunr.Pipeline.registerFunction(lunr.zh.stemmer, 'stemmer-zh'); + + /* lunr stop word filter. see https://www.ranks.nl/stopwords/chinese-stopwords */ + lunr.generateStopWordFilter = function (stopWords) { + var words = stopWords.reduce(function (memo, stopWord) { + memo[stopWord] = stopWord + return memo + }, {}) + + return function (token) { + if (token && words[token.toString()] !== token.toString()) return token + } + } + + lunr.zh.stopWordFilter = lunr.generateStopWordFilter( + '的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自'.split(' ')); + lunr.Pipeline.registerFunction(lunr.zh.stopWordFilter, 'stopWordFilter-zh'); + }; +})) diff --git a/js/lunr.zh.min.js b/js/lunr.zh.min.js new file mode 100644 index 0000000..6c2e84d --- /dev/null +++ b/js/lunr.zh.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("nodejieba")):r()(e.lunr)}(this,function(n){return function(u,t){if(void 0===u)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===u.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var s="2"==u.version[0];u.zh=function(){this.pipeline.reset(),this.pipeline.add(u.zh.trimmer,u.zh.stopWordFilter,u.zh.stemmer),s?this.tokenizer=u.zh.tokenizer:(u.tokenizer&&(u.tokenizer=u.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=u.zh.tokenizer))},u.zh.tokenizer=function(e){if(!arguments.length||null==e)return[];if(Array.isArray(e))return e.map(function(e){return s?new u.Token(e.toLowerCase()):e.toLowerCase()});t&&n.load(t);var i=e.toString().trim().toLowerCase(),r=[],o=(n.cut(i,!0).forEach(function(e){r=r.concat(e.split(" "))}),r=r.filter(function(e){return!!e}),0);return r.map(function(e,r){var t,n;return s?(t=i.indexOf(e,o),(n={}).position=[t,e.length],n.index=r,o=t,new u.Token(e,n)):e})},u.zh.wordCharacters="\\w一-龥",u.zh.trimmer=u.trimmerSupport.generateTrimmer(u.zh.wordCharacters),u.Pipeline.registerFunction(u.zh.trimmer,"trimmer-zh"),u.zh.stemmer=function(e){return e},u.Pipeline.registerFunction(u.zh.stemmer,"stemmer-zh"),u.generateStopWordFilter=function(e){var r=e.reduce(function(e,r){return e[r]=r,e},{});return function(e){if(e&&r[e.toString()]!==e.toString())return e}},u.zh.stopWordFilter=u.generateStopWordFilter("的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自".split(" ")),u.Pipeline.registerFunction(u.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/js/mathtex-script-type.min.js b/js/mathtex-script-type.min.js new file mode 100644 index 0000000..af02830 --- /dev/null +++ b/js/mathtex-script-type.min.js @@ -0,0 +1 @@ +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("katex"));else if("function"==typeof define&&define.amd)define(["katex"],t);else{var r="object"==typeof exports?t(require("katex")):t(e.katex);for(var n in r)("object"==typeof exports?exports:e)[n]=r[n]}}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var o=r[e];if(void 0!==o)return o.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var o,i,a,u={};return o=n(771),i=n.n(o),a=document.body.getElementsByTagName("script"),(a=Array.prototype.slice.call(a)).forEach((function(e){if(!e.type||!e.type.match(/math\/tex/i))return-1;var t=null!=e.type.match(/mode\s*=\s*display(;|\s|\n|$)/),r=document.createElement(t?"div":"span");r.setAttribute("class",t?"equation":"inline-equation");try{i().render(e.text,r,{displayMode:t})}catch(t){r.textContent=e.text}e.parentNode.replaceChild(r,e)})),u=u.default}()})); \ No newline at end of file diff --git a/js/prestyle.js b/js/prestyle.js new file mode 100644 index 0000000..2516247 --- /dev/null +++ b/js/prestyle.js @@ -0,0 +1,4 @@ +const items = document.querySelectorAll('.preStyle'); +items.forEach(item => { + item.rel = 'stylesheet'; +}); diff --git a/js/search.js b/js/search.js new file mode 100644 index 0000000..30cc278 --- /dev/null +++ b/js/search.js @@ -0,0 +1,366 @@ +window.onload = function() { + if (document.body.contains(document.goSearch)) { + document.goSearch.onsubmit = function() { return goSearchNow() }; + + /* + Source: + - https://github.com/nextapps-de/flexsearch#index-documents-field-search + - https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html + - http://elasticlunr.com/ + - https://github.com/getzola/zola/blob/master/docs/static/search.js + - https://github.com/aaranxu/adidoks/blob/main/static/js/search.js + */ + (function(){ + function inputFocus(e) { + + if (e.keyCode === 191//forward slash + && document.activeElement.tagName !== "INPUT" + && document.activeElement.tagName !== "TEXTAREA") { + e.preventDefault(); + searchinput.focus(); + suggestions.classList.remove('d-none'); + } + + if (e.keyCode === 27 ) {//escape + searchinput.blur(); + suggestions.classList.add('d-none'); + closeAllLists(); + } + + const focusableSuggestions= suggestions.querySelectorAll('a'); + if (suggestions.classList.contains('d-none') + || focusableSuggestions.length === 0) { + return; + } + const focusable= [...focusableSuggestions]; + const index = focusable.indexOf(document.activeElement); + + let nextIndex = 0; + + if (e.keyCode === 38) {//up arrow + e.preventDefault(); + nextIndex= index > 0 ? index-1 : 0; + focusableSuggestions[nextIndex].focus(); + } + else if (e.keyCode === 40) {//down arrow + e.preventDefault(); + nextIndex= index+1 < focusable.length ? index+1 : index; + focusableSuggestions[nextIndex].focus(); + } + + } + + var suggestions = document.getElementById("suggestions"); + var searchinput = document.getElementById("searchinput"); + document.addEventListener("keydown", inputFocus); + document.addEventListener("click", function(event) {suggestions.contains(event.target) || suggestions.classList.add("d-none")}); + + var lang = document.documentElement.getAttribute("lang"); + var langOnly = lang.substring(0, 2); + var baseUrl = document.querySelector("meta[name='base']").getAttribute("content"); + if (baseUrl.slice(-1) == "/") { + baseUrl = baseUrl.slice(0, -1); + } + + var index; + searchinput.addEventListener('input', show_results, true); + suggestions.addEventListener('click', accept_suggestion, true); + + + // in page results when press enter or click search icon from search box + function closeSearchNow() { + const main = document.querySelector("main"); + main.innerHTML = window.main + } + + function goSearchNow() { + const main = document.querySelector("main"); + if (!window.main) { + window.main = main.innerHTML + }; + var results = document.getElementById("suggestions");// suggestions div generated by search box + + var ResultsClone = results.cloneNode(true);// make a clone of the results, so that we can alter it + ResultsClone.id = "results";// alter the id of our clone, so that we can apply different css style + + var headerDiv = document.createElement("div");// create a div element + + var headerContent = '

'.concat(document.getElementById("searchinput").value, "

");// header to use at top of results page + + headerDiv.innerHTML = headerContent;// document element div (headerDiv), set the inner contents to our header html (headerContent) + + ResultsClone.insertBefore(headerDiv, ResultsClone.firstChild);//insert our header div at the top of the page + + main.innerHTML = ResultsClone.outerHTML;//display ResultsClone.outerHTML as the page + results.innerHTML = "";// clear the suggestions div popup + document.getElementById("searchinput").value = "";// clear the search input box + document.body.contains(document.closeSearch) && (document.closeSearch.onsubmit = function() { closeSearchNow() }) + return false + } + + /* Close search suggestion popup list */ + function closeAllLists(elmnt) { + var suggestions = document.getElementById("suggestions"); + while (suggestions.firstChild) { + suggestions.removeChild(suggestions.firstChild); + } + } + + + + async function show_results() { + var initIndex = async function () { + if (index === undefined) { + index = fetch(baseUrl + '/search_index.' + langOnly + '.json') + .then( + async function(response) { + return await elasticlunr.Index.load(await response.json()); + } + ); + } + let res = await index; + return res; + } + var value = this.value.trim(); + var options = { + bool: "OR", + fields: { + title: {boost: 2}, + body: {boost: 1}, + } + }; + //var results = index.search(value, options); + var results = (await initIndex()).search(value, options); + + var entry, childs = suggestions.childNodes; + var i = 0, len = results.length; + var items = value.split(/\s+/); + suggestions.classList.remove('d-none'); + + results.forEach(function(page) { + if (page.doc.body !== '') { + entry = document.createElement('div'); + + entry.innerHTML = ''; + + a = entry.querySelector('a'), + t = entry.querySelector('span:first-child'), + d = entry.querySelector('span:nth-child(2)'); + a.href = page.ref; + t.textContent = page.doc.title; + d.innerHTML = makeTeaser(page.doc.body, items); + + suggestions.appendChild(entry); + } + }); + + while(childs.length > len){ + suggestions.removeChild(childs[i]) + } + + } + + function accept_suggestion(){ + + while(suggestions.lastChild){ + + suggestions.removeChild(suggestions.lastChild); + } + + return false; + } + // Get the string bytes from binary + function getByteByBinary(binaryCode) { + // Binary system, starts with `0b` in ES6 + // Octal number system, starts with `0` in ES5 and starts with `0o` in ES6 + // Hexadecimal, starts with `0x` in both ES5 and ES6 + var byteLengthDatas = [0, 1, 2, 3, 4]; + var len = byteLengthDatas[Math.ceil(binaryCode.length / 8)]; + return len; + } + + // Get the string bytes from hexadecimal + function getByteByHex(hexCode) { + return getByteByBinary(parseInt(hexCode, 16).toString(2)); + } + // Get substring by bytes + // If using JavaScript inline substring method, it will return error codes + // Source: https://www.52pojie.cn/thread-1059814-1-1.html + function substringByByte(str, maxLength) { + var result = ""; + var flag = false; + var len = 0; + var length = 0; + var length2 = 0; + for (var i = 0; i < str.length; i++) { + var code = str.codePointAt(i).toString(16); + if (code.length > 4) { + i++; + if ((i + 1) < str.length) { + flag = str.codePointAt(i + 1).toString(16) == "200d"; + } + } + if (flag) { + len += getByteByHex(code); + if (i == str.length - 1) { + length += len; + if (length <= maxLength) { + result += str.substr(length2, i - length2 + 1); + } else { + break + } + } + } else { + if (len != 0) { + length += len; + length += getByteByHex(code); + if (length <= maxLength) { + result += str.substr(length2, i - length2 + 1); + length2 = i + 1; + } else { + break + } + len = 0; + continue; + } + length += getByteByHex(code); + if (length <= maxLength) { + if (code.length <= 4) { + result += str[i] + } else { + result += str[i - 1] + str[i] + } + length2 = i + 1; + } else { + break + } + } + } + return result; + } + /* Taken from mdbook + // The strategy is as follows: + // First, assign a value to each word in the document: + // Words that correspond to search terms (stemmer aware): 40 + // Normal words: 2 + // First word in a sentence: 8 + // Then use a sliding window with a constant number of words and count the + // sum of the values of the words within the window. Then use the window that got the + // maximum sum. If there are multiple maximas, then get the last one. + // Enclose the terms in . + */ + function makeTeaser(body, terms) { + var TERM_WEIGHT = 40; + var NORMAL_WORD_WEIGHT = 2; + var FIRST_WORD_WEIGHT = 8; + var TEASER_MAX_WORDS = 30; + + var stemmedTerms = terms.map(function (w) { + return elasticlunr.stemmer(w.toLowerCase()); + }); + var termFound = false; + var index = 0; + var weighted = []; // contains elements of ["word", weight, index_in_document] + + // split in sentences, then words + var sentences = body.toLowerCase().split(". "); + for (var i in sentences) { + var words = sentences[i].split(/[\s\n]/); + var value = FIRST_WORD_WEIGHT; + for (var j in words) { + + var word = words[j]; + + if (word.length > 0) { + for (var k in stemmedTerms) { + if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) { + value = TERM_WEIGHT; + termFound = true; + } + } + weighted.push([word, value, index]); + value = NORMAL_WORD_WEIGHT; + } + + index += word.length; + index += 1; // ' ' or '.' if last word in sentence + } + + index += 1; // because we split at a two-char boundary '. ' + } + + if (weighted.length === 0) { + if (body.length !== undefined && body.length > TEASER_MAX_WORDS * 10) { + return body.substring(0, TEASER_MAX_WORDS * 10) + '...'; + } else { + return body; + } + } + + var windowWeights = []; + var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS); + // We add a window with all the weights first + var curSum = 0; + for (var i = 0; i < windowSize; i++) { + curSum += weighted[i][1]; + } + windowWeights.push(curSum); + + for (var i = 0; i < weighted.length - windowSize; i++) { + curSum -= weighted[i][1]; + curSum += weighted[i + windowSize][1]; + windowWeights.push(curSum); + } + + // If we didn't find the term, just pick the first window + var maxSumIndex = 0; + if (termFound) { + var maxFound = 0; + // backwards + for (var i = windowWeights.length - 1; i >= 0; i--) { + if (windowWeights[i] > maxFound) { + maxFound = windowWeights[i]; + maxSumIndex = i; + } + } + } + + var teaser = []; + var startIndex = weighted[maxSumIndex][2]; + for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) { + var word = weighted[i]; + if (startIndex < word[2]) { + // missing text from index to start of `word` + teaser.push(body.substring(startIndex, word[2])); + startIndex = word[2]; + } + + // add around search terms + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + + startIndex = word[2] + word[0].length; + // Check the string is ascii characters or not + var re = /^[\x00-\xff]+$/ + if (word[1] !== TERM_WEIGHT && word[0].length >= 12 && !re.test(word[0])) { + // If the string's length is too long, it maybe a Chinese/Japance/Korean article + // if using substring method directly, it may occur error codes on emoji chars + var strBefor = body.substring(word[2], startIndex); + var strAfter = substringByByte(strBefor, 12); + teaser.push(strAfter); + } else { + teaser.push(body.substring(word[2], startIndex)); + } + + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + } + teaser.push("…"); + return teaser.join(""); + } + document.goSearch.onsubmit = function() { return goSearchNow() }; + }()); + } +}; diff --git a/js/search_elasticlunr.min.js b/js/search_elasticlunr.min.js new file mode 100644 index 0000000..f0bb867 --- /dev/null +++ b/js/search_elasticlunr.min.js @@ -0,0 +1 @@ +!function(){function g(e){var t=new g.Index;return t.pipeline.add(g.trimmer,g.stopWordFilter,g.stemmer),e&&e.call(t,t),t}var a,c,e,t,d,h,f,p,m,v,y,S,x,b,w,I,E,D,F,C,_,k,N,P,n;g.version="0.9.5",((lunr=g).utils={}).warn=(n=this,function(e){n.console}),g.utils.toString=function(e){return null==e?"":e.toString()},(g.EventEmitter=function(){this.events={}}).prototype.addListener=function(){var e=[].slice.call(arguments),t=e.pop();if("function"!=typeof t)throw new TypeError("last argument must be a function");e.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},g.EventEmitter.prototype.removeListener=function(e,t){this.hasHandler(e)&&-1!=(t=this.events[e].indexOf(t))&&(this.events[e].splice(t,1),0==this.events[e].length)&&delete this.events[e]},g.EventEmitter.prototype.emit=function(e){var t;this.hasHandler(e)&&(t=[].slice.call(arguments,1),this.events[e].forEach(function(e){e.apply(void 0,t)},this))},g.EventEmitter.prototype.hasHandler=function(e){return e in this.events},(g.tokenizer=function(e){var t,n;return arguments.length&&null!=e?Array.isArray(e)?(t=(t=e.filter(function(e){return null!=e})).map(function(e){return g.utils.toString(e).toLowerCase()}),n=[],t.forEach(function(e){e=e.split(g.tokenizer.seperator);n=n.concat(e)},this),n):e.toString().trim().toLowerCase().split(g.tokenizer.seperator):[]}).defaultSeperator=/[\s\-]+/,g.tokenizer.seperator=g.tokenizer.defaultSeperator,g.tokenizer.setSeperator=function(e){null!=e&&"object"==typeof e&&(g.tokenizer.seperator=e)},g.tokenizer.resetSeperator=function(){g.tokenizer.seperator=g.tokenizer.defaultSeperator},g.tokenizer.getSeperator=function(){return g.tokenizer.seperator},(g.Pipeline=function(){this._queue=[]}).registeredFunctions={},g.Pipeline.registerFunction=function(e,t){t in g.Pipeline.registeredFunctions&&g.utils.warn("Overwriting existing registered function: "+t),e.label=t,g.Pipeline.registeredFunctions[t]=e},g.Pipeline.getRegisteredFunction=function(e){return e in g.Pipeline.registeredFunctions!=1?null:g.Pipeline.registeredFunctions[e]},g.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||g.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},g.Pipeline.load=function(e){var n=new g.Pipeline;return e.forEach(function(e){var t=g.Pipeline.getRegisteredFunction(e);if(!t)throw Error("Cannot load un-registered function: "+e);n.add(t)}),n},g.Pipeline.prototype.add=function(){[].slice.call(arguments).forEach(function(e){g.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},g.Pipeline.prototype.after=function(e,t){g.Pipeline.warnIfFunctionNotRegistered(t);e=this._queue.indexOf(e);if(-1==e)throw Error("Cannot find existingFn");this._queue.splice(1+e,0,t)},g.Pipeline.prototype.before=function(e,t){g.Pipeline.warnIfFunctionNotRegistered(t);e=this._queue.indexOf(e);if(-1==e)throw Error("Cannot find existingFn");this._queue.splice(e,0,t)},g.Pipeline.prototype.remove=function(e){e=this._queue.indexOf(e);-1!=e&&this._queue.splice(e,1)},g.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,o=this._queue.length,i=0;i=n&&r-1>=o;)s[n]!==u[o]?s[n]u[o]&&o++:(t.add(s[n]),n++,o++);return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){for(var t,e=this.length

'.concat(document.getElementById("searchinput").value,"

");return o.innerHTML=i,n.insertBefore(o,n.firstChild),e.innerHTML=n.outerHTML,t.innerHTML="",document.getElementById("searchinput").value="",document.body.contains(document.closeSearch)&&(document.closeSearch.onsubmit=function(){document.querySelector("main").innerHTML=window.main}),!1}function b(e){return e=parseInt(e,16).toString(2),[0,1,2,3,4][Math.ceil(e.length/8)]}var u,r,l,c,h;document.body.contains(document.goSearch)&&(document.goSearch.onsubmit=function(){return goSearchNow()},u=document.getElementById("suggestions"),r=document.getElementById("searchinput"),document.addEventListener("keydown",function(t){if(191===t.keyCode&&"INPUT"!==document.activeElement.tagName&&"TEXTAREA"!==document.activeElement.tagName&&(t.preventDefault(),r.focus(),u.classList.remove("d-none")),27===t.keyCode){r.blur(),u.classList.add("d-none");for(var e=document.getElementById("suggestions");e.firstChild;)e.removeChild(e.firstChild)}var n=u.querySelectorAll("a");if(!u.classList.contains("d-none")&&0!==n.length){var o=[...n],i=o.indexOf(document.activeElement);let e=0;38===t.keyCode?(t.preventDefault(),n[e=0",a=n.querySelector("a"),t=n.querySelector("span:first-child"),d=n.querySelector("span:nth-child(2)"),a.href=e.ref,t.textContent=e.doc.title,d.innerHTML=function(e,t){var n=t.map(function(e){return elasticlunr.stemmer(e.toLowerCase())}),o=!1,i=0,r=[],s=e.toLowerCase().split(". ");for(p in s){var u,l=s[p].split(/[\s\n]/),a=8;for(u in l){if(0<(S=l[u]).length){for(var c in n)elasticlunr.stemmer(S).startsWith(n[c])&&(a=40,o=!0);r.push([S,a,i]),a=2}i=i+S.length+1}i+=1}if(0===r.length)return void 0!==e.length&&300"),y=S[2]+S[0].length;40===S[1]||S[0].length<12||/^[\x00-\xff]+$/.test(S[0])?v.push(e.substring(S[2],y)):(x=function(e,t){for(var n="",o=!1,i=0,r=0,s=0,u=0;u")}return v.push("…"),v.join("")}(e.doc.body,s),u.appendChild(n))});i.length>r;)u.removeChild(i[0])},!0),u.addEventListener("click",function(){for(;u.lastChild;)u.removeChild(u.lastChild);return!1},!0),document.goSearch.onsubmit=e)}; \ No newline at end of file diff --git a/js/search_elasticlunr_jindex.min.js b/js/search_elasticlunr_jindex.min.js new file mode 100644 index 0000000..5544d4b --- /dev/null +++ b/js/search_elasticlunr_jindex.min.js @@ -0,0 +1 @@ +window.searchIndex={fields:["title","description","body"],pipeline:["trimmer","stopWordFilter","stemmer"],ref:"id",version:"0.9.5",index:{body:{root:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.8284271247461903},"https://abridge.netlify.app/overview-images/":{tf:6.244997998398398}},df:2,".":{docs:{},df:0,1:{docs:{},df:0,7:{docs:{},df:0,".":{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}},5:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-images/":{tf:6},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:4,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"!":{docs:{},df:0,d:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,y:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}},".":{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},8:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},9:{docs:{},df:0,":":{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},"/":{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-images/":{tf:3.4641016151377544}},df:2,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}}},0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1}},df:2},5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,1:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},t:{docs:{},df:0,a:{docs:{},df:0,x:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},1:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:2.6457513110645907}},df:2,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,1:{docs:{},df:0,1:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},z:{docs:{},df:0,'"':{docs:{},df:0,"/":{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}},2:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:3.872983346207417}},df:2,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},3:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178}},df:2,l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,1:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},4:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:4.242640687119285}},df:2,h:{docs:{},df:0,7:{docs:{},df:0,c:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},5:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178}},df:2,h:{docs:{},df:0,5:{docs:{},df:0,l:{docs:{},df:0,1:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}},6:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,0:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},c:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},7:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},8:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:3},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3,4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},h:{docs:{},df:0,6:{docs:{},df:0,l:{docs:{},df:0,1:{docs:{},df:0,7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},z:{docs:{},df:0,'"':{docs:{},df:0,"/":{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}},p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}},9:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:3.1622776601683795}},df:3,2:{docs:{},df:0,x:{docs:{},df:0,1:{docs:{},df:0,9:{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,".":{docs:{},df:0,p:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},m:{docs:{},df:0,".":{docs:{},df:0,p:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},":":{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},b:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,_:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}},c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,2:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}},2:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:6},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:4,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}},0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:2.23606797749979}},df:2,1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,5:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},2:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},2:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}},6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},v:{docs:{},df:0,5:{docs:{},df:0,l:{docs:{},df:0,7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},1:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178}},df:2,4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},5:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},l:{docs:{},df:0,5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},2:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:1,2:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,2:{docs:{},df:0,2:{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1}}},3:{docs:{},df:0,l:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2.23606797749979}},df:1,7:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,2:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2.23606797749979}},df:1,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},7:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},8:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},9:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},9:{docs:{},df:0,c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},":":{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},c:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},l:{docs:{},df:0,1:{docs:{},df:0,8:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},2:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},t:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},3:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:2},"https://abridge.netlify.app/overview-images/":{tf:6.557438524302},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:4,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}},0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:2,2:{docs:{},df:0,c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},1:{docs:{},df:0,c:{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},2:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,4:{docs:{},df:0,c:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,v:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},8:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:1,c:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},l:{docs:{},df:0,2:{docs:{},df:0,9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},d:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},v:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},4:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-images/":{tf:5.477225575051661},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:4,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,".":{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}},a:{docs:{},df:0,1:{docs:{},df:0,1:{docs:{},df:0,6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},6:{docs:{},df:0,c:{docs:{},df:0,2:{docs:{},df:0,7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2}},df:1},8:{docs:{},df:0,9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},d:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,_:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}},h:{docs:{},df:0,7:{docs:{},df:0,l:{docs:{},df:0,2:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},l:{docs:{},df:0,2:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},z:{docs:{},df:0,m:{docs:{},df:0,4:{docs:{},df:0,0:{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}},5:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:5.5677643628300215},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:4,"#":{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},1:{docs:{},df:0,2:{docs:{},df:0,x:{docs:{},df:0,5:{docs:{},df:0,1:{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,".":{docs:{},df:0,p:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},2:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},z:{docs:{},df:0,'"':{docs:{},df:0,"/":{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}},3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},5:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1},6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,c:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},7:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},8:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},c:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},h:{docs:{},df:0,6:{docs:{},df:0,l:{docs:{},df:0,2:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},v:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},z:{docs:{},df:0,'"':{docs:{},df:0,"/":{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,g:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}},6:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:5.0990195135927845}},df:2,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}}},0:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,"*":{docs:{},df:0,6:{docs:{},df:0,0:{docs:{},df:0,"*":{docs:{},df:0,2:{docs:{},df:0,4:{docs:{},df:0,"*":{docs:{},df:0,3:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},1:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},3:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},4:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2,0:{docs:{},df:0,".":{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}},w:{docs:{},df:0,e:{docs:{},df:0,b:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}},5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,3:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:1}},7:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:5}},df:2,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,y:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}},1:{docs:{},df:0,z:{docs:{},df:0,'"':{docs:{},df:0,"/":{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}},7:{docs:{},df:0,7:{docs:{},df:0,7:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},b:{docs:{},df:0,u:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,d:{docs:{},df:0,_:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}},l:{docs:{},df:0,2:{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},z:{docs:{},df:0,'"':{docs:{},df:0,"/":{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}},8:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:3.1622776601683795},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}},0:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},4:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},m:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,y:{docs:{},df:0,_:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},9:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:3}},df:3,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,y:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}}},0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}},3:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1},5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1},6:{docs:{},df:0,0:{docs:{},df:0,".":{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}},f:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,d:{docs:{},df:0,_:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},l:{docs:{},df:0,3:{docs:{},df:0,6:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},4:{docs:{},df:0,9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},_:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,s:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,"[":{docs:{},df:0,"'":{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,_:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}},s:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,"[":{docs:{},df:0,"'":{docs:{},df:0,p:{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,_:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,k:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}},a:{docs:{},df:0,b:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,e:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},o:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/about/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-abridge/":{tf:4.123105625617661},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979}},df:3,e:{docs:{},df:0,'"':{docs:{},df:0,"/":{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},".":{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:3}}},n:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,y:{docs:{},df:0,".":{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}},s:{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},m:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},s:{docs:{},df:0,"(":{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}},c:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},o:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},u:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1,s:{docs:{},df:0,_:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{},df:0,e:{docs:{},df:0,_:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,_:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},x:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},u:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}},d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:5,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:2.449489742783178}},df:5,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}},o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},r:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}},j:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},m:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},v:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}},f:{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1}},df:2}}}},t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,w:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},g:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2}}},r:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}},h:{docs:{},df:0,o:{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},j:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{},df:0,a:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,f:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}},l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,2:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},g:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},q:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},l:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:3,f:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},o:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},t:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:2.8284271247461903}},df:4,"=":{docs:{},df:0,'"':{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:3.4641016151377544}},df:1}}}}},i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},w:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}}},"ı":{docs:{},df:0,"ş":{docs:{},df:0,t:{docs:{},df:0,"ı":{docs:{},df:0,r:{docs:{},df:0,"ı":{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,r:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,t:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}},m:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,";":{docs:{},df:0,"&":{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},n:{docs:{},df:0,d:{docs:{},df:0,"/":{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:2.449489742783178}},df:1}}},a:{docs:{},df:0,e:{docs:{},df:0,p:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},r:{docs:{},df:0,o:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:2}}}}},n:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},o:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:1}}},t:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},y:{docs:{},df:0,w:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},p:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,a:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,"/":{docs:{},df:0,j:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}},s:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},v:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{},df:0,"+":{docs:{},df:0,x:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,"+":{docs:{},df:0,r:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}}},q:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},i:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},e:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},n:{docs:{},df:0,"'":{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}}}},i:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,"'":{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},2:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}},o:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},r:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:2.6457513110645907}},df:1}},o:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},t:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1}},df:7}}}}},s:{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},t:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},o:{docs:{},df:0,m:{docs:{},df:0,".":{docs:{},df:0,x:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}}}}},u:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:3}},df:2,"(":{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,"=":{docs:{},df:0,"[":{docs:{},df:0,'"':{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,".":{docs:{},df:0,o:{docs:{},df:0,g:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}},g:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},s:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{},df:0,"ü":{docs:{},df:0,h:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.8284271247461903}},df:1,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:2,"/":{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{},df:0,"/":{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}},m:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3}}},p:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1}},df:1}}},l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:3}}}},r:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:1}}}}}}},v:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},w:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},b:{docs:{},df:0,$:{docs:{},df:0,2:{docs:{},df:0,5:{docs:{},df:0,4:{docs:{},df:0,$:{docs:{},df:0,2:{docs:{},df:0,4:{docs:{},df:0,9:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,2:{docs:{},df:0,7:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,2:{docs:{},df:0,4:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,2:{docs:{},df:0,3:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,1:{docs:{},df:0,3:{docs:{},df:0,$:{docs:{},df:0,8:{docs:{},df:0,8:{docs:{},df:0,$:{docs:{},df:0,8:{docs:{},df:0,3:{docs:{},df:0,$:{docs:{},df:0,7:{docs:{},df:0,4:{docs:{},df:0,$:{docs:{},df:0,6:{docs:{},df:0,1:{docs:{},df:0,$:{docs:{},df:0,5:{docs:{},df:0,5:{docs:{},df:0,$:{docs:{},df:0,5:{docs:{},df:0,4:{docs:{},df:0,$:{docs:{},df:0,3:{docs:{},df:0,8:{docs:{},df:0,$:{docs:{},df:0,3:{docs:{},df:0,1:{docs:{},df:0,$:{docs:{},df:0,3:{docs:{},df:0,0:{docs:{},df:0,$:{docs:{},df:0,2:{docs:{},df:0,8:{docs:{},df:0,$:{docs:{},df:0,2:{docs:{},df:0,7:{docs:{},df:0,$:{docs:{},df:0,2:{docs:{},df:0,2:{docs:{},df:0,$:{docs:{},df:0,2:{docs:{},df:0,1:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,9:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,7:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,6:{docs:{},df:0,$:{docs:{},df:0,1:{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},a:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2,g:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,_:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},t:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},n:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}},d:{docs:{},df:0,w:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},n:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,e:{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},s:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1},h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:2.23606797749979}},df:1,c:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:1}}}},e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,b:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},u:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}},c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},f:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}},l:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},n:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}},t:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1}},df:2}}},w:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2}}}}},w:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{},df:0,b:{docs:{},df:0,a:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},i:{docs:{},df:0,n:{docs:{},df:0,"/":{docs:{},df:0,b:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,m:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},l:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3}},df:1}}},i:{docs:{},df:0,n:{docs:{},df:0,k:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}},o:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2},"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:4,q:{docs:{},df:0,u:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.23606797749979}},df:1}}}}}}},u:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,s:{docs:{},df:0,h:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},m:{docs:{},df:0,e:{docs:{},df:0,2:{docs:{},df:0,8:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},o:{docs:{},df:0,b:{docs:{},df:0,2:{docs:{},df:0,7:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},n:{docs:{},df:0,j:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},o:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}}}},t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2},t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},r:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}},o:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}},w:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2.8284271247461903},"https://abridge.netlify.app/privacy/":{tf:1}},df:4,"/":{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}}}}}},u:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.1622776601683795}},df:1,_:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}},n:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},d:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.8284271247461903}},df:1}}},t:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907}},df:1}}}}},"ạ":{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178}},df:1,1:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},2:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},a:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/offline/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907}},df:2}},l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},n:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},g:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},s:{docs:{},df:0,c:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,e:{docs:{},df:0,g:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2}}}}}}},c:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178}},df:1},e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},h:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3}},r:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},s:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}}}}}}}},e:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,_:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}},e:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},i:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},r:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:2}}}},"à":{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},i:{docs:{},df:0,a:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1}},df:2,a:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:2}},df:7,"=":{docs:{},df:0,'"':{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:3}},df:1}}},s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},y:{docs:{},df:0,v:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}},i:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}}}}}},i:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,".":{docs:{},df:0,w:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,_:{docs:{},df:0,p:{docs:{},df:0,o:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,s:{docs:{},df:0,"(":{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}},p:{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},o:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178}},df:1}},s:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-code-blocks/":{tf:4},"https://abridge.netlify.app/overview-images/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.23606797749979}},df:4,c:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{},df:0,y:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},y:{docs:{},df:0,3:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},l:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.4641016151377544},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}},m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2},m:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,m:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},s:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},u:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}},p:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1}},df:2}},l:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},r:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}},n:{docs:{},df:0,c:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,"(":{docs:{},df:0,d:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,".":{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,b:{docs:{},df:0,y:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,p:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,".":{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},d:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},e:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,i:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1,".":{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},e:{docs:{},df:0,x:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:4.242640687119285},"https://abridge.netlify.app/overview-math/":{tf:1}},df:2}}}}},":":{docs:{},df:0,":":{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3}},df:1}}}}},n:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/offline/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:2}}}},s:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},t:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/contact/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:2}}},e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:5,"/":{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,s:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2}},df:1}}}}}}}}}},o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.7320508075688772}},df:1,".":{docs:{},df:0,f:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},m:{docs:{},df:0,p:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},o:{docs:{},df:0,g:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},w:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},_:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,1:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}},v:{docs:{},df:0,p:{docs:{},df:0,9:{docs:{},df:0,".":{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,b:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}},s:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},"\\":{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}},r:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,s:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}}},v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}}}}},o:{docs:{},df:0,k:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/privacy/":{tf:1}},df:4}}},p:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907}},df:1}},r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},n:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},r:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},u:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}},t:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1},r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:5,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3}},t:{docs:{},df:0,r:{docs:{},df:0,l:{docs:{},df:0,"+":{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,"+":{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}},f:{docs:{},df:0,5:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,l:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1,u:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},r:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}},s:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:7}}}}},z:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},"ó":{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}},d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,3:{docs:{},df:0,c:{docs:{},df:0,3:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},"=":{docs:{},df:0,'"':{docs:{},df:0,m:{docs:{},df:0,2:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},2:{docs:{},df:0,7:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},3:{docs:{},df:0,3:{docs:{},df:0,9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},6:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},5:{docs:{},df:0,6:{docs:{},df:0,5:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},7:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},9:{docs:{},df:0,9:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},a:{docs:{},df:0,i:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},n:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.4641016151377544}},df:1}},t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-showdata/":{tf:1.7320508075688772},"https://abridge.netlify.app/privacy/":{tf:1}},df:3},e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1.4142135623730951}},df:3}},y:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},d:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},e:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},f:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3},"https://abridge.netlify.app/overview-code-blocks/":{tf:3},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:6}}}},i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}}},j:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},m:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:2,n:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},n:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},p:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},l:{docs:{},df:0,o:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:4}}}}},i:{docs:{},df:0,g:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:2}},r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}},k:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},v:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,"/":{docs:{},df:0,p:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}},e:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},i:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},f:{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2}},df:2}},i:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},r:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:2}},o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1}}}}}}},s:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1,e:{docs:{},df:0,d:{docs:{},df:0,"/":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-showdata/":{tf:1.7320508075688772}},df:5}}}}},v:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:1}}}}}},o:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,u:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}}}}}}}}}}},".":{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}},g:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,b:{docs:{},df:0,y:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,p:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,".":{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}},u:{docs:{},df:0,g:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}},q:{docs:{},df:0,u:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}}}}},e:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},e:{docs:{},df:0,s:{docs:{},df:0,n:{docs:{},df:0,"'":{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:2.449489742783178}},df:1}}}}},l:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},t:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}},l:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}},u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},n:{docs:{},df:0,"'":{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},r:{docs:{},df:0,a:{docs:{},df:0,f:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},o:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}},u:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},t:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},x:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}}}}}}}}}},y:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},"ü":{docs:{},df:0,z:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}},e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979}},df:1,".":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}}}}}}}}},"^":{docs:{},df:0,"{":{docs:{},df:0,i:{docs:{},df:0,"\\":{docs:{},df:0,p:{docs:{},df:0,i:{docs:{},df:0,"}":{docs:{},df:0,"+":{docs:{},df:0,1:{docs:{},df:0,"=":{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:1}}}}}}}}}}},a:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2}},df:3}},s:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:4}}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:2,a:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},i:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},"á":{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},y:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},f:{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}}}},g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},i:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},j:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}},l:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,l:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3}},df:1,".":{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}},e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-rich-content/":{tf:1.7320508075688772}},df:2}}}}},i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},s:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},c:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1}}}},s:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{},df:0,j:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1}}}}}}}}}},b:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3,e:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:5}}}},n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-math/":{tf:2.6457513110645907}},df:2}}},d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:4,i:{docs:{},df:0,g:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},l:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},i:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},o:{docs:{},df:0,u:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:2}},i:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},v:{docs:{},df:0,i:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}},o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:1,s:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},q:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}},r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,c:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},e:{docs:{},df:0,g:{docs:{},df:0,u:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}},p:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:2,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1.7320508075688772}},df:2,"/":{docs:{},df:0,n:{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,x:{docs:{},df:0,"/":{docs:{},df:0,n:{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}},u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},v:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1},r:{docs:{},df:0,y:{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},x:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},m:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:5}}}},c:{docs:{},df:0,e:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},r:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},e:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,"á":{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}},r:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},i:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}},p:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},e:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},i:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2}}}}},q:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}},t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},e:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},s:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:1}},r:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:2}}},r:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:2.449489742783178}},df:3}}},"é":{docs:{},df:0,c:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178}},df:2,"(":{docs:{},df:0,"\\":{docs:{},df:0,x:{docs:{},df:0,i:{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,e:{docs:{},df:0,"^":{docs:{},df:0,"{":{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}},"\\":{docs:{},df:0,",":{docs:{},df:0,e:{docs:{},df:0,"^":{docs:{},df:0,"{":{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}}}}},x:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1}},1:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},2:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,c:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},b:{docs:{},df:0,o:{docs:{},df:0,o:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},i:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},i:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}},l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,b:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,_:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}},s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:4.123105625617661},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:5},t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,"=":{docs:{},df:0,'"':{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},s:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:3}}},e:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1}},df:3,e:{docs:{},df:0,s:{docs:{},df:0,'"':{docs:{},df:0,",":{docs:{},df:0,'"':{docs:{},df:0,s:{docs:{},df:0,h:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,'"':{docs:{},df:0,",":{docs:{},df:0,'"':{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}},e:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,s:{docs:{},df:0,"]":{docs:{},df:0,"(":{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2}}}}}}}}}}}}}}}}},f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},h:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,"=":{docs:{},df:0,4:{docs:{},df:0,8:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},i:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:3}}},g:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}},l:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:5.656854249492381},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:5,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2.23606797749979}},df:1}}}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,"=":{docs:{},df:0,'"':{docs:{},df:0,"#":{docs:{},df:0,8:{docs:{},df:0,f:{docs:{},df:0,1:{docs:{},df:0,f:{docs:{},df:0,1:{docs:{},df:0,d:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}},f:{docs:{},df:0,f:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1}}}}}}}},n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,f:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}},i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},n:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},r:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1},e:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:4}}}},l:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,".":{docs:{},df:0,p:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,n:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}},n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},o:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},l:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},l:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}},n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-code-blocks/":{tf:3.4641016151377544}},df:2,"/":{docs:{},df:0,e:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},o:{docs:{},df:0,p:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,y:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},t:{docs:{},df:0,t:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},a:{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},e:{docs:{},df:0,x:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}},o:{docs:{},df:0,b:{docs:{},df:0,j:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},o:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}},r:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/contact/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:2.6457513110645907}},df:3}},u:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},u:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/offline/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},r:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},p:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,"=":{docs:{},df:0,'"':{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}}}}}},r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},e:{docs:{},df:0,n:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}},u:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:1}}}},s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},u:{docs:{},df:0,g:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},l:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},n:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,t:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:3,s:{docs:{},df:0,".":{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}},r:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,$:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}}}}},s:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,"ó":{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,h:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}},w:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,"=":{docs:{},df:0,6:{docs:{},df:0,4:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},g:{docs:{"https://abridge.netlify.app/about/":{tf:1}},df:1,e:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:3.3166247903554}},df:2}}},r:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},s:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,p:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178}},df:1}}}}}}}}},t:{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,_:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}},p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},s:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,".":{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,_:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}}},p:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,z:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,"(":{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,s:{docs:{},df:0,p:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}},i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2.6457513110645907}},df:3,"(":{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,"=":{docs:{},df:0,"[":{docs:{},df:0,'"':{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,_:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,1:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3}},df:1}},l:{docs:{},df:0,o:{docs:{},df:0,b:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-math/":{tf:2}},df:1}}}}},o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},k:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1}},df:2},g:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:2}}},p:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}},s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1,i:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{},df:0,s:{docs:{},df:0,".":{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,"(":{docs:{},df:0,")":{docs:{},df:0,".":{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}},o:{docs:{},df:0,u:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:5.477225575051661},"https://abridge.netlify.app/overview-images/":{tf:3},"https://abridge.netlify.app/overview-rich-content/":{tf:3.4641016151377544}},df:3,";":{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},z:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1,"/":{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}},_:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,f:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,_:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}},h:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,p:{docs:{},df:0,_:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},p:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,x:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},t:{docs:{},df:0,y:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},v:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178}},df:2,1:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},2:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},3:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},4:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},5:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},6:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},a:{docs:{},df:0,l:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/about/":{tf:1}},df:1},l:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}},n:{docs:{},df:0,d:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},p:{docs:{},df:0,p:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1},y:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2}},df:1}}}}}}},r:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},s:{docs:{},df:0,_:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,d:{docs:{},df:0,_:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}},e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}},v:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}},i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:2},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:3,"=":{docs:{},df:0,'"':{docs:{},df:0,4:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:3}},df:1}},8:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1},9:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}},j:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1},l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2}},p:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},v:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}},r:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2.449489742783178}},df:3}},y:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},l:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:3}}}}}}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}},o:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},r:{docs:{},df:0,i:{docs:{},df:0,z:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1}}}},r:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,p:{docs:{},df:0,s:{docs:{},df:0,":":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,".":{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:5,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}},5:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}},"|":{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{},df:0,"|":{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{},df:0,"|":{docs:{},df:0,j:{docs:{},df:0,s:{docs:{},df:0,"|":{docs:{},df:0,x:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{},df:0,"|":{docs:{},df:0,x:{docs:{},df:0,s:{docs:{},df:0,l:{docs:{},df:0,"|":{docs:{},df:0,t:{docs:{},df:0,x:{docs:{},df:0,t:{docs:{},df:0,"|":{docs:{},df:0,w:{docs:{},df:0,o:{docs:{},df:0,f:{docs:{},df:0,f:{docs:{},df:0,"|":{docs:{},df:0,w:{docs:{},df:0,o:{docs:{},df:0,f:{docs:{},df:0,f:{docs:{},df:0,2:{docs:{},df:0,"|":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{},df:0,"|":{docs:{},df:0,o:{docs:{},df:0,t:{docs:{},df:0,f:{docs:{},df:0,"|":{docs:{},df:0,e:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{},df:0,"|":{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,p:{docs:{},df:0,"(":{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1},":":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,1:{docs:{},df:0,2:{docs:{},df:0,7:{docs:{},df:0,".":{docs:{},df:0,0:{docs:{},df:0,".":{docs:{},df:0,0:{docs:{},df:0,".":{docs:{},df:0,1:{docs:{},df:0,":":{docs:{},df:0,1:{docs:{},df:0,1:{docs:{},df:0,1:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}},s:{docs:{},df:0,":":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,y:{docs:{},df:0,".":{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}},g:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,"/":{docs:{},df:0,j:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,2:{docs:{},df:0,3:{docs:{},df:0,0:{docs:{},df:0,"/":{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}},y:{docs:{},df:0,x:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,"/":{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}},i:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,k:{docs:{},df:0,u:{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,"/":{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},j:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,k:{docs:{},df:0,u:{docs:{},df:0,".":{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{},df:0,".":{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},u:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.8284271247461903}},df:1,i:{docs:{},df:0,t:{docs:{},df:0,y:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,5:{docs:{},df:0,5:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}},n:{docs:{},df:0,g:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},"ä":{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},i:{docs:{},df:0,"'":{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1},v:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}},c:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.3166247903554},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:2}}},d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.7320508075688772}},df:4,e:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},b:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},f:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951}},df:3}}}},g:{docs:{},df:0,n:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},m:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.4641016151377544},"https://abridge.netlify.app/overview-images/":{tf:4.242640687119285},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2.23606797749979}},df:4,e:{docs:{},df:0,"(":{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,"=":{docs:{},df:0,"[":{docs:{},df:0,'"':{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}},"/":{docs:{},df:0,p:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}},s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{},df:0,"+":{docs:{},df:0,x:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}},g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2,"(":{docs:{},df:0,s:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,".":{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,g:{docs:{},df:0,"/":{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}},"/":{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}},f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}},s:{docs:{},df:0,w:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2,"(":{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,_:{docs:{},df:0,s:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,".":{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,g:{docs:{},df:0,"/":{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}},"/":{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}},f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}},p:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}}},o:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}}},r:{docs:{},df:0,o:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},n:{docs:{},df:0,c:{docs:{},df:0,l:{docs:{},df:0,u:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:3}}},t:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,".":{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},i:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}}}}}},f:{docs:{},df:0,l:{docs:{},df:0,u:{docs:{},df:0,x:{docs:{},df:0,d:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1,c:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}},o:{docs:{},df:0,r:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1}},df:2}}},t:{docs:{},df:0,y:{docs:{},df:0,"}":{docs:{},df:0,"^":{docs:{},df:0,"\\":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,f:{docs:{},df:0,t:{docs:{},df:0,y:{docs:{},df:0,"\\":{docs:{},df:0,h:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}},i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}},l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:3}}},p:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},s:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},r:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},p:{docs:{},df:0,i:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/about/":{tf:1}},df:1}}},t:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.1622776601683795}},df:1},n:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1}}}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1,"(":{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}},_:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1,0:{docs:{},df:0,"^":{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}},e:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},r:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}},o:{docs:{},df:0,m:{docs:{},df:0,m:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},p:{docs:{},df:0,s:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},s:{docs:{},df:0,_:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},d:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1},s:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,"(":{docs:{},df:0,$:{docs:{},df:0,_:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,"[":{docs:{},df:0,"'":{docs:{},df:0,p:{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,_:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,k:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,"'":{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},a:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},c:{docs:{},df:0,s:{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,d:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,k:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},e:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.449489742783178}},df:2}}}},j:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,k:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/about/":{tf:1}},df:1}},n:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1},p:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},v:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2}}}}}}}}},e:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},i:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,k:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/about/":{tf:1}},df:1}}}}},o:{docs:{},df:0,h:{docs:{},df:0,n:{docs:{},df:0,5:{docs:{},df:0,9:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},p:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},s:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:3,_:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}}},c:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{},df:0,y:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,_:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}},p:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,y:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},s:{docs:{},df:0,w:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,_:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}}}}},o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1,b:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},t:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-math/":{tf:3.7416573867739413}},df:2,"(":{docs:{},df:0,b:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{},df:0,"=":{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}},t:{docs:{},df:0,r:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}}}}}}}}},b:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},e:{docs:{},df:0,e:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},r:{docs:{},df:0,r:{docs:{},df:0,y:{docs:{},df:0,2:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},y:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:3,"=":{docs:{},df:0,'"':{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,_:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}}}}}}}},w:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178}},df:1}}}}}},j:{docs:{},df:0,"ø":{docs:{},df:0,r:{docs:{},df:0,b:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,n:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}},n:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}},o:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},"ó":{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},"ö":{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},"ø":{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,d:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}},l:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},c:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,"=":{docs:{},df:0,'"':{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}}}}}},u:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:2}}}}},r:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2}},df:2,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},s:{docs:{},df:0,t:{docs:{},df:0,_:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}},t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:3}},u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},u:{docs:{},df:0,n:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},y:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},e:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1}}}},p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1}},n:{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}},v:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}},i:{docs:{},df:0,b:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},r:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1}},df:2}}}}},c:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/about/":{tf:1.4142135623730951}},df:1}}}},f:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:3.4641016151377544},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:3,h:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:2}}}},w:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:3}}}}}}}}},m:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}},n:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2},k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.23606797749979}},df:3,".":{docs:{},df:0,j:{docs:{},df:0,o:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,"(":{docs:{},df:0,$:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}}},e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},t:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},v:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},o:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-showdata/":{tf:1.7320508075688772}},df:5,_:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}}},i:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,z:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:3},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}}}}}}}}}}},c:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:2}}},o:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/offline/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:2},p:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:2}},s:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},l:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},w:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,"(":{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},s:{docs:{},df:0,p:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,";":{docs:{},df:0,"!":{docs:{},df:0,d:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,y:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}}},"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},"/":{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}},b:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,y:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}}},d:{docs:{},df:0,i:{docs:{},df:0,v:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:4}}}}}},h:{docs:{},df:0,2:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}},t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}}},p:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}},v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}}}},"?":{docs:{},df:0,p:{docs:{},df:0,h:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1,u:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}},b:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,y:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}}},d:{docs:{},df:0,i:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:4,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}}}},f:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}},h:{docs:{},df:0,1:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,";":{docs:{},df:0,"—":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,h:{docs:{},df:0,6:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}}}}}},2:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}},6:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}},t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}},i:{docs:{},df:0,f:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}},m:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:3},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},o:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}},l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},m:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}},p:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,p:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}}}}}}}}}}}}}}},i:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}}}}},s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1}}}}},o:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:3.3166247903554}},df:1,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}},t:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,".":{docs:{},df:0,h:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}},t:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}}}}}}}}}}}}},v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.7320508075688772}},df:1}}}}}}}}}},u:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},w:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,".":{docs:{},df:0,".":{docs:{},df:0,u:{docs:{},df:0,p:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}},m:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,c:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}},i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1},n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.8284271247461903},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:3,_:{docs:{},df:0,s:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1}}}}}},k:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178}},df:1}},n:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772}},df:7}}}}}},g:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},i:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3,f:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}},u:{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,k:{docs:{},df:0,s:{docs:{},df:0,w:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,y:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{},df:0,h:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,v:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,b:{docs:{},df:0,m:{docs:{},df:0,w:{docs:{},df:0,h:{docs:{},df:0,y:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,k:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,s:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,u:{docs:{},df:0,z:{docs:{},df:0,u:{docs:{},df:0,k:{docs:{},df:0,i:{docs:{},df:0,v:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,v:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,z:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,j:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{},df:0,g:{docs:{},df:0,m:{docs:{},df:0,c:{docs:{},df:0,p:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,d:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.449489742783178}},df:3}}}}}},s:{docs:{},df:0,k:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,e:{docs:{},df:0,".":{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}},t:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-math/":{tf:2.6457513110645907}},df:2,_:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,_:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-math/":{tf:2.23606797749979}},df:1}}}}}}}}}},e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:2.8284271247461903}},df:2}}}}}},x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}},d:{docs:{},df:0,5:{docs:{},df:0,"(":{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,q:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,p:{docs:{},df:0,f:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}},e:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}},d:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},m:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}}},n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,l:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},u:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,_:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}},r:{docs:{},df:0,h:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},s:{docs:{},df:0,s:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},t:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,h:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}},i:{docs:{},df:0,l:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},n:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},t:{docs:{"https://abridge.netlify.app/about/":{tf:1.4142135623730951}},df:1},x:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},o:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/offline/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-abridge/":{tf:2.8284271247461903},"https://abridge.netlify.app/overview-math/":{tf:1}},df:3,r:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:2}}},i:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,c:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},l:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}},o:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},n:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:4.123105625617661}},df:1,";":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},s:{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}}}}},u:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1}},v:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},z:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,f:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}}}}}}}}}}}}}},"ż":{docs:{},df:0,n:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},p:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1},4:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},u:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},o:{docs:{},df:0,k:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}},t:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}},w:{docs:{},df:0,":":{docs:{},df:0,7:{docs:{},df:0,5:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},y:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},v:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},2:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},"ů":{docs:{},df:0,"ž":{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,".":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},"=":{docs:{},df:0,$:{docs:{},df:0,"{":{docs:{},df:0,d:{docs:{},df:0,"#":{docs:{},df:0,"*":{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,m:{docs:{},df:0,u:{docs:{},df:0,_:{docs:{},df:0,g:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}},n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3},"https://abridge.netlify.app/overview-code-blocks/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},n:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},v:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1,i:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}},b:{docs:{},df:0,s:{docs:{},df:0,p:{docs:{},df:0,";":{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:2.449489742783178}},df:1}}}}}}}}},e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,a:{docs:{},df:0,r:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/about/":{tf:1}},df:1}}}},e:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}},t:{docs:{},df:0,l:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},i:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},y:{docs:{},df:0,".":{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}}}}}}}},u:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:5,".":{docs:{},df:0,u:{docs:{},df:0,p:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},x:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}},i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},o:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1}},df:1}}}}}}}},c:{docs:{},df:0,o:{docs:{},df:0,o:{docs:{},df:0,k:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,"/":{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,b:{docs:{},df:0,e:{docs:{},df:0,d:{docs:{},df:0,"/":{docs:{},df:0,3:{docs:{},df:0,2:{docs:{},df:0,g:{docs:{},df:0,y:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,s:{docs:{},df:0,"/":{docs:{},df:0,n:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}},n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,s:{docs:{},df:0,e:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},r:{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}}}}},t:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:2}},e:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2},o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},v:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},w:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:2}},p:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.4641016151377544}},df:1}},u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:3.1622776601683795}},df:1}},m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,b:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:2,b:{docs:{},df:0,f:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},s:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}},v:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},d:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}},f:{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/offline/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:2}}},s:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,g:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},m:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2}},df:1}},n:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,m:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1,l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,c:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,"(":{docs:{},df:0,")":{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},p:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,g:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}},t:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178}},df:1},o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-embed-youtube/":{tf:2},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:7}}}}},r:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}},z:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},d:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}}},i:{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,w:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}}}}},u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,e:{docs:{},df:0,r:{docs:{},df:0,m:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1}},df:2}}},p:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:2},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:8}}}}},v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:2,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1,".":{docs:{},df:0,f:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},m:{docs:{},df:0,p:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},w:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},_:{docs:{},df:0,v:{docs:{},df:0,p:{docs:{},df:0,9:{docs:{},df:0,".":{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,b:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}},r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}}},v:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},x:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1}}}},y:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}},p:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,e:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}}}}}}}}}},g:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/contact/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:4.242640687119285},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:3},"https://abridge.netlify.app/privacy/":{tf:1}},df:9,"'":{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1},".":{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,".":{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{},df:0,b:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}},i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1,a:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,_:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},r:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},m:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}},i:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,i:{docs:{"https://abridge.netlify.app/privacy/":{tf:1.4142135623730951}},df:1,c:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:1}}}}}},n:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},s:{docs:{},df:0,s:{docs:{},df:0,w:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:3},"https://abridge.netlify.app/overview-rich-content/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:4}}},e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:2.449489742783178}},df:2,f:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},o:{docs:{},df:0,r:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}},i:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},s:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}}}},h:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1,k:{docs:{},df:0,e:{docs:{},df:0,"'":{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},1:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},x:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},l:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:2}},df:1}},n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2},y:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2,e:{docs:{},df:0,r:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}},n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}},l:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951}},df:1}}}},s:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}}}},e:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/contact/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:2}}},i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},p:{docs:{},df:0,g:{docs:{},df:0,s:{docs:{},df:0,q:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},u:{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2,"/":{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},q:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}}}}}}},o:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/privacy/":{tf:1.7320508075688772}},df:1}},s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},p:{docs:{},df:0,u:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},r:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},t:{docs:{},df:0,u:{docs:{},df:0,g:{docs:{},df:0,u:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},s:{docs:{},df:0,i:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},s:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:2}}}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1}},df:3,".":{docs:{},df:0,m:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},f:{docs:{},df:0,i:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},w:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},r:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},i:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}},l:{docs:{},df:0,o:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}},t:{docs:{},df:0,y:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},v:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2}}},i:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},i:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3}}}},n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,"(":{docs:{},df:0,'"':{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}},g:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}},s:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,"(":{docs:{},df:0,'"':{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}},l:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1,"!":{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},b:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},"ạ":{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},d:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},z:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},i:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},z:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},q:{docs:{},df:0,u:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,t:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},h:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},"ä":{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},"¡":{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},"こ":{docs:{},df:0,"の":{docs:{},df:0,"コ":{docs:{},df:0,"ー":{docs:{},df:0,"ド":{docs:{},df:0,"は":{docs:{},df:0,"編":{docs:{},df:0,"集":{docs:{},df:0,"し":{docs:{},df:0,"て":{docs:{},df:0,"実":{docs:{},df:0,"行":{docs:{},df:0,"出":{docs:{},df:0,"来":{docs:{},df:0,"ま":{docs:{},df:0,"す":{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,j:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}},"这":{docs:{},df:0,"段":{docs:{},df:0,"代":{docs:{},df:0,"码":{docs:{},df:0,"是":{docs:{},df:0,"可":{docs:{},df:0,"以":{docs:{},df:0,"编":{docs:{},df:0,"辑":{docs:{},df:0,"并":{docs:{},df:0,"且":{docs:{},df:0,"能":{docs:{},df:0,"够":{docs:{},df:0,"运":{docs:{},df:0,"行":{docs:{},df:0,"的":{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,z:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},v:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/privacy/":{tf:1.7320508075688772}},df:2}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,b:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},c:{docs:{},df:0,e:{docs:{},df:0,d:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},f:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}},g:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},j:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1,"'":{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}}},p:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:2}}}}},u:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,"/":{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,_:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}},t:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}},s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}}}},r:{docs:{},df:0,p:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979},"https://abridge.netlify.app/privacy/":{tf:1}},df:2}},w:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3}},df:1,"=":{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},y:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,3:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},q:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},l:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1},y:{docs:{},df:0,"=":{docs:{},df:0,9:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:1,a:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},e:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},b:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:1}}}},r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,a:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},i:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1,a:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/contact/":{tf:1}},df:1}},l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},c:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},o:{docs:{},df:0,m:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:2}}}}}}},d:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},b:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},u:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},r:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},g:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,t:{docs:{},df:0,y:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},u:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,"=":{docs:{},df:0,'"':{docs:{},df:0,p:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},s:{docs:{},df:0,t:{docs:{},df:0,y:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}},e:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},o:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}},m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-math/":{tf:2.449489742783178}},df:1}}}},p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,s:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},r:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}}},q:{docs:{},df:0,u:{docs:{},df:0,i:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/offline/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-math/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1.7320508075688772}},df:4,e:{docs:{},df:0,_:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,"'":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,m:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,".":{docs:{},df:0,p:{docs:{},df:0,h:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}},r:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},s:{docs:{},df:0,p:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}},u:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:2,s:{docs:{},df:0,c:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,e:{docs:{},df:0,".":{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,r:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},i:{docs:{},df:0,n:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{},df:0,b:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}},o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-rich-content/":{tf:2.23606797749979}},df:2}}}},v:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1}}},i:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-rich-content/":{tf:3.4641016151377544}},df:2}},g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},o:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:1,o:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}},m:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},o:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1}},df:3}},u:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,"(":{docs:{},df:0,b:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,2:{docs:{},df:0,8:{docs:{},df:0,0:{docs:{},df:0,".":{docs:{},df:0,h:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},p:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}},w:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},s:{docs:{},df:0,y:{docs:{},df:0,n:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.8284271247461903}},df:1}}}},u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,b:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},l:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,r:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}},n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.605551275463989},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,n:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}},s:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,a:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1}}}}}}}}},s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,"/":{docs:{},df:0,"^":{docs:{},df:0,"#":{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},a:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:3},p:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1}},df:6}}},n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178}},df:1},p:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}},"\\":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}},v:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},c:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},r:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:1}},df:2}}},r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178}},df:1}}},o:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:4},"https://abridge.netlify.app/overview-code-blocks/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},_:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}},c:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},o:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,a:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},t:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:2.449489742783178}},df:2,_:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,"]":{docs:{},df:0,"/":{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}},d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:3,n:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}},g:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},l:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3}}},f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},m:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:3}}}},n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,e:{docs:{},df:0,r:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,"(":{docs:{},df:0,"'":{docs:{},df:0,j:{docs:{},df:0,a:{docs:{},df:0,k:{docs:{},df:0,e:{docs:{},df:0,"@":{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{"https://abridge.netlify.app/privacy/":{tf:1.4142135623730951}},df:1,e:{docs:{},df:0,n:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1},p:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:2}}},q:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},r:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},v:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907}},df:1,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2}},i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}},s:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:5},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-images/":{tf:2.8284271247461903},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1}},df:8,c:{docs:{},df:0,o:{docs:{},df:0,o:{docs:{},df:0,k:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,"'":{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}},v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},h:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772},"https://abridge.netlify.app/privacy/":{tf:1.4142135623730951}},df:2}}},e:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},i:{docs:{},df:0,f:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,w:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,"=":{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},o:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{},df:0,_:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-rich-content/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-showdata/":{tf:1.7320508075688772}},df:8}}}}},w:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:6,c:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:6}}},d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:2,"(":{docs:{},df:0,s:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,p:{docs:{},df:0,s:{docs:{},df:0,":":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,w:{docs:{},df:0,".":{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,"/":{docs:{},df:0,j:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,k:{docs:{},df:0,u:{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,"/":{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,"/":{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},r:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},m:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},p:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}},n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,g:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},t:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},v:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},e:{docs:{"https://abridge.netlify.app/about/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-abridge/":{tf:3.1622776601683795},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:2.23606797749979},"https://abridge.netlify.app/privacy/":{tf:1.7320508075688772}},df:5,m:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,".":{docs:{},df:0,x:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}},i:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},x:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},z:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:4}}},k:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},l:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.3166247903554}},df:1}}},i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},o:{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},m:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:3,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,l:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},o:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}},k:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,".":{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}},f:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{},df:0,"=":{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}},l:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/privacy/":{tf:1.4142135623730951}},df:1}},m:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/offline/":{tf:1}},df:1}}},u:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2.8284271247461903},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:4}}}},p:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},n:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},e:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3}}},n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}},e:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:2}},r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}},u:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},q:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1},u:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},i:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}},r:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-images/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:3,"=":{docs:{},df:0,'"':{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,s:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}},h:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,p:{docs:{},df:0,s:{docs:{},df:0,":":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,y:{docs:{},df:0,".":{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,p:{docs:{},df:0,"/":{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-rich-content/":{tf:2.8284271247461903}},df:2}}}}}}}}}}}}}}}}}}}}}}}}}}}},p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,".":{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,"/":{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{},df:0,"/":{docs:{},df:0,5:{docs:{},df:0,1:{docs:{},df:0,4:{docs:{},df:0,4:{docs:{},df:0,0:{docs:{},df:0,2:{docs:{},df:0,6:{docs:{},df:0,4:{docs:{},df:0,8:{docs:{},df:0,"?":{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,b:{docs:{},df:0,e:{docs:{},df:0,d:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,d:{docs:{},df:0,"=":{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,u:{docs:{},df:0,e:{docs:{},df:0,"&":{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,";":{docs:{},df:0,d:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,"=":{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},w:{docs:{},df:0,w:{docs:{},df:0,w:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,"/":{docs:{},df:0,e:{docs:{},df:0,"/":{docs:{},df:0,9:{docs:{},df:0,2:{docs:{},df:0,o:{docs:{},df:0,k:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}},y:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:1}}}}}}}}}}}}}}}}}},i:{docs:{},df:0,m:{docs:{},df:0,g:{docs:{},df:0,"/":{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,s:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}},o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}},s:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,p:{docs:{},df:0,s:{docs:{},df:0,":":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,y:{docs:{},df:0,".":{docs:{},df:0,a:{docs:{},df:0,p:{docs:{},df:0,p:{docs:{},df:0,"/":{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.7320508075688772}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1,_:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},t:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:2,"/":{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},w:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},y:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},d:{docs:{},df:0,":":{docs:{},df:0,":":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},e:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}},i:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},o:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1}},df:2},k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.7416573867739413}},df:1}}},r:{docs:{},df:0,"(":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,"(":{docs:{},df:0,h:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979}},df:1}}}}},t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979}},df:1}}}}}}}}}},e:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:2.23606797749979}},df:2,e:{docs:{},df:0,"(":{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,9:{docs:{},df:0,2:{docs:{},df:0,o:{docs:{},df:0,k:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1}},df:1}}}}}}}}}}}}}}}}},i:{docs:{},df:0,n:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:2.8284271247461903}},df:1}},p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}},u:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},f:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}},y:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,s:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},u:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,l:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},m:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}},c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}},d:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}},f:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},g:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},p:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,p:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-rich-content/":{tf:2.8284271247461903},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:5}}}}},r:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1},r:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:4}}}}}}},v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},w:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}},_:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},a:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:2.6457513110645907}},df:2,_:{docs:{},df:0,s:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:1,"=":{docs:{},df:0,'"':{docs:{},df:0,".":{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,g:{docs:{},df:0,"/":{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}},"/":{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}},f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}},e:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},i:{docs:{},df:0,t:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.1622776601683795}},df:1,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.7416573867739413}},df:1,'"':{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},d:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}},y:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2},"https://abridge.netlify.app/overview-math/":{tf:1}},df:4}}}},s:{docs:{},df:0,"/":{docs:{},df:0,k:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,m:{docs:{},df:0,u:{docs:{},df:0,_:{docs:{},df:0,g:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,p:{docs:{},df:0,s:{docs:{},df:0,"/":{docs:{},df:0,"*":{docs:{},df:0,"/":{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}},z:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,z:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,".":{docs:{},df:0,c:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,"!":{docs:{},df:0,0:{docs:{},df:0,")":{docs:{},df:0,")":{docs:{},df:0,".":{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}},i:{docs:{},df:0,n:{docs:{},df:0,n:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}},a:{docs:{},df:0,b:{docs:{},df:0,"/":{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:2.449489742783178}},df:3},s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,p:{docs:{},df:0,"=":{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:3.7416573867739413}},df:4},k:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:2}},df:1}},l:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},r:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,"/":{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,"/":{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},t:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}},x:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,c:{docs:{},df:0,h:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},m:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,e:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979}},df:1,e:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,9:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}},f:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1},l:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.23606797749979}},df:1,e:{docs:{},df:0,s:{docs:{},df:0,"/":{docs:{},df:0,".":{docs:{},df:0,g:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,k:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}},m:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{},df:0,"/":{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,".":{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}},r:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},x:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2,"/":{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},j:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}},p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},x:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}},h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/about/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-abridge/":{tf:5.385164807134504},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:6,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}},_:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},c:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},s:{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,e:{docs:{},df:0,"/":{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,".":{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,"/":{docs:{},df:0,_:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}},s:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}},p:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},n:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,y:{docs:{},df:0,".":{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}},p:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,".":{docs:{},df:0,j:{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}},i:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1.4142135623730951}},df:2}}},o:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},r:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},u:{docs:{},df:0,m:{docs:{},df:0,b:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}},i:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3,".":{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}},s:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,p:{docs:{},df:0,"(":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},t:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,e:{docs:{},df:0,"(":{docs:{},df:0,")":{docs:{},df:0,"+":{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}},o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},s:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}}}}}},n:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1},y:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.7416573867739413}},df:1,"/":{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}},t:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:5,e:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,c:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},s:{docs:{},df:0,t:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1}},df:1}}}}}},v:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1}},df:1}}}}},y:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:1}}}}}}}}}}},u:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},"ế":{docs:{},df:0,p:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,v:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}},o:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1},g:{docs:{},df:0,g:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},k:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},o:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},p:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2},u:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},r:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:2}},i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:2,g:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}},m:{docs:{},df:0,"(":{docs:{},df:0,s:{docs:{},df:0,a:{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,p:{docs:{},df:0,o:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,"(":{docs:{},df:0,"'":{docs:{},df:0,f:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}},u:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3.605551275463989},"https://abridge.netlify.app/overview-code-blocks/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:2},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:3.1622776601683795}},df:5}},"ự":{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},t:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},u:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}},n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},w:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}},o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}},y:{docs:{},df:0,p:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:2},"https://abridge.netlify.app/overview-showdata/":{tf:1.7320508075688772}},df:5,"=":{docs:{},df:0,'"':{docs:{},df:0,a:{docs:{},df:0,u:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,"/":{docs:{},df:0,f:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},m:{docs:{},df:0,p:{docs:{},df:0,3:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},o:{docs:{},df:0,g:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},w:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}},b:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},i:{docs:{},df:0,m:{docs:{},df:0,g:{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.7320508075688772}},df:1}}}}}}}},m:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,"/":{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,e:{docs:{},df:0,"^":{docs:{},df:0,"{":{docs:{},df:0,i:{docs:{},df:0,"\\":{docs:{},df:0,p:{docs:{},df:0,i:{docs:{},df:0,"}":{docs:{},df:0,"+":{docs:{},df:0,1:{docs:{},df:0,"=":{docs:{},df:0,0:{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},";":{docs:{},df:0,m:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,"=":{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{},df:0,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"\\":{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,_:{docs:{},df:0,0:{docs:{},df:0,"^":{docs:{},df:0,1:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}},v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{},df:0,"/":{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}},w:{docs:{},df:0,e:{docs:{},df:0,b:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}},s:{docs:{},df:0,e:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},u:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}}}},i:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1,t:{docs:{},df:0,v:{docs:{},df:0,o:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,b:{docs:{},df:0,a:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,d:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}},n:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772}},df:4,s:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},i:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},t:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}},n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,"(":{docs:{},df:0,'"':{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},l:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}},o:{docs:{},df:0,r:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}},p:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1,e:{docs:{},df:0,_:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}}}},p:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,a:{docs:{},df:0,v:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:3},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:2},u:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,"ć":{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,p:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}},s:{docs:{"https://abridge.netlify.app/about/":{tf:1},"https://abridge.netlify.app/contact/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:5.656854249492381},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-math/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:3.3166247903554},"https://abridge.netlify.app/privacy/":{tf:1}},df:9,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-math/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-rich-content/":{tf:2},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:7}},e:{docs:{},df:0,"/":{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}},r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1}},df:2,_:{docs:{},df:0,u:{docs:{},df:0,p:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,"/":{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,"/":{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}},l:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,"/":{docs:{},df:0,b:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,"/":{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}},t:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{},df:0,y:{docs:{},df:0,s:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}},t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,i:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},v:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,a:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}},u:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2.6457513110645907},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:3}},r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1,"(":{docs:{},df:0,$:{docs:{},df:0,f:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}}}},i:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1}}},o:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,l:{docs:{},df:0,i:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,i:{docs:{},df:0,m:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}},n:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,u:{docs:{},df:0,s:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}},r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,f:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},s:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:2}}}}}},i:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1},d:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:2.449489742783178},"https://abridge.netlify.app/overview-embed-youtube/":{tf:2},"https://abridge.netlify.app/overview-rich-content/":{tf:3.7416573867739413}},df:5,"(":{docs:{},df:0,s:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,r:{docs:{},df:0,c:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,"=":{docs:{},df:0,"[":{docs:{},df:0,'"':{docs:{},df:0,o:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,9:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,_:{docs:{},df:0,a:{docs:{},df:0,v:{docs:{},df:0,1:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,4:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},e:{docs:{},df:0,t:{docs:{},df:0,n:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},w:{docs:{},df:0,b:{docs:{},df:0,o:{docs:{},df:0,x:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}},m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:2.23606797749979}},df:2,"(":{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,5:{docs:{},df:0,1:{docs:{},df:0,4:{docs:{},df:0,4:{docs:{},df:0,0:{docs:{},df:0,2:{docs:{},df:0,6:{docs:{},df:0,4:{docs:{},df:0,8:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1}},df:1}}}}}}}}}}}}}}}}},s:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,o:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772}},df:1}}}}}},o:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,q:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}},o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,u:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}},r:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},u:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1,i:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}}}},w:{docs:{"https://abridge.netlify.app/overview-images/":{tf:2.449489742783178}},df:1,a:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:6}},t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}}}},v:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},e:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2,":":{docs:{},df:0,"/":{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,"/":{docs:{},df:0,w:{docs:{},df:0,w:{docs:{},df:0,w:{docs:{},df:0,"/":{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}}}}}}}},k:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,f:{docs:{},df:0,u:{docs:{},df:0,l:{docs:{},df:0,l:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}}}}}}}}}}}}}}}}},m:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1},p:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}},r:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,"!":{docs:{},df:0,'"':{docs:{},df:0,")":{docs:{},df:0,",":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}},h:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,v:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},e:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}},i:{docs:{},df:0,d:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-images/":{tf:2},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:4,"=":{docs:{},df:0,'"':{docs:{},df:0,6:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-images/":{tf:3.1622776601683795}},df:1}},4:{docs:{},df:0,0:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}}},n:{docs:{},df:0,d:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,".":{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}}}}}}}},t:{docs:{},df:0,h:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772}},df:1}},o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-math/":{tf:1}},df:2}}}}}},o:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},r:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:2}},df:1,e:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}},l:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2}},df:1}},m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},r:{docs:{},df:0,a:{docs:{},df:0,p:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}},i:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},x:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:2,'"':{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,i:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"&":{docs:{},df:0,l:{docs:{},df:0,t:{docs:{},df:0,";":{docs:{},df:0,"/":{docs:{},df:0,b:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,n:{docs:{},df:0,"&":{docs:{},df:0,g:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"^":{docs:{},df:0,2:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1}},e:{docs:{},df:0,r:{docs:{},df:0,u:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1},m:{docs:{},df:0,l:{docs:{},df:0,n:{docs:{},df:0,s:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,h:{docs:{},df:0,t:{docs:{},df:0,t:{docs:{},df:0,p:{docs:{},df:0,":":{docs:{},df:0,"/":{docs:{},df:0,"/":{docs:{},df:0,w:{docs:{},df:0,w:{docs:{},df:0,w:{docs:{},df:0,".":{docs:{},df:0,w:{docs:{},df:0,3:{docs:{},df:0,".":{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,g:{docs:{},df:0,"/":{docs:{},df:0,2:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,0:{docs:{},df:0,"/":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},"}":{docs:{},df:0,",":{docs:{},df:0,d:{docs:{},df:0,"\\":{docs:{},df:0,x:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}},"\\":{docs:{},df:0,",":{docs:{},df:0,d:{docs:{},df:0,"\\":{docs:{},df:0,x:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}}},y:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1,e:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.23606797749979}},df:1}},l:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1}}}}}}}}}}}},n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:2.23606797749979}},df:2,e:{docs:{},df:0,"(":{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,"=":{docs:{},df:0,'"':{docs:{},df:0,3:{docs:{},df:0,2:{docs:{},df:0,g:{docs:{},df:0,y:{docs:{},df:0,f:{docs:{},df:0,i:{docs:{},df:0,w:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,u:{docs:{},df:0,w:{docs:{"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:1}}}}}}}}}}}}}}}}}}}},"’":{docs:{},df:0,r:{docs:{"https://abridge.netlify.app/offline/":{tf:1}},df:1}}}},r:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:2.6457513110645907}},df:1}},z:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,i:{docs:{},df:0,u:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}},n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1},o:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/about/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-abridge/":{tf:4.242640687119285},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.7320508075688772},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1.7320508075688772}},df:9,"'":{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}},n:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.7320508075688772}},df:1}}},v:{docs:{},df:0,r:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},description:{root:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951}},df:1,e:{docs:{},df:0,".":{docs:{},df:0,c:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}},f:{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}}}},r:{docs:{},df:0,t:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:6}}}}},u:{docs:{},df:0,d:{docs:{},df:0,i:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}},b:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},l:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}}}},r:{docs:{},df:0,i:{docs:{},df:0,e:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}},c:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1,a:{docs:{},df:0,s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:1}},n:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/contact/":{tf:1.4142135623730951}},df:1}}},e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},s:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},u:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:6}}}}}},d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1},e:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}},e:{docs:{},df:0,s:{docs:{},df:0,c:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,p:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}}}},i:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}},s:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{},df:0,y:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}}}},e:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}}}}}},m:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3,e:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1}},df:4}}}},x:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}},t:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}}}},f:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}},e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,"]":{docs:{},df:0,"(":{docs:{},df:0,f:{docs:{},df:0,e:{docs:{},df:0,r:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,s:{docs:{},df:0,".":{docs:{},df:0,s:{docs:{},df:0,v:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}}}}}}}}}}}}}},o:{docs:{},df:0,r:{docs:{},df:0,m:{docs:{"https://abridge.netlify.app/contact/":{tf:1}},df:1,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}},g:{docs:{},df:0,i:{docs:{},df:0,f:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}},h:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}}}}},t:{docs:{},df:0,m:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:3}}}},i:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:2}},p:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}}}}}},j:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}},k:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}},l:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}},g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1,w:{docs:{},df:0,e:{docs:{},df:0,i:{docs:{},df:0,g:{docs:{},df:0,h:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}}}}},o:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}},m:{docs:{},df:0,a:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}},n:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},r:{docs:{},df:0,k:{docs:{},df:0,d:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1.4142135623730951}},df:2}}}}}},t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1}}}}}}},o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/offline/":{tf:1}},df:1,r:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}},n:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1.4142135623730951}},df:1}}}}},o:{docs:{},df:0,f:{docs:{},df:0,f:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/offline/":{tf:1}},df:1}}}}},u:{docs:{},df:0,t:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}}}}},p:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/contact/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/privacy/":{tf:1}},df:5}}},l:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/contact/":{tf:1}},df:1}}}},o:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/privacy/":{tf:1.7320508075688772}},df:1}}}},s:{docs:{},df:0,s:{docs:{},df:0,i:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}},r:{docs:{},df:0,e:{docs:{},df:0,v:{docs:{},df:0,e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},i:{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/privacy/":{tf:1.4142135623730951}},df:1}}}}}},u:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}},r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/contact/":{tf:1}},df:1}}}},i:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},s:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,p:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:6}}}},e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}},t:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}},h:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1.4142135623730951}},df:6}}}}},w:{docs:{},df:0,c:{docs:{},df:0,a:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1},"https://abridge.netlify.app/overview-math/":{tf:1}},df:6}}},d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}}}}},i:{docs:{},df:0,t:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}},t:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951}},df:1}}}}}}},y:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}},y:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,x:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1},"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:2}}}}}},t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-code-blocks/":{tf:1.4142135623730951}},df:2}}}}},u:{docs:{},df:0,s:{docs:{"https://abridge.netlify.app/contact/":{tf:1},"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-images/":{tf:1.4142135623730951}},df:3}},v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:4}}},m:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1.4142135623730951}},df:1}}}}},w:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,t:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}}},y:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-embed-youtube/":{tf:1.4142135623730951}},df:1}}}}}},z:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1.4142135623730951},"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1},"https://abridge.netlify.app/overview-rich-content/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:6}}}}}},title:{root:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,r:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}},b:{docs:{},df:0,l:{docs:{},df:0,o:{docs:{},df:0,c:{docs:{},df:0,k:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}}}}},c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:1}},n:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/contact/":{tf:1}},df:1}}},e:{docs:{},df:0,n:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}}}}},e:{docs:{},df:0,m:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}},i:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,g:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1}},df:1}}}},m:{docs:{},df:0,a:{docs:{},df:0,r:{docs:{},df:0,k:{docs:{},df:0,d:{docs:{},df:0,o:{docs:{},df:0,w:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}}},t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}}}},o:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/offline/":{tf:1}},df:1}}}},n:{docs:{},df:0,o:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{"https://abridge.netlify.app/overview-math/":{tf:1}},df:1}}}}},o:{docs:{},df:0,f:{docs:{},df:0,f:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,n:{docs:{"https://abridge.netlify.app/offline/":{tf:1}},df:1}}}}}},p:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}}}},r:{docs:{},df:0,i:{docs:{},df:0,v:{docs:{},df:0,a:{docs:{},df:0,c:{docs:{},df:0,i:{docs:{"https://abridge.netlify.app/privacy/":{tf:1}},df:1}}}}}}},r:{docs:{},df:0,i:{docs:{},df:0,c:{docs:{},df:0,h:{docs:{"https://abridge.netlify.app/overview-rich-content/":{tf:1}},df:1}}}},s:{docs:{},df:0,h:{docs:{},df:0,o:{docs:{},df:0,r:{docs:{},df:0,t:{docs:{},df:0,c:{docs:{},df:0,o:{docs:{},df:0,d:{docs:{"https://abridge.netlify.app/overview-images/":{tf:1},"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:2}}}}},w:{docs:{},df:0,d:{docs:{},df:0,a:{docs:{},df:0,t:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-showdata/":{tf:1}},df:1}}}}}}},t:{docs:{},df:0,r:{docs:{},df:0,e:{docs:{},df:0,a:{docs:{},df:0,m:{docs:{},df:0,a:{docs:{},df:0,b:{docs:{},df:0,l:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1}},df:1}}}}}}},y:{docs:{},df:0,l:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-markdown-and-style/":{tf:1}},df:1}}}}},t:{docs:{},df:0,h:{docs:{},df:0,e:{docs:{},df:0,m:{docs:{},df:0,e:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1},"https://abridge.netlify.app/overview-code-blocks/":{tf:1}},df:2}}}}},v:{docs:{},df:0,i:{docs:{},df:0,d:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-embed-streamable/":{tf:1},"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1},"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:3}}},m:{docs:{},df:0,e:{docs:{},df:0,o:{docs:{"https://abridge.netlify.app/overview-embed-vimeo/":{tf:1}},df:1}}}}},y:{docs:{},df:0,o:{docs:{},df:0,u:{docs:{},df:0,t:{docs:{},df:0,u:{docs:{},df:0,b:{docs:{"https://abridge.netlify.app/overview-embed-youtube/":{tf:1}},df:1}}}}}},z:{docs:{},df:0,o:{docs:{},df:0,l:{docs:{},df:0,a:{docs:{"https://abridge.netlify.app/overview-abridge/":{tf:1}},df:1}}}}}}},documentStore:{save:!0,docs:{"https://abridge.netlify.app/":{body:"",description:"",id:"https://abridge.netlify.app/",title:""},"https://abridge.netlify.app/about/":{body:"This site provides a demo for the abridge theme for Zola the static site generator.\nAbridge was created by Jake G (jieiku) to be fast and lightweight, using semantic html, a class-light abridge.css, and No Mandatory JS.\nNearly half of the existing Zola MIT themes were inspiration for features and design of this theme.\nAbridge is licensed under the MIT license.\n",description:"",id:"https://abridge.netlify.app/about/",title:"About"},"https://abridge.netlify.app/archive/":{body:"",description:"",id:"https://abridge.netlify.app/archive/",title:""},"https://abridge.netlify.app/contact/":{body:"",description:"To reach us please use the contact form on this page.",id:"https://abridge.netlify.app/contact/",title:"Contact"},"https://abridge.netlify.app/offline/":{body:"Offline Mode\nSorry, no cache found and it looks like you’re offline, a connection is required.\n",description:"",id:"https://abridge.netlify.app/offline/",title:"Offline Mode"},"https://abridge.netlify.app/overview-abridge/":{body:'A fast, lightweight, and modern Zola theme utilizing abridge.css (a class-light semantic HTML CSS Framework). Perfect Lighthouse, YellowLabTools, and Observatory scores. Here is a Zola Themes Benchmarks Page.\n\n\nFeatures\n\n\nPerfect Lighthouse, YellowLabTools, and Observatory scores.\n\nPWA support (Progressive Web Application).\n\nAll JavaScript can be fully disabled.\n\nDark, Light, Auto, and Switcher themes. (colors can be customized, css variables)\n\nCode syntax highlighting. (colors can be customized, css variables)\n\nNumbered code blocks with line highlighting.\n\nMulti-language support.\n\nSearch support. (elasticlunr, tinysearch, stork)\n\nSearch Suggestions navigation keys, / focus, arrow move, enter select, escape close.\n\nSearch Results Page, type search query then hit Enter Key or click the search button icon.\n\nSEO support. (Search Engine Optimization)\n\nPagination with numbered paginator on index.\n\nTitle Based Previous and Next Article links at bottom of Article.\n\nTable of Contents in page Index (Optional, clickable links)\n\nRecent Posts Block. (Optional)\n\nBack to Top button. (uses css only)\n\nCode Blocks copy button.\n\nEmail link in footer obfuscation. (anti-spam)\n\nKaTeX support.\n\nArchive page.\n\nTags.\n\nCategories. (similar to Tags, disabled/commented out by default)\n\nSocial icon links in footer.\n\nResponsive design. (mobile first)\n\nVideo Shortcodes: Youtube, Vimeo, Streamable.\n\nMedia Shortcodes: video, img, imgswap, image, gif, audio.\n\nOther Shortcodes: showdata, katex.\n\nQuick Start\nThis theme requires version \n \n 0.17.2\n or later of Zola\ngit clone https://github.com/jieiku/abridge.git\ncd abridge\nzola serve\n# open http://127.0.0.1:1111/ in the browser\n\nInstallation\nThe Quick Start shows how to run the theme directly. Next we will use abridge as a theme to a NEW site.\n1: Create a new zola site\nzola init mysite\ncd mysite\n\n2: Install Abridge\nAdd the theme as a git submodule:\ngit init # if your project is a git repository already, ignore this command\ngit submodule add https://github.com/jieiku/abridge.git themes/abridge\n\nOr clone the theme into your themes directory:\ngit clone https://github.com/jieiku/abridge.git themes/abridge\n\n3: Configuration\nCopy some files from the theme directory to your project\'s root directory:\ntouch templates/.gitkeep\nrsync themes/abridge/config.toml config.toml\nrsync themes/abridge/content/_index.md content/\nrsync themes/abridge/COPY-TO-ROOT-SASS/* sass/\nrsync themes/abridge/netlify.toml netlify.toml\nrsync themes/abridge/package.json package.json\nrsync -r themes/abridge/content/static content/\n\n\ntemplates/.gitkeep the templates directory is required in your base site. #2150\nconfig.toml base configuration with all config values.\ncontent/_index.md required to set pagination.\nCOPY-TO-ROOT-SASS/abridge.scss overrides to customize Abridge variables.\nnetlify.toml settings to deploy your repo with netlfiy.\npackage.json to switch between nosearch, elasticlunr, tinysearch, stork.\ncontent/static files for generating tinysearch and stork indexes.\n\nUncomment the theme line in your project\'s root config.toml:\nsed -i \'s/^#theme = "abridge"/theme = "abridge"/\' config.toml\n\n4: Add new content\nCopy the content from the theme directory to your project or make a new post:\nrsync -r themes/abridge/content .\n\n5: Run the project\nJust run zola serve in the root path of the project:\nzola serve\n\nZola will start the dev web server, accessible by default at http://127.0.0.1:1111.\nSaved changes will live reload in the browser. (press ctrl+f5, or while developing set pwa=false in config.toml)\nPagination\nYou can set the number of home page items by editing content\\_index.md file and adjusting paginate_by\nSass Overrides\nAbridge SASS variables can be overrided by editing sass\\abridge.scss file in your project\'s root sass folder.\nPage Width\n$mw:75%,// max-width\n\nAbridge Theme Modes\n$abridgeMode: "switcher",//valid values: switcher, auto, dark, light\n\n\nswitcher: automatically displays a dark or light version depending on browser/OS settings, and has a javascript user clickable theme switcher.\nauto: automatically displays a dark or light version depending on browser/OS settings.\ndark: is the dark theme always.\nlight: is the light theme always.\n\nColors and Styles\nYou can specify which color template you want to use as a base:\n$color: "orange",// color template to use/override: orange, blue, blueshade\n\nThen override individual colors as needed:\n/// Dark Colors\n$f1d: #ccc,// Font Color Primary\n$f2d: #ddd,// Font Color Headers\n$c1d: #111,// Background Color Primary\n$c2d: #222,// Background Color Secondary\n...\n\nFooter Social Icons\nYou should configure which social icons you plan to use. (makes the css file size smaller)\nTo simply turn them all off you can set $enable-icons: false (disables ALL icons, navigation, search, etc.)\nOtherwise enable only the icons you need, eg for mail you would set $icon-mail: true\nYou should then disable all the other icons that you do not use.\nTheme for noscript visits\nIf you have abridge configured to use the switcher mode instead of auto/dark/light, then your site will have a button that allows the visitor to toggle the theme.\nIf your visitor uses noscript or some other javascript blocking browser addon, then they will be stuck with whatever the configured default theme is for the switcher mode.\nTo adjust this mode you would set the following two config values in abridge.scss AND config.toml:\n$switcherDefault: "dark",// default nojs switcher mode: dark, light (make sure to also set js_switcher_default in config.toml)\n\njs_switcher_default = "dark" # default nojs switcher mode: dark, light (make sure to also set $switcherDefault in abridge.scss)\n\nBy default abridge uses dark mode for the switcher, so unless you want to set the default mode to light for nojs/noscript visitors, then you do not need to worry about these settings.\nConfig.toml Configuration\nMost Options in config.toml are self documenting. (obvious between name of config value and comments)\nAbridge will work with a barebones config.toml because default values are provided in the template files.\nI recommend copying the entire config.toml file as outlined in Step 3 as it provides all configurable values.\nTop and Footer menus\nSet a field in extra with a key of menu and menu_footer.\nIf you want the link to open in a new tab/browser then set blank = true.\nIf a link should have a trailing slash at the end of the url set slash = true.\n(generally all links should have a trailing slash unless its a file link such as sitemap.xml)\nmenu = [\n {url = "about", name = "About", slash = true, blank = false},\n {url = "posts", name = "Posts", slash = true, blank = false},\n {url = "categories", name = "Categories", slash = true, blank = false},\n {url = "tags", name = "Tags", slash = true, blank = false},\n]\nmenu_footer = [\n {url = "about", name = "About", slash = true, blank = false},\n {url = "contact", name = "Contact", slash = true, blank = false},\n {url = "privacy", name = "Privacy", slash = true, blank = false},\n {url = "sitemap.xml", name = "Sitemap", slash = false, blank = true},\n]\n\nSEO and Header Tags\nYou can review the SEO tags in the head macro located at templates/macros/head.html, all configurable values should be in config.toml under config.extra or in the content markdown files.\nIn your post markdown file you should set a title less than 60 characters and a description between 80 and 160 characters in length. The description is what is displayed in search results below the page title. Anywhere that you do not set a page description, the primary site config.description will be used instead.\nYou should also set page specific keywords unless your keywords defined in config.toml suffice, any keywords that you add to the page are in addition to the ones defined in config.toml, so do not add those same keywords to your page keywords.\nYou can optionally also set a page specific image for search results by using page.extra.thumbnail. Facebook, Twitter, and OpenGraph Cards are supported (automatic image & description for posted links). OpenGraph recommends 1200 x 630 (1.9:1). Twitter recommends 2:1 for large and 1:1 for small. If you do not set a page specific thumbnail then the banner defined in config.toml will be used instead.\nRefer to overview-images for an example:\n+++\ntitle = "Image Shortcodes"\ndescription = "Images can be embedded directly using markdown `![Ferris](ferris.svg)`, but using a shortcode prevents CLS by explicitly setting the width and height."\ndate = 2021-05-19\ndraft = false\n\n[taxonomies]\ntags = ["Features","Shortcodes","Images"]\n[extra]\ntoc = true\nkeywords = "Image, Markdown, Shortcodes, Swap"\nthumbnail = "ferris-gesture.png"\n+++\n\nKaTeX Math Notation\nKaTeX can be used to display complex mathematics, it is a "Fast math typesetting for the web."\nYou can see a demo on this page.\nFor better performance I recommend only enabling math on a per page bases in your post.md files, instead of in your main config.toml file.\nPWA, Progressive Web App\nAbridge theme has PWA support. You can install the entire site as an app and have it work offline. To try it out simply use google chrome or your phone and go here: abridge.netlify.app\nIf using Chrome on desktop then look at the end of the address bar for the install button. On Android you should get a popup to install, you can also install from the 3 dot menu in the top right corner. Once you have the PWA installed, you can go completely offline and you will still be able to browse or search the site!\nTo use it in your own instance you will need to edit static/sw.js for the list of files to cache. Technically you do not need to edit sw.js, but if even a single file in the cache list is missing then it wont pre cache the list, so it will only cache as you browse.\nThere is an npm script to generate the file cache list and minification npm run pwa. My netlify.toml file automatically runs this npm script during site deployment, so everything is automatic. If Zola was able to template a js file then it might be possible to generate the list of cache files dynamically at build.\nThe PWA feature is also easy to disable by simply setting pwa = false in config.toml\nPerformance Optimization\nJavascript files\nAll javascript can be disabled in config.toml:\nbuild_search_index = false\n\njs_bundle = false\njs_copycode = false\njs_email_encode = false\njs_prestyle = false\njs_switcher = false\n\nThese are the javascript files used by Abridge:\n\nsearch_index.en.js: search index generated by zola at each build for elasticlunr.\nelasticlunr.min.js: search library for client side searching.\nsearch.js: to make use of elasticlunr from our sites search box for both suggestions and the results page.\nemail.js: uses javascript to obfuscate your real email address for the mail icon at the bottom of the page.\ncodecopy.js: add a Copy Button to code blocks, to copy contents of the code block to clipboard.\ntheme.js: tiny script to facilitate local storage for the theme switcher. (never bundle, always separate)\ntheme_button.js: tiny script for the theme switcher function when you click the theme switch button.\nprestyle.js: Used to preload css files <link rel="preload" - this script changes these to <link rel="stylesheet" once the page has finished loading, this allows us to load stylesheets for external fonts, fontawesome, or katex in a non blocking fashion.\nsw.js: this is the Service Worker file for the PWA.\nsw_load.js: this file handles loading the Service Worker for the PWA.\n\njs_bundle option\njs_bundle when set to true serves a bundle file instead of all of the individual js files.\nAll Bundles are defined in package.json\nA Bundle can be generated from the package.json scripts using npm:\n\nnpm run nosearch - generates a bundle without search.\nnpm run elasticlunr - generates a bundle of all js with elasticlunr.\nnpm run tinysearch - generates a bundle of all js with tinysearch.\nnpm run stork - generates a bundle of all js with stork.\n\nSwitch Search Library\nIn addition to elasticlunr abridge also supports tinysearch and stork.\ntinysearch demo: https://jieiku.github.io/abridge-tinysearch/\nstork demo: https://jieiku.github.io/abridge-stork/\nTo use tinysearch/stork extra steps are required.\nSwitch to tinysearch:\nFirst you have to install tinysearch so that you can build the index:\ngit clone https://github.com/tinysearch/tinysearch\ncd tinysearch\ncargo build --release\nsudo cp ./target/release/tinysearch /usr/local/bin/tinysearch\nexit # reload shell environment\n\nSwitch Abridge to tinysearch:\nnpm run tinysearch\nzola build\ntinysearch --optimize --path static public/data_tinysearch/index.html\n# zola serve\n\nSwitch to stork:\nFirst you have to install stork so that you can build the index:\ngit clone https://github.com/jameslittle230/stork\ncd stork\ncargo build --release\nsudo cp ./target/release/stork /usr/local/bin/stork\nexit # reload shell environment\n\nSwitch Abridge to stork:\nnpm run stork\nzola build\nstork build --input public/data_stork/index.html --output static/stork.st\n# zola serve\n\nSwitch to elasticlunr:\nnpm run elasticlunr\n\nSwitch to nosearch:\nnpm run nosearch\n\nTheme-Switcher\nThe theme switcher relies on javascript to work, it applies the .light class to the root documentElement. The file that handles this (theme.js) is tiny and optimized and it is the first file loaded in the head, so the performance hit is minimal. Without the Theme switcher you can still use The automatic Theme which uses the Browser/OS preference settings. You can even install a Firefox plugin to quickly switch between the two.\nOptimize PNG/ICO files\nGood tool to generate maskable icons for manifest.json: maskable.app\nAll png files can be optimized using oxipng:\ncd static\noxipng -o max --strip all -a -Z *.png\n\nWith larger displays and greater pixel density becoming common it is probably a good idea to use atleast a littly bit of lossy compression. For example you can use pngquant with a 93% quality and you will often get images around 1/2 the size. Understand that pngquant is cumulative, so you should keep your original images somewhere, and only ever use pngquant once per image, if you use it again and again on the same image then you will lower the image quality each time. Always use oxipng afterwards, oxipng is lossless.\npngquant --skip-if-larger --strip --quality=93-93 --speed 1 *.png\noxipng -o max --strip all -a -Z *.png\n\nleanify can compress farther for both png and ico files:\ngit clone https://github.com/JayXon/Leanify\ncd Leanify\nmake\nsudo cp leanify /usr/local/bin/leanify\nexit #launch new terminal\nleanify -i 7777 *.png\nleanify -i 7777 *.ico\n\nPre gzip/brotli content\nIf you are serving your site with nginx, you can pre gzip your content.\n(Netlify brotli gzips your files automatically, no exta work required.)\nFirst configure nginx:\nsudo nano /etc/nginx/nginx.conf\n\ngzip on;\ngzip_vary on;\ngzip_proxied expired no-cache no-store private auth;\n#gzip_proxied any;\ngzip_comp_level 9;\ngzip_buffers 64 16k;\n#gzip_buffers 16 8k;\ngzip_http_version 1.1;\ngzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml application/xhtml+xml application/x-javascript application/x-font-ttf application/vnd.ms-fontobject font/opentype font/ttf font/eot font/otf;\n#gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;\n\nThen you can gzip/brotli your files:\nzola build\nfind ~/.dev/abridge/public -type f -regextype posix-extended -regex \'.*\\.(htm|html|css|js|xml|xsl|txt|woff|woff2|svg|otf|eot|ttf)\' -exec gzip --best -k -f {} \\+ -exec brotli --best -f {} \\;\nrsync -zvrh ~/.dev/abridge/public/ web:/var/www/abridge\n\nNginx does not come by default with brotli support, but adding it was not difficult.\n',description:"Abridge is a fast and lightweight Zola theme using semantic html, abridge.css class-light CSS, and No Mandatory JS.",id:"https://abridge.netlify.app/overview-abridge/",title:"Abridge Zola Theme"},"https://abridge.netlify.app/overview-code-blocks/":{body:'This article shows various Code Blocks allowing to easily compare sublime themes.\nCode Blocks\nCode blocks.. ❤️ with automatic syntax highlighting ✨‍\nSee the docs for options.\nInline Code block\nIf we want, we can also specify inline code which is useful for the small stuff.\nRust\nfn main() {\n let greetings = ["Hello", "Hola", "Bonjour",\n "Ciao", "こんにちは", "안녕하세요",\n "Cześć", "Olá", "Здравствуйте",\n "Chào bạn", "您好", "Hallo",\n "Hej", "Ahoj", "سلام",\n "Hej", "Hallo", "Hei",\n "Helló", "Hallo", "Buna ziua",\n "Merhaba"];\n\n for (num, greeting) in greetings.iter().enumerate() {\n print!("{} : ", greeting);\n match num {\n 0 => println!("This code is editable and runnable!"),//en English\n 1 => println!("¡Este código es editable y ejecutable!"),//es Spanish\n 2 => println!("Ce code est modifiable et exécutable !"),//fr French\n 3 => println!("Questo codice è modificabile ed eseguibile!"),//it Italian\n 4 => println!("このコードは編集して実行出来ます!"),//jp Japanese\n 5 => println!("여기에서 코드를 수정하고 실행할 수 있습니다!"),//ko Korean\n 6 => println!("Ten kod można edytować oraz uruchomić!"),//pl Polish\n 7 => println!("Este código é editável e executável!"),//pt Portuguese\n 8 => println!("Этот код можно отредактировать и запустить!"),//ru Russian\n 9 => println!("Bạn có thể edit và run code trực tiếp!"),//vi Vietnamese\n 10 => println!("这段代码是可以编辑并且能够运行的!"),//zh Chinese\n 11 => println!("Dieser Code kann bearbeitet und ausgeführt werden!"),//de German\n 12 => println!("Den här koden kan redigeras och köras!"),//sv Swedish\n 13 => println!("Tento kód můžete upravit a spustit"),//cs Czech\n 14 => println!("این کد قابلیت ویرایش و اجرا دارد!"),//fa Persian\n 15 => println!("Denne kode kan redigeres og køres!"),//da Danish\n 16 => println!("Deze code is bewerkbaar en uitvoerbaar!"),//du Dutch\n 17 => println!("Tämä koodi on muokattavissa ja ajettavissa!"),//fi Finnish\n 18 => println!("Ez a kód szerkeszthető és futtatható!"),//hu Hungarian\n 19 => println!("Denne koden er redigerbar og kjørbar!"),//no Norwegian\n 20 => println!("Acest cod este editabil și rulabil!"),//ro Romanian\n 21 => println!("Bu kod düzenlenebilir ve çalıştırılabilir!"),//tr Turkish\n _ => {},\n }\n }\n}\n\nBash\n#!/bin/bash\nfor d in /sys/kernel/iommu_groups/*/devices/*; do\n n=${d#*/iommu_groups/*}; n=${n%%/*}\n printf \'IOMMU Group %s \' "$n"\n lspci -nns "${d##*/}"\ndone\n\nTOML\n1base_url = "https://abridge.netlify.app/"\n2title = "Abridge"\n3description = "Abridge is a fast and lightweight Zola theme using semantic html, abridge.css class-light CSS, and No Mandatory JS."\n4default_language = "en"\n5#theme = "abridge"\n6\n7build_search_index = true\n8minify_html = false\n9feed_filename = "atom.xml"\n10taxonomies = [\n11 {name = "categories", feed = true},\n12 {name = "tags", feed = true},\n13]\n\nHTML\n<!doctype html>\n<html lang="en">\n<head>\n <meta charset="utf-8">\n <title>Example HTML5 Document</title>\n</head>\n<body>\n <!--Main Content Area-->\n <p>Test</p>\n</body>\n</html>\n\nCSS\nhtml {\n font-size: var(--fs);\n}\n\n.c {\n text-align: center;\n}\n\nSCSS\n\n$font: Roboto system-ui -apple-system BlinkMacSystemFont "Segoe UI" Oxygen Ubuntu Cantarell "Fira Sans" "Droid Sans" "Helvetica Neue" "Noto Sans" Helvetica Arial sans-serif !default;\n$font-mono: ui-monospace Menlo Monaco Consolas "SF Mono" "Cascadia Mono" "Segoe UI Mono" "DejaVu Sans Mono" "Liberation Mono" "Roboto Mono" "Oxygen Mono" "Ubuntu Monospace" "Ubuntu Mono" "Source Code Pro" "Fira Mono" "Droid Sans Mono" "Courier New" Courier monospace !default;\n\n@mixin font {\n // convert space separated list to comma separated list\n $font: list.join($font, "", $separator: comma);\n $font: functions.remove($font, "");\n $font-mono: list.join($font-mono, "", $separator: comma);\n $font-mono: functions.remove($font-mono, "");\n\n $font: functions.font-var($font, $fontExt-Main, $findFont-Main);\n $font-mono: functions.font-var($font-mono, $fontExt-Code, $findFont-Code);\n\n #{--ff}: $font;\n #{--fm}: $font-mono;//code\n}\n\nJavascript\nfunction closeSearch() {//close the search displaying the regular page.\n const e = document.querySelector("main");\n e.innerHTML = window.main\n}\n\nfunction goSearch() {// on enter key or search icon click display results to the page.\n const e = document.querySelector("main");\n window.main || (window.main = e.innerHTML);\n var t = document.getElementById("suggestions"),\n n = ((ResultsClone = t.cloneNode(!0)).id = "results", document.createElement("div")),\n o = \'<h2><button type="button" title="Close Search" onclick="closeSearch()"><i class="svgs x"></i></button> Results For: \'.concat(document.getElementById("searchinput").value, "</h2>");\n return n.innerHTML = o, ResultsClone.insertBefore(n, ResultsClone.firstChild), e.innerHTML = ResultsClone.outerHTML, t.innerHTML = "", document.getElementById("searchinput").value = "", !1\n}! function() {\n // search function code goes here\n}\n\nPHP\n<?php\n/**\n * Postfix Admin\n */\nrequire_once(\'common.php\');\n$CONF = Config::getInstance()->getAll();\n\nif ($_SERVER[\'REQUEST_METHOD\'] == "POST") {\n if (!isset($_SESSION[\'PFA_token\'])) {\n die("Invalid token (session timeout; refresh the page and try again?)");\n }\n $fUsername = trim(safepost(\'fUsername\'));\n if ($lang != check_language(false)) { # only set cookie if language selection was changed\n setcookie(\'lang\', $lang, time() + 60*60*24*30); # language cookie, lifetime 30 days\n }\n}\n\n$_SESSION[\'PFA_token\'] = md5(uniqid("pfa" . rand(), true));\n\n/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */\n\nJson\n{\n "name": "Abridge Zola Theme",\n "short_name": "Abridge",\n "description": "Fast & Lightweight Zola Theme",\n "start_url": "/index.html",\n "scope": "/",\n "background_color": "#111111",\n "theme_color": "#222222",\n "display": "standalone",\n "icons": [\n {\n "src": "/android-chrome-192x192.png",\n "sizes": "192x192",\n "type": "image/png"\n },\n {\n "src": "/android-chrome-512x512.png",\n "sizes": "512x512",\n "type": "image/png"\n },\n {\n "src": "/android-chrome-192x192m.png",\n "sizes": "192x192",\n "type": "image/png",\n "purpose": "maskable"\n }\n ]\n}\n\nSQL\n-- jelly-actix-web-starter - Creates an accounts table, along with some associated helpers.\n\ncreate or replace function update_timestamp() returns trigger as $$\nbegin\n new.updated = now();\n return new;\nend;\n$$ language \'plpgsql\';\n\ncreate table if not exists accounts (\n id serial primary key,\n name text not null,\n email text not null unique,\n password text not null,\n profile jsonb not null default \'{}\',\n plan integer not null default 0,\n is_active boolean not null default true,\n is_admin boolean not null default false,\n has_verified_email boolean not null default false,\n last_login timestamp with time zone,\n created timestamp with time zone not null default now(),\n updated timestamp with time zone not null default now()\n);\n\ncreate unique index accounts_unique_lower_email_idx on accounts (lower(email));\n\ncreate trigger user_updated before insert or update on accounts\nfor each row execute procedure update_timestamp();\n\nLua\nfunction square(x)\n return x * x\nend\n\nprint(square(2)) -- prints \'4\'\n\nfunction getPlayerInformation()\n playerName = UnitName("player")\n playerLevel = UnitLevel("player")\n specId, specName = GetSpecializationInfo(GetSpecialization())\n\n return "Hey, I\'m " .. playerName .. " (Level " .. playerLevel .. "). I\'m currently in spec " .. specName .. "."\nend\n\nprint(getPlayerInformation())\n\nC\n#include <stdio.h>\nint main() {\n int a;\n /* actual initialization */\n a = 10;\n printf("Hello, World!");\n return 0;\n}\n\nC++\n// Your First C++ Program\n\n#include <iostream>\n\nint main() {\n int a;\n /* actual initialization */\n a = 10;\n std::cout << "Hello World!";\n return 0;\n}\n\nGo\npackage main\n\nimport "fmt"\n\nfunc main() {\n var myvariable1 = 20\n var myvariable2 = "hello world"\n fmt.Println("hello world")\n}\n\nPython\n#!/usr/bin/env python3\nimport smtplib, socket\nfrom influxdb import InfluxDBClient\n\nwhile True:\n send = 1\n later = time.time() + 25200\n iso = time.ctime(later)\n tempF = round(bme280.temperature * 1.8 + 29, 3) #C to F formula is +32, difference is to correct bme280 temperature offset\n humidity = round(bme280.humidity, 3)\n pressure = round(bme280.pressure, 3)\n # serialize data as JSON\n data = [\n {\n "measurement": measurement,\n "tags": {\n "location": location,\n },\n "time": iso,\n "fields": {\n "temperature" : tempF,\n "humidity": humidity,\n "pressure": pressure\n }\n }\n ]\n # Send the JSON data to InfluxDB\n try:\n client.write_points(data)\n except socket.error as e:\n print("Could Not Connect to InfluxDB!")\n if tempF > 90 and humidity > 55:\n emailSubject = "Humidity>55: " + str(int(humidity)) + "%H , Temperature>90: " + str(int(tempF)) + "F"\n emailContent = \'Humidity: \' + str(int(humidity)) + \'%H , Temperature: \' + str(int(tempF)) + \'F <a href="https://metrics.example.com">Dashboard</a>\'\n elif humidity > 55:\n emailSubject = "Humidity>55: " + str(int(humidity)) + "%H"\n emailContent = \'Humidity: \' + str(int(humidity)) + \'%H , Temperature: \' + str(int(tempF)) + \'F <a href="https://metrics.example.com">Dashboard</a>\'\n elif tempF > 90:\n emailSubject = "Temperature>90: " + str(int(tempF)) + "F"\n emailContent = \'Humidity: \' + str(int(humidity)) + \'%H , Temperature: \' + str(int(tempF)) + \'F <a href="https://metrics.example.com">Dashboard</a>\'\n else:\n send = 0\n if send == 1:\n try:\n if time.time() > lastEmailTime or abs(lastTemp-int(tempF)) > 1:\n lastEmailTime = time.time()+emailInterval\n lastTemp = int(tempF)\n sender.sendmail(\'jake@example.com\', emailSubject, emailContent)\n except socket.error as e:\n print("Could Not Connect to SMTP server!")\n time.sleep(interval)\n\nRuby\n=begin\n Ruby program to check whether the\n year is leap year or not between range.\n=end\n\nputs "Enter the lower limit:"\nlwr = gets.chomp.to_i\nputs "Enter the upper limit:"\nupr = gets.chomp.to_i\n\nfor yr in lwr..upr do\n if yr % 400 == 0\n puts "#{yr} is a leap year"\n elsif yr % 4 == 0 && yr % 100 !=0\n puts "#{yr} is a leap year"\n else\n puts "#{yr} is not a leap year"\n end\nend\n\n',description:"Sample article showcasing syntax highlighting and formatting for Code Blocks with a custom theme.",id:"https://abridge.netlify.app/overview-code-blocks/",title:"Code Blocks and Themes"},"https://abridge.netlify.app/overview-embed-streamable/":{body:'Zola has many shortcodes, and new are easily added, this example shows streamable.\nStreamable\nUsage\n{{ streamable(id="92ok4") }}\n\n\nid: the video id (mandatory)\nclass: a class to add to the <div> surrounding the iframe (optional)\ntitle - set alt title for the iframe (optional, defaults to "Streamable")\n\nOutput\n<div class="yv">\n <iframe src="https://www.streamable.com/e/92ok4" title="Streamable" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n</div>\n\n\n\n \n\n',description:"Sample article showcasing a custom Zola shortcode for embedding Streamable Videos into your pages.",id:"https://abridge.netlify.app/overview-embed-streamable/",title:"Embed Streamable Video"},"https://abridge.netlify.app/overview-embed-vimeo/":{body:'Zola has many shortcodes, and new are easily added, this example shows vimeo.\nVimeo\nUsage\n{{ vimeo(id="514402648") }}\n\n\nid: the video id (mandatory)\nclass: a class to add to the <div> surrounding the iframe (optional)\nautoplay: when set to "true", the video autoplays on load (optional)\nloop: when set to "true", the video plays on a loop (optional)\nnoautopause: when set to "true", the video will not autopause (optional)\ntitle - set alt title for the iframe (optional, defaults to "Vimeo")\ncookie - set to "true" if you want tracking cookies, otherwise it defaults to false.\n\nOutput\n<div class="yv">\n <iframe src="https://player.vimeo.com/video/514402648?embedded=true&dnt=1" title="Vimeo" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n</div>\n\n\n\n \n\n',description:"Sample article showcasing a custom Zola shortcode for embedding Vimeo Videos into your pages.",id:"https://abridge.netlify.app/overview-embed-vimeo/",title:"Embed Vimeo Video"},"https://abridge.netlify.app/overview-embed-youtube/":{body:'Zola has many shortcodes, and new are easily added, this example shows youtube.\nYoutube\nUsage\n{{ youtube(id="32gyFIWecuw") }}\n\n\nid: the video id (mandatory)\nplaylist: the playlist id (optional)\nclass: a class to add to the <div> surrounding the iframe (optional)\nautoplay: when set to "true", the video autoplays on load (optional)\ntitle - set alt title for the iframe (optional, defaults to "Youtube")\ncookie - set to "true" if you want tracking cookies, otherwise it defaults to false.\n\nOutput\n<div class="yv">\n <iframe src="https://www.youtube-nocookie.com/embed/32gyFIWecuw" title="Youtube" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n</div>\n\n\n\n \n\n',description:"Sample article showcasing a custom Zola shortcode for embedding Youtube Videos into your pages.",id:"https://abridge.netlify.app/overview-embed-youtube/",title:"Embed Youtube Video"},"https://abridge.netlify.app/overview-images/":{body:'This post covers the imgswap and img shortcodes. Images can also be embedded directly using markdown ![Ferris](ferris.svg), but it is better to use a shortcode so you can explicitly set the width and height, this will help prevent content layout shift which improves user experience and the google lighthouse score.\nimg Shortcode\n\nsrc is the path and filename of the image. (mandatory)\nclass sets a class for the image. (optional)\nalt sets the alt note for the image.\nw is the width of the image.\nh is the height of the image.\n\n** google lighthouse recommends setting alt, w, and h attributes. If alt is omitted then the filename is used. If w or h are omitted then get_image_metadata() fills these values. **\nUsage (same path)\n{{ img(src="ferris-happy.svg" alt="Ferris is Happy") }}\n\nOutput\n \n<img src="ferris-happy.svg" alt="Ferris is Happy" width="600" height="400" loading="lazy" />\n\n\n \n\nUsage (relative path ./)\n{{ img(src="./img/ferris-gesture.svg" alt="Ferris says Hello") }}\n\nOutput\n \n<img src="img/ferris-gesture.svg" alt="Ferris says Hello" width="600" height="400" loading="lazy" />\n\n\n \n\nUsage (root path /)\n{{ img(src="/overview-rich-content/ferris.svg" alt="Ferris the Rustacean") }}\n\nOutput\n \n<img src="https://abridge.netlify.app/overview-rich-content/ferris.svg" alt="Ferris the Rustacean" width="600" height="400" loading="lazy" />\n\n\n \n\nSVG image directly in code\n<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 489" width="600" height="489"><g fill="#8f1f1d"><path d="M70 324c1 3 3 4 6 4l24 4 2 5-10 20v5l7 4 24-1 4 4-7 21c0 2 0 4 3 6 1 2 4 2 7 2l24-5 4 4-1 22c-1 2 0 4 3 5h6l23-8 6 3 4 22c0 2 1 3 3 4h7l21-13 6 2 8 20 5 5c3 0 5 0 7-2l18-15h5l13 18c1 2 3 4 6 4l5-3 14-18h6l17 16c1 1 4 2 6 1 3 0 5-1 6-3l9-21 6-1 19 14h7c3 0 5-3 5-5l4-21 6-2 22 9 7-1c2-1 3-2 3-5v-21l5-4 24 6c3 0 5 0 6-2 2-2 3-4 2-6l-4-21 3-5 24 2c4 0 6 0 7-3v-5l-9-21 3-5 25-2 5-5-1-5-14-18c0-1-1-19-12-33v-1c-26-36-106-64-201-65-100-2-184 26-206 64-10 10-12 26-11 26l-15 17c-1 3-2 5-1 7z"/><path d="M565 247c-1-3-12-2-14-3l-38 1-4-7 26-38c1-2 7-7 6-9-3-3-12 1-14 1l-39 7-4-6 22-49c0-3 7-15 5-18-2-2-11 6-13 6l-43 28-4-5 11-43c0-3 7-18 5-19-2-2-9 5-12 6l-38 30-5-4 9-51c0-3 3-18 1-19s-15 13-17 14l-30 38-6-3-3-56c0-3 0-14-3-14-3-1-5 8-8 11l-25 50-7-1-13-57c-1-3-2-12-4-12-4 0-5 10-7 13l-15 56-7 1-22-52c-1-2-4-12-7-12-3 1-2 9-3 12l-7 61-6 3-19-27c-3-1-15-19-18-18-2 1 0 21-1 23l1 40-6 4-36-35c-3-1-7-7-10-5-2 2 0 10 0 13l13 53-4 5-41-26c-2-1-10-7-12-4-2 2 3 4 3 7l22 56-5 6-65-22c-3-1-10-5-12-1-1 2 5 6 6 9l49 53-3 7-47-6c-3 0-9-1-11 1-1 4 6 7 7 9l36 40a116 116 0 0 0 14 46c27 50 110 87 209 87 105 0 193-41 214-95 11-15 13-37 12-38l29-31c2-4 9-9 8-11z"/><path d="m99 289-67 10c-13 3-5 5 0 6 14 2 84 3 85 4zm402 3 67 10c13 4 5 6 0 6-14 2-84 5-86 5z"/></g><path d="M227 293s-24-26-47 0c0 0-18 35 0 52 0 0 30 24 47 0 0 0 21-20 0-52z"/><path fill="#fff" d="M200 302c0 11 6 19 14 19 7 0 12-8 12-19 0-10-5-18-12-18-8 0-14 8-14 18z"/><path d="M360 283s-40-17-52 22c0 0-11 47 33 49 0 0 58-10 19-71z"/><path fill="#fff" d="M339 299c0 10 7 20 14 20 8 0 14-10 14-20s-6-18-14-18c-7 0-14 8-14 18z"/></svg>\n\n\nimgswap Shortcode\nBy default main_src is the image displayed, swap_src is displayed on mouse hover.\nWhen you hover your mouse over the image it will display the image to compare.\n\nmain_src is the path and filename for the default image. (mandatory)\nswap_src is the path and filename for the swap image. (mandatory)\nclass sets a class for the image. (optional)\nalt sets the alt note for the image.\nw is the width of the image.\nh is the height of the image.\n\n** google lighthouse recommends setting alt, w, and h attributes. If alt is omitted then the filename is used. If w or h are omitted then get_image_metadata() fills these values. **\nUsage (same path)\n{{ imgswap(main_src="ferris.svg" swap_src="ferris-happy.svg") }}\n\nOutput\n<div class="img-swap-div"> \n <img src="ferris.svg" class="img-main" alt="ferris" width="600" height="400" loading="lazy" /> \n <img src="ferris-happy.svg" class="img-swap" alt="ferris" width="600" height="400" loading="lazy" />\n</div>\n\n\n \n \n \n\nUsage (relative path ./)\n{{ imgswap(main_src="./img/ferris.svg" swap_src="./img/ferris-gesture.svg") }}\n\nOutput\n<div class="img-swap-div"> \n <img src="img/ferris.svg" class="img-main" alt="ferris" width="600" height="400" loading="lazy" /> \n <img src="img/ferris-gesture.svg" class="img-swap" alt="ferris" width="600" height="400" loading="lazy" />\n</div>\n\n\n \n \n \n\nUsage (root path /)\n{{ imgswap(main_src="/overview-rich-content/ferris.svg" swap_src="/overview-rich-content/ferris-gesture.svg") }}\n\nOutput\n<div class="img-swap-div"> \n <img src="https://abridge.netlify.app/overview-rich-content/ferris.svg" class="img-main" alt="ferris" width="600" height="400" loading="lazy" /> \n <img src="https://abridge.netlify.app/overview-rich-content/ferris-gesture.svg" class="img-swap" alt="ferris" width="600" height="400" loading="lazy" />\n</div>\n\n\n \n \n \n\n',description:"Images can be embedded directly using markdown `![Ferris](ferris.svg)`, but using a shortcode prevents CLS by explicitly setting the width and height.",id:"https://abridge.netlify.app/overview-images/",title:"Image Shortcodes"},"https://abridge.netlify.app/overview-markdown-and-style/":{body:'This article offers a sample of basic Markdown syntax that can be used in Zola content files, also it shows if basic HTML elements are decorated with CSS in a Zola theme.\nHeadings\nThe following HTML <h1>—<h6> elements represent six levels of section\nheadings. <h1> is the highest section level while <h6> is the lowest.\nH1\nH2\nH3\nH4\nH5\nH6\nParagraph\nXerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum,\nvoluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma\ndolestendit peritin re plis aut quas inctum laceat est volestemque commosa as\ncus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin\nporecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur?\nQuiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit\nut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda\nveliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore\neost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata\ntiustia prat.\nItatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne\nsapicia is sinveli squiatum, core et que aut hariosam ex eat.\nBlockquotes\nThe blockquote element represents content that is quoted from another source,\noptionally with a citation which must be within a footer or cite element,\nand optionally with in-line changes such as annotations and abbreviations.\nBlockquote no attribution\n\nTiam, ad mint andaepu dandae nostion secatur sequo quae.\nNote that you can use Markdown syntax within a blockquote.\n\nBlockquote attribution\n\nDon\'t communicate by sharing memory, share memory by communicating.\n— Rob Pike1\n\n\nAll men by nature desire to know.\n― Aristotle2\n\n\nPower comes in response to a need, not a desire.\n— Goku\n\nTables\nTables aren\'t part of the core Markdown spec, but Zola supports them\nout-of-the-box.\nNameAge\nAlice23\nBob27\nCody33\nJohn59\nKerry23\n\nTable Inline Markdown\nItalicsBoldCodeStrikeThrough\nitalicsboldcodestrikethrough\n\nLarge table within figure\nSurround very Large tables with <figure></figure> so they can scroll horizontally.\n\nManufacturerVolkswagenToyotaFordHondaChevroletBMWHyundaiAudiNissanKiaMercedesTeslaMitsubishiSuzukiVolvoSubaruMazdaJaguarBuickLexusGMCPorscheCadillac\nRevenue $B$254$249$127$124$123$113$88$83$74$61$55$54$38$31$30$28$27$22$21$19$17$16$12\n\n\n*revenue values found on search engine and not verified, for figure scroller table demonstration purposes only.*\nFoldable Text\n\n Title 1\n IT\'S A SECRET TO EVERYBODY.\n\n\n Title 2\n Stay awhile, and listen!\n\nCode Blocks\nCode blocks.. ❤️ with automatic syntax highlighting ✨‍\nSee the docs for options.\nCode block with backticks\n<!doctype html>\n<html lang="en">\n<head>\n <meta charset="utf-8">\n <title>Example HTML5 Document</title>\n</head>\n<body>\n <p>Test</p>\n</body>\n</html>\n\nLine Numbers, Highlights\n1<!doctype html>\n2<html lang="en">\n3<head>\n4 <meta charset="utf-8">\n5 <title>Example HTML5 Document</title>\n6</head>\n7<body>\n8 <p>Test</p>\n9</body>\n10</html>\n\nInline Code block\nIf we want, we can also specify inline code which is useful for the small stuff.\nList Types\nOrdered List\n\nFirst item\nSecond item\nThird item\n\nUnordered List\n\nList item\nAnother item\nAnd another item\n\nNested list\n\nFruit\n\nApple\nOrange\nBanana\n\n\nDairy\n\nMilk\nCheese\n\n\n\nOther Elements — abbr, sub, sup, kbd, mark, link\nGIF is a bitmap image format.\nH2O\nXn + Yn = Zn\nPress CTRL+ALT+Delete to end the\nsession.\nMost salamanders are nocturnal, and hunt for insects, worms, and\nother small creatures.\n\n\n1\nThe above quote is excerpted from Rob Pike\'s talk\nduring Gopherfest, November 18, 2015.\n\n2\nThe quote is the first sentence of Aristotle\'s Metaphysics.\n\nNavs\nSite primary menu is created by nesting the nav under a header tag. Refer to the top of this site for an example. Navigation is responsive, shrink the page width to see it in action.\nForms\n\n Name\n \n \n Email Address\n \n \n Message\n \n \n \n Send\n \n \n Fruit\n \n Select a fruit…\n Banana\n Watermelon\n Apple\n Orange\n Mango\n \n \n \n Size\n \n \n Small\n \n \n \n Medium\n \n \n \n Large\n \n \n \n Extra Large\n \n \n \n \n \n \n I agree to the Terms and Conditions\n \n \n \n I agree to share my information with partners\n \n \n \n \n \n \n Publish on my profile\n \n \n \n Publish on my profile my accomplishments\n \n \n \n \n \n \n File browser\n \n \n \n Range slider\n \n \n \n Date\n \n \n \n Time\n \n \n \n Color\n \n \n\n',description:"Sample article showcasing basic Markdown syntax and formatting for HTML elements.",id:"https://abridge.netlify.app/overview-markdown-and-style/",title:"Markdown and Style"},"https://abridge.netlify.app/overview-math/":{body:'You can use KaTeX to render mathematical notations.\nYou can enable the $\\KaTeX$ support globally, per-section or per-page basis.\nEnable Globally\nTo enable the $\\KaTeX$ support globally, add math = true under [extra] of the config.toml\nat your site root. Now the katex shortcode will be rendered, you can also add math_auto_render = true\nand every section and page of your site will load the KaTeX autorender extension.\n[extra]\nmath = true\nmath_auto_render = false\n\nPer-section Basis\nTo enable the $\\KaTeX$ support in a particular section, add math = true under [extra] in the [SECTION_NAME]/_index.md.\nNow the katex shortcode will be rendered, you can also add math_auto_render = true\nand the section of your site will load the KaTeX autorender extension.\n+++\n[extra]\nmath = true\n+++\n\nPer-page Basis\nTo enable the $\\KaTeX$ support in a particular page, add math = true under [extra] in the page\'s\nfrontmatter. Now the katex shortcode will be rendered, you can also add math_auto_render = true\nand the page of your site will load the KaTeX autorender extension.\n+++\n[extra]\nmath = true\nmath_auto_render = true\n+++\n\nIt is a good practice to enable $\\KaTeX$ support on a per-page basis, since this will only load the\nrequired files on that particular page, without affecting the page load speed of other pages.\nIf your site is not math-heavy, please do NOT enable this feature globally or per-section basis.\nUsage\nWrap any valid $\\KaTeX$ syntax with $...$ for inline\nMathematics and $$...$$ for block Mathematics.\nInline Mathematics\nThis is the most beautiful equation I\'ve ever seen:\nUsage\n{% katex(block=false) %} e^{i\\pi}+1=0 {% end %}\n\nOutput\n<script type="math/tex">e^{i\\pi}+1=0</script>\n\n\n\nBlock Mathematics\nSome Mathematics in display mode is fair enough:\nUsage\n{% katex(block=true) %} \\int_0^1 x^2 dx {% end %}\n\nOutput\n<script type="math/tex;mode=display">\\int_0^1 x^2 dx</script>\n\n\n\nAuto Render Inline\n$ e^{i\\pi}+1=0 $\n\n$ e^{i\\pi}+1=0 $\nAuto Render Block\n$$\nf(x) = \\int_{-\\infty}^\\infty\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\\,d\\xi\n$$\n\n$$\nf(x) = \\int_{-\\infty}^\\infty\\hat f(\\xi),e^{2 \\pi i \\xi x},d\\xi\n$$\n',description:"Sample article showcasing the display of Mathematical Notations, made possible by the KaTeX library.",id:"https://abridge.netlify.app/overview-math/",title:"Mathematical Notations"},"https://abridge.netlify.app/overview-rich-content/":{body:'Several custom shortcodes are included to augment CommonMark (courtesy of d3c3nt theme). video, image, gif, and audio were created to help you take advantage of modern HTML elements in your writing.\nVideo\nThe video shortcode takes a sources parameter (an array of strings)\nand returns a <video> tag. Each string in the sources array should\nbe a path to a video file of a different type (webm, mp4, etc). Each\nindividual source is then converted into a <source> tag, and the\nelement is returned.\nUsage\n{{ video(sources=["over9000_av1.mp4", "over9000_vp9.webm"]) }}\n\nOutput\n<video controls>\n <source src="https://abridge.netlify.app/overview-rich-content/over9000_av1.mp4" type="video/mp4" />\n <source src="https://abridge.netlify.app/overview-rich-content/over9000_vp9.webm" type="video/webm" />\n Your browser doesn\'t support the video tag and/or the video formats in use here – sorry!\n</video>\n\n\n\n \n \n Your browser doesn\'t support the video tag and/or the video formats in use here – sorry!\n\nImage\nThe image shortcode returns a <picture> tag and accepts three\nparameters: sources (an array of strings), fallback_path, and\nfallback_alt (both strings).\nEach string in the sources array should be a path to an image file of\na different type (avif, webp, png, jpg, etc). fpath and\nfalt are used to create an <img> tag for the browser to fall\nback on if the other formats aren\'t yet supported, fw and fh set the width and height of the fallback\nUsage\n{{ image(sources=["over9000-960.avif", "over9000-640.avif", "over9000-400.avif"], fpath="over9000-640.webp", fw=640, fh=480, falt="ITS OVER 9000!") }}\n\nOutput\n<picture>\n <source srcset="https://abridge.netlify.app/overview-rich-content/over9000-960.avif" type="img/avif" />\n <source srcset="https://abridge.netlify.app/overview-rich-content/over9000-640.avif" type="img/avif" />\n <source srcset="https://abridge.netlify.app/overview-rich-content/over9000-400.avif" type="img/avif" />\n <img src="over9000-640.webp" alt="ITS OVER 9000!" width="640" height="480" loading="lazy" />\n</picture>\n\n\n\n \n \n \n \n\nGIF\nThe gif shortcode is exactly the same as the video shortcode\n– it takes an array of strings called sources and returns a\n<video> tag. The only difference is in the outermost tag, which has\nfour additional properties: autoplay, loop, muted, playsinline.\nUsing the <video> tag in place of gifs allows for reduced file sizes,\nwhich is especially important in regions where internet is slower or\nless reliable.\nUsage\n{{ gif(sources=["over9000_av1.mp4", "over9000_vp9.webm"]) }}\n\nOutput\n<video autoplay loop muted playsinline>\n <source src="https://abridge.netlify.app/overview-rich-content/over9000_av1.mp4" type="video/mp4" />\n <source src="https://abridge.netlify.app/overview-rich-content/over9000_vp9.webm" type="video/webm" />\n Your browser doesn\'t support the video tag, which I use in place of .gifs, and/or the video formats in use here – sorry!\n</video>\n\n\n\n \n \n Your browser doesn\'t support the video tag, which I use in place of .gifs, and/or the video formats in use here – sorry!\n\nAudio\nThe audio shortcode takes a sources array of strings and returns an\n<audio> tag. Each string in the sources array should be a path to an\naudio file of a different type (ogg, mp3, flac, wav, etc).\nThe browser will play the first type it supports, so placing them in order of size smallest to largest will use the least bandwidth if that is your goal.\nUsage\n{{ audio(sources=["over9000.ogg", "over9000.mp3", "over9000.flac", "over9000.wav"]) }}\n\nOutput\n<audio controls>\n <source src="https://abridge.netlify.app/overview-rich-content/over9000.ogg" type="audio/ogg" />\n <source src="https://abridge.netlify.app/overview-rich-content/over9000.mp3" type="audio/mp3" />\n <source src="https://abridge.netlify.app/overview-rich-content/over9000.flac" type="audio/flac" />\n <source src="https://abridge.netlify.app/overview-rich-content/over9000.wav" type="audio/wav" />\n Your browser doesn\'t support the audio tag and/or the audio formats in use here – sorry!\n</audio>\n\n\n\n \n \n Your browser doesn\'t support the audio tag and/or the audio formats in use here – sorry!\n\n',description:"A brief description of custom Shortcodes for Zola that implement modern html elements: video, image, gif, audio.",id:"https://abridge.netlify.app/overview-rich-content/",title:"Rich Content"},"https://abridge.netlify.app/overview-showdata/":{body:'The showdata shortcode can load and display data from an external source via Zola\'s load_data() function.\n\nThese are the parameters, currently all 3 are required.\n\nsrc path or url to file (if url, must include the http(s):// prefix).\ntype the type of file to load. (supported types)\nkey the field in the data that you want to display.\n\nUsage\nThis theme requires version {{ showdata(src="https://raw.githubusercontent.com/Jieiku/abridge/master/theme.toml" type="toml" key="min_version") }} or later of Zola.\nOutput\nThis theme requires version \n \n 0.17.2\n or later of Zola.\n',description:"A brief description of a custom Shortcode for Zola that implements loading and displaying external data.",id:"https://abridge.netlify.app/overview-showdata/",title:"Showdata Shortcode"},"https://abridge.netlify.app/pages/":{body:"",description:"",id:"https://abridge.netlify.app/pages/",title:""},"https://abridge.netlify.app/privacy/":{body:"Privacy\n\nThis site does not set or use cookies.\nThis site does not store data in the browser to be shared, sent, or sold to third-parties.\nNo personal information is shared, sent, or sold to third-parties.\n\nEffective Date: 1st Jan 2022\n",description:"This page outlines the Privacy Policy for this site, and the date at which this policy was put into affect.",id:"https://abridge.netlify.app/privacy/",title:"Privacy Policy"}},docInfo:{"https://abridge.netlify.app/":{body:0,description:0,title:0},"https://abridge.netlify.app/about/":{body:39,description:0,title:0},"https://abridge.netlify.app/archive/":{body:0,description:0,title:0},"https://abridge.netlify.app/contact/":{body:0,description:6,title:1},"https://abridge.netlify.app/offline/":{body:10,description:0,title:2},"https://abridge.netlify.app/overview-abridge/":{body:1579,description:14,title:3},"https://abridge.netlify.app/overview-code-blocks/":{body:978,description:10,title:3},"https://abridge.netlify.app/overview-embed-streamable/":{body:42,description:10,title:3},"https://abridge.netlify.app/overview-embed-vimeo/":{body:71,description:10,title:3},"https://abridge.netlify.app/overview-embed-youtube/":{body:63,description:10,title:3},"https://abridge.netlify.app/overview-images/":{body:841,description:14,title:2},"https://abridge.netlify.app/overview-markdown-and-style/":{body:480,description:9,title:2},"https://abridge.netlify.app/overview-math/":{body:201,description:10,title:2},"https://abridge.netlify.app/overview-rich-content/":{body:372,description:13,title:2},"https://abridge.netlify.app/overview-showdata/":{body:50,description:10,title:2},"https://abridge.netlify.app/pages/":{body:0,description:0,title:0},"https://abridge.netlify.app/privacy/":{body:26,description:9,title:2}},length:17},lang:"English"},function(){function h(d){var e=new h.Index;return e.pipeline.add(h.trimmer,h.stopWordFilter,h.stemmer),d&&d.call(e,e),e}var r,p,d,e,n,l,v,b,g,y,w,m,u,k,x,S,_,T,$,I,z,C,j,E,o;h.version="0.9.5",((lunr=h).utils={}).warn=(o=this,function(d){o.console&&console.warn&&console.warn(d)}),h.utils.toString=function(d){return null==d?"":d.toString()},(h.EventEmitter=function(){this.events={}}).prototype.addListener=function(){var d=Array.prototype.slice.call(arguments),e=d.pop();if("function"!=typeof e)throw new TypeError("last argument must be a function");d.forEach(function(d){this.hasHandler(d)||(this.events[d]=[]),this.events[d].push(e)},this)},h.EventEmitter.prototype.removeListener=function(d,e){this.hasHandler(d)&&-1!==(e=this.events[d].indexOf(e))&&(this.events[d].splice(e,1),0==this.events[d].length)&&delete this.events[d]},h.EventEmitter.prototype.emit=function(d){var e;this.hasHandler(d)&&(e=Array.prototype.slice.call(arguments,1),this.events[d].forEach(function(d){d.apply(void 0,e)},this))},h.EventEmitter.prototype.hasHandler=function(d){return d in this.events},(h.tokenizer=function(d){var e,o;return arguments.length&&null!=d?Array.isArray(d)?(e=(e=d.filter(function(d){return null!=d})).map(function(d){return h.utils.toString(d).toLowerCase()}),o=[],e.forEach(function(d){d=d.split(h.tokenizer.seperator);o=o.concat(d)},this),o):d.toString().trim().toLowerCase().split(h.tokenizer.seperator):[]}).defaultSeperator=/[\s\-]+/,h.tokenizer.seperator=h.tokenizer.defaultSeperator,h.tokenizer.setSeperator=function(d){null!=d&&"object"==typeof d&&(h.tokenizer.seperator=d)},h.tokenizer.resetSeperator=function(){h.tokenizer.seperator=h.tokenizer.defaultSeperator},h.tokenizer.getSeperator=function(){return h.tokenizer.seperator},(h.Pipeline=function(){this._queue=[]}).registeredFunctions={},h.Pipeline.registerFunction=function(d,e){e in h.Pipeline.registeredFunctions&&h.utils.warn("Overwriting existing registered function: "+e),d.label=e,h.Pipeline.registeredFunctions[e]=d},h.Pipeline.getRegisteredFunction=function(d){return d in h.Pipeline.registeredFunctions!=1?null:h.Pipeline.registeredFunctions[d]},h.Pipeline.warnIfFunctionNotRegistered=function(d){d.label&&d.label in this.registeredFunctions||h.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",d)},h.Pipeline.load=function(d){var o=new h.Pipeline;return d.forEach(function(d){var e=h.Pipeline.getRegisteredFunction(d);if(!e)throw new Error("Cannot load un-registered function: "+d);o.add(e)}),o},h.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach(function(d){h.Pipeline.warnIfFunctionNotRegistered(d),this._queue.push(d)},this)},h.Pipeline.prototype.after=function(d,e){h.Pipeline.warnIfFunctionNotRegistered(e);d=this._queue.indexOf(d);if(-1===d)throw new Error("Cannot find existingFn");this._queue.splice(d+1,0,e)},h.Pipeline.prototype.before=function(d,e){h.Pipeline.warnIfFunctionNotRegistered(e);d=this._queue.indexOf(d);if(-1===d)throw new Error("Cannot find existingFn");this._queue.splice(d,0,e)},h.Pipeline.prototype.remove=function(d){d=this._queue.indexOf(d);-1!==d&&this._queue.splice(d,1)},h.Pipeline.prototype.run=function(d){for(var e=[],o=d.length,t=this._queue.length,s=0;sc[t]&&t++:(e.add(i[o]),o++,t++);return e},lunr.SortedSet.prototype.clone=function(){var d=new lunr.SortedSet;return d.elements=this.toArray(),d.length=d.elements.length,d},lunr.SortedSet.prototype.union=function(d){for(var e,d=this.length>=d.length?(e=this,d):(e=d,this),o=e.clone(),t=0,s=d.toArray();t

Results For: '.concat(document.getElementById("searchinput").value,"

");return t.innerHTML=s,o.insertBefore(t,o.firstChild),d.innerHTML=o.outerHTML,e.innerHTML="",document.getElementById("searchinput").value="",document.body.contains(document.closeSearch)&&(document.closeSearch.onsubmit=function(){document.querySelector("main").innerHTML=window.main}),!1}function k(d){return d=parseInt(d,16).toString(2),[0,1,2,3,4][Math.ceil(d.length/8)]}var r,f,o,p;document.body.contains(document.goSearch)&&(document.goSearch.onsubmit=function(){return goSearchNow()},r=document.getElementById("suggestions"),f=document.getElementById("searchinput"),document.addEventListener("keydown",function(e){if(191===e.keyCode&&"INPUT"!==document.activeElement.tagName&&"TEXTAREA"!==document.activeElement.tagName&&(e.preventDefault(),f.focus(),r.classList.remove("d-none")),27===e.keyCode){f.blur(),r.classList.add("d-none");for(var d=document.getElementById("suggestions");d.firstChild;)d.removeChild(d.firstChild)}var o=r.querySelectorAll("a");if(!r.classList.contains("d-none")&&0!==o.length){var t=[...o],s=t.indexOf(document.activeElement);let d=0;38===e.keyCode?(e.preventDefault(),o[d=0",a=o.querySelector("a"),t=o.querySelector("span:first-child"),d=o.querySelector("span:nth-child(2)"),a.href=e.ref,t.textContent=e.doc.title,d.innerHTML=function(d,e){var o=e.map(function(d){return elasticlunr.stemmer(d.toLowerCase())}),t=!1,s=0,f=[],i=d.toLowerCase().split(". ");for(b in i){var c,a=i[b].split(/[\s\n]/),r=8;for(c in a){if(0<(m=a[c]).length){for(var p in o)elasticlunr.stemmer(m).startsWith(o[p])&&(r=40,t=!0);f.push([m,r,s]),r=2}s=s+m.length+1}s+=1}if(0===f.length)return void 0!==d.length&&300"),w=m[2]+m[0].length;40!==m[1]&&12<=m[0].length&&!/^[\x00-\xff]+$/.test(m[0])?(u=function(d,e){for(var o="",t=!1,s=0,f=0,i=0,c=0;c")}return y.push("…"),y.join("")}(e.doc.body,c),r.appendChild(o))});for(;f.length>i;)r.removeChild(f[0])},!0),r.addEventListener("click",function(){for(;r.lastChild;)r.removeChild(r.lastChild);return!1},!0),p=elasticlunr.Index.load(window.searchIndex),document.goSearch.onsubmit=e)}; \ No newline at end of file diff --git a/js/search_stork.min.js b/js/search_stork.min.js new file mode 100644 index 0000000..40adad3 --- /dev/null +++ b/js/search_stork.min.js @@ -0,0 +1 @@ +function loadStork(){var e=document.querySelector("meta[name='base']").getAttribute("content");"/"==e.slice(-1)&&(e=e.slice(0,-1)),stork.initialize(e+"/stork.wasm").then(()=>{}).catch(e=>{}),stork.register("stork",e+"/stork.st")}(()=>{function r(e){var t=o[e];return void 0!==t||(t=o[e]={exports:{}},n[e].call(t.exports,t,t.exports,r)),t.exports}var n={214:(e,t,r)=>{function o(e){return s[e]}function d(){return n=null!==n&&n.buffer===p.memory.buffer?n:new Uint8Array(p.memory.buffer)}function h(n,r,t){if(void 0===t){let e=l.encode(n),t=r(e.length);return d().subarray(t,t+e.length).set(e),m=e.length,t}let o=n.length,s=r(o);var i=d();let a=0;for(;av,wasm_register_index:()=>function(e,t){try{var n=p.__wbindgen_add_to_stack_pointer(-16),r=h(e,p.__wbindgen_malloc,p.__wbindgen_realloc),o=m,s=(u=t,c=(0,p.__wbindgen_malloc)(+u.length),d().set(u,+c),m=u.length,c),i=m,a=(p.wasm_register_index(n,r,o,s,i),f()[n/4+0]),l=f()[n/4+1];return g(a,l)}finally{p.__wbindgen_add_to_stack_pointer(16),p.__wbindgen_free(a,l)}var u,c},wasm_search:()=>function(e,t){try{var n=p.__wbindgen_add_to_stack_pointer(-16),r=h(e,p.__wbindgen_malloc,p.__wbindgen_realloc),o=m,s=h(t,p.__wbindgen_malloc,p.__wbindgen_realloc),i=m,a=(p.wasm_search(n,r,o,s,i),f()[n/4+0]),l=f()[n/4+1];return g(a,l)}finally{p.__wbindgen_add_to_stack_pointer(16),p.__wbindgen_free(a,l)}},wasm_stork_version:()=>function(){try{var e=p.__wbindgen_add_to_stack_pointer(-16),t=(p.wasm_stork_version(e),f()[e/4+0]),n=f()[e/4+1];return g(t,n)}finally{p.__wbindgen_add_to_stack_pointer(16),p.__wbindgen_free(t,n)}}}),Array(32).fill(void 0)),i=(s.push(void 0,null,!0,!1),s.length),m=0,n=null,l=new TextEncoder("utf-8"),u="function"==typeof l.encodeInto?function(e,t){return l.encodeInto(e,t)}:function(e,t){var n=l.encode(e);return t.set(n),{read:e.length,written:n.length}},a=null,c=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),v=(c.decode(),async function e(t){void 0===t&&(t=new URL("stork_bg.wasm",function(){var e=r.p;let t="";return e&&~e.indexOf("://")||(t+=window.location.protocol+"//"+window.location.host),(t+=e||"/")+"node_modules/stork-search/stork.js"}()));var n={wbg:{}},{instance:t,module:n}=(n.wbg.__wbg_new_693216e109162396=function(){return e=Error(),i===s.length&&s.push(s.length+1),t=i,i=s[t],s[t]=e,t;var e,t},n.wbg.__wbg_stack_0ddaca5d1abfb52f=function(e,t){var t=h(o(t).stack,p.__wbindgen_malloc,p.__wbindgen_realloc),n=m;f()[e/4+1]=n,f()[e/4+0]=t},n.wbg.__wbg_error_09919627ac0992f5=function(e,t){p.__wbindgen_free(e,t)},n.wbg.__wbindgen_object_drop_ref=function(e){o(e),(e=e)<36||(s[e]=i,i=e)},await async function(e,t){if("function"==typeof Response&&e instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(e,t)}catch(t){if("application/wasm"==e.headers.get("Content-Type"))throw t}var n=await e.arrayBuffer();return WebAssembly.instantiate(n,t)}n=await WebAssembly.instantiate(e,t);return n instanceof WebAssembly.Instance?{instance:n,module:e}:n}(await(t="string"==typeof t||"function"==typeof Request&&t instanceof Request||"function"==typeof URL&&t instanceof URL?fetch(t):t),n));return p=t.exports,e.__wbindgen_wasm_module=n,p})},914:(e,l,t)=>{Object.defineProperty(l,"__esModule",{value:!0}),l.calculateOverriddenConfig=l.defaultConfig=void 0;var u=t(445),c=t(466);l.defaultConfig={showProgress:!0,printIndexInfo:!1,showScores:!1,showCloseButton:!0,minimumQueryLength:3,forceOverwrite:!1,resultNoun:{singular:"file",plural:"files"},onQueryUpdate:void 0,onResultSelected:void 0,onResultsHidden:void 0,onInputCleared:void 0,transformResultUrl:function(e){return e}},l.calculateOverriddenConfig=function(e){var t,n=(0,c.difference)(Object.keys(e),Object.keys(l.defaultConfig));if(0{Object.defineProperty(t,"__esModule",{value:!0}),t.existsBeyondContainerBounds=t.setText=t.clear=t.add=t.create=void 0,t.create=function(e,t){e=document.createElement(e);return t.classNames&&e.setAttribute("class",t.classNames.join(" ")),e},t.add=function(e,t,n){n.insertAdjacentElement(t,e)},t.clear=function(e){for(;e&&e.firstChild;)e.removeChild(e.firstChild)},t.setText=function(e,t){t=document.createTextNode(t);e&&e.firstChild?e.replaceChild(t,e.firstChild):e&&e.appendChild(t)},t.existsBeyondContainerBounds=function(e,t){e=e.getBoundingClientRect(),t=t.getBoundingClientRect();return e.bottom>t.bottom||e.top{Object.defineProperty(t,"__esModule",{value:!0}),t.Entity=void 0;var r=n(139),o=n(771),s=n(214),i=n(445);function a(e,t,n){var r=this;this._state="initialized",this.downloadProgress=0,this.results=[],this.totalResultCount=0,this.eventListenerFunctions={},this.highlightedResult=0,this.resultsVisible=!1,this.hoverSelectEnabled=!0,this.setDownloadProgress=function(e){r.state="loading",r.downloadProgress=e,r.config.showProgress&&r.render()},this.name=e,this.url=t,this.config=n}Object.defineProperty(a.prototype,"state",{get:function(){return this._state},set:function(e){this._state=e,this.render()},enumerable:!1,configurable:!0}),a.prototype.getCurrentMessage=function(){var e;return this.domManager?(e=this.domManager.getQuery(),"error"===this.state?"Error! Check the browser console.":"ready"!=this.state?"Loading...":(null==e?void 0:e.length){Object.defineProperty(t,"__esModule",{value:!0}),t.EntityDom=void 0;var a=n(227),i=n(9),o={results:[],resultsVisible:!1,showScores:!1,message:null,showProgress:!1,progress:1,state:"ready"};function r(n,e){var r=this,e=(this.scrollAnchorPoint="end",this.entity=e,[{selector:'input[data-stork="'.concat(n,'"]'),elementName:"input"},{selector:'div[data-stork="'.concat(n,'-output"]'),elementName:"output"}].map(function(e){var t=document.querySelector(e.selector);if(t)return t;throw Error('Could not register search box "'.concat(n,'": ').concat(e.elementName," element not found. Make sure an element matches the query selector `").concat(e.selector,"`"))})),t=e[0],e=e[1];this.elements={input:t,output:e,list:(0,a.create)("ul",{classNames:["stork-results"]}),attribution:(0,a.create)("div",{classNames:["stork-attribution"]}),progress:(0,a.create)("div",{classNames:["stork-progress"]}),message:(0,a.create)("div",{classNames:["stork-message"]}),closeButton:(0,a.create)("button",{classNames:["stork-close-button"]})},this.elements.input.removeEventListener("input",this.entity.eventListenerFunctions.inputInputEvent),this.elements.input.removeEventListener("keydown",this.entity.eventListenerFunctions.inputKeydownEvent),this.entity.eventListenerFunctions={inputInputEvent:function(e){r.handleInputEvent(e)},inputKeydownEvent:function(e){r.handleKeyDownEvent(e)}},this.elements.input.addEventListener("input",this.entity.eventListenerFunctions.inputInputEvent),this.elements.input.addEventListener("keydown",this.entity.eventListenerFunctions.inputKeydownEvent),null!=(t=this.elements.list)&&t.addEventListener("mousemove",function(){r.hoverSelectEnabled=!0}),this.elements.attribution.innerHTML='Powered by Stork',this.elements.closeButton.innerHTML='\n\n\n\n\n\n\n\n',this.entity.config.showProgress&&(0,a.add)(this.elements.progress,"afterend",this.elements.input),null!=(e=this.elements.closeButton)&&e.addEventListener("click",function(){r.elements.input.value="",r.elements.input.focus(),r.render(o);var e=[r.entity.config.onInputCleared,r.entity.config.onResultsHidden],t=e[0],e=e[1];t&&t(),e&&e()})}r.prototype.clearDom=function(){var e;(0,a.clear)(this.elements.output),(0,a.clear)(this.elements.list),null!=(e=this.elements.closeButton)&&e.remove(),this.elements.output.classList.remove("stork-output-visible")},r.prototype.render=function(r){var e,o=this,t=this.elements.input.value;if(this.clearDom(),(this.lastRenderState=r).showProgress&&((e=function(){switch(r.state){case"ready":case"error":return 1;case"initialized":case"loading":return.9*r.progress+.05}}())<1?(this.elements.progress.style.width="".concat(100*e,"%"),this.elements.progress.style.opacity="1"):(this.elements.progress.style.width="100%",this.elements.progress.style.opacity="0")),"error"===r.state&&this.elements.input.classList.add("stork-error"),0{Object.defineProperty(t,"__esModule",{value:!0}),t.loadIndexFromUrl=void 0,t.loadIndexFromUrl=function(e,r){var t=new XMLHttpRequest;t.addEventListener("load",function(e){var t=e.target,n=t.status,t=t.response;0!==n?n<200||299{Object.defineProperty(t,"__esModule",{value:!0}),t.highlight=void 0,t.highlight=function(e,t){function n(e,t,n){return e.substr(0,t)+n+e.substr(t)}for(var r=0,o=0,s=t;o',l="";e=n(e,i.beginning+r,a),r+=30,e=n(e,i.end+r,l),r+=7}return e}},9:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.resultToListItem=void 0;var r=n(112);t.resultToListItem=function(e,t){var n=document.createElement("template");return n.innerHTML='\n
  • \n \n
    \n

    ').concat((0,r.highlight)(e.entry.title,e.title_highlight_ranges||[]),"

    \n ").concat(t.showScores?"".concat(e.score,""):"","\n
    \n ").concat(0':"","\n ").concat(e.excerpts.map(function(e){return'

    \n ...'.concat((0,r.highlight)(e.text,e.highlight_ranges||[]),"...\n

    \n ").concat(t.showScores?"".concat(e.score,""):"","\n
    ")}).join(""),"\n ").concat(0":"","\n
    \n
  • "),n.content.firstElementChild}},139:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.resolveSearch=void 0;var o=n(214),s=n(445);t.resolveSearch=function(e,t){var n=null,r=null;try{n=(0,o.wasm_search)(e,t),r=JSON.parse(n)}catch(e){throw new s.default("Could not parse data from wasm_search. If you see this, please file a bug: https://jil.im/storkbug "+n)}if(!r)throw new s.default("Data was an empty object");if(r.error)throw new s.default("Could not perform search: the WASM binary failed to return search results.\n You might not be serving your search index properly.\n If you think this is an error, please file a bug: https://jil.im/storkbug\n \n The WASM binary came back with:\n ".concat(r.error));return r}},445:function(e,t){var r,n,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]}instanceof Array?function(e,t){e.__proto__=t}:function(e,t){for(var n in t)!{}.hasOwnProperty.call(t,n)||(e[n]=t[n])}))(e,t)},function(e,t){function n(){this.constructor=e}if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+t+" is not a constructor or null");r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=(Object.defineProperty(t,"__esModule",{value:!0}),o(s,n=Error),s);function s(e){e=n.call(this,e)||this;return e.name="StorkError",e}t.default=o},466:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.plural=t.difference=t.htmlToElement=void 0,t.htmlToElement=function(e){var t=document.createElement("template");return e=e.trim(),t.innerHTML=e,t.content.firstChild},t.difference=function(e,t){var n=new Set(t),t=new Set(Array.from(new Set(e)).filter(function(e){return!n.has(e)}));return Array.from(t)},t.plural=function(e,t,n){return 1==e?t:n}},34:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.validateIndexParams=void 0;var r=n(445);t.validateIndexParams=function(e,t){return"string"!=typeof e?new r.default("Index registration name must be a string."):"string"!=typeof t?new r.default("URL must be a string."):null}},258:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.debug=t.loadWasm=t.runAfterWasmLoaded=void 0;var r=n(214),o=n(445),s=null,i=null,a=[],l=[],u=(t.loadWasm=function(e){var t;return i||(t=(e=void 0===e?null:e)||"https://files.stork-search.net/releases/v1.5.0/stork.wasm",s=t,e=(0,r.default)(t).then(function(){return u(),t}).catch(function(){throw c(),new o.default("Error while loading WASM at ".concat(t))}),i=e)},t.runAfterWasmLoaded=function(e,t){return i?(i.then(function(){return e()}).catch(function(){return t()}),i):(a.push(e),l.push(t),null)},function(){a.forEach(function(e){e()}),a=[]}),c=function(){l.forEach(function(e){e()}),l=[]};t.debug=function(){return{wasmSourceUrl:s,wasmLoadPromise:i,queueLength:a.length}}}},o={};r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("","return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,t)=>({}).hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.g.importScripts&&(e=r.g.location+"");var e,t=r.g.document;if(e||!t||(e=t.currentScript?t.currentScript.src:e)||(t=t.getElementsByTagName("script")).length&&(e=t[t.length-1].src),!e)throw Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r.p=e;t=r(480);stork=t})();var stork,loaded=!1;window.onload=function(){document.body.contains(document.goSearch)&&(document.goSearch.onsubmit=function(){return goSearchNow()}),document.getElementById("searchinput").onfocus=function(){loaded||(loadStork(),loaded=!0,document.body.contains(document.goSearch)&&(document.goSearch.onsubmit=function(){return goSearchNow()})),document.getElementById("searchinput").onfocus=""}}; \ No newline at end of file diff --git a/js/search_tinysearch.min.js b/js/search_tinysearch.min.js new file mode 100644 index 0000000..08cbe19 --- /dev/null +++ b/js/search_tinysearch.min.js @@ -0,0 +1 @@ +function closeSearchNow(){document.querySelector("main").innerHTML=window.main}function goSearchNow(){var e=document.querySelector("main"),t=(window.main||(window.main=e.innerHTML),document.getElementById("suggestions")),n=t.cloneNode(!0),o=(n.id="results",document.createElement("div")),a='

    '.concat(document.getElementById("searchinput").value,"

    ");return o.innerHTML=a,n.insertBefore(o,n.firstChild),e.innerHTML=n.outerHTML,t.innerHTML="",document.getElementById("searchinput").value="",document.body.contains(document.closeSearch)&&(document.closeSearch.onsubmit=function(){closeSearchNow()}),!1}async function lazyLoad(){var e=document.querySelector("meta[name='base']").getAttribute("content");await init((e="/"==e.slice(-1)?e.slice(0,-1):e)+"/tinysearch_engine_bg.wasm")}function closeAllLists(e){for(var t=document.getElementById("suggestions");t.firstChild;)t.removeChild(t.firstChild)}function markTerm(e,t){return e.replace(RegExp("(^|)("+t+")(|$)","ig"),"$1$2$3")}function autocomplete(e){e.addEventListener("input",function(e){var t=this.value;if(closeAllLists(),!t)return!1;for(var n=document.getElementById("suggestions"),o=search(t,99),a=0;a",c=s.querySelector("a"),r=s.querySelector("span:first-child"),i=s.querySelector("span:nth-child(2)"),c.href=u[1]+"?q="+encodeURIComponent(t),r.innerHTML=markTerm(u[0],t),i.innerHTML=markTerm(u[2],t),n.appendChild(s)}})}function suggestionFocus(t){191===t.keyCode&&"INPUT"!==document.activeElement.tagName&&"TEXTAREA"!==document.activeElement.tagName&&(t.preventDefault(),searchinput.focus(),suggestions.classList.remove("d-none")),27===t.keyCode&&(searchinput.blur(),suggestions.classList.add("d-none"),closeAllLists());var n=suggestions.querySelectorAll("a");if(!suggestions.classList.contains("d-none")&&0!==n.length){var o=[...n],a=o.indexOf(document.activeElement);let e=0;38===t.keyCode?(t.preventDefault(),n[e=0 0 ? index-1 : 0; + focusableSuggestions[nextIndex].focus(); + } + else if (e.keyCode === 40) {//down arrow + e.preventDefault(); + nextIndex= index+1 < focusable.length ? index+1 : index; + focusableSuggestions[nextIndex].focus(); + } + + } + + var suggestions = document.getElementById("suggestions"); + var searchinput = document.getElementById("searchinput"); + document.addEventListener("keydown", inputFocus); + document.addEventListener("click", function(event) {suggestions.contains(event.target) || suggestions.classList.add("d-none")}); + + var lang = document.documentElement.getAttribute("lang"); + var langOnly = lang.substring(0, 2); + var baseUrl = document.querySelector("meta[name='base']").getAttribute("content"); + if (baseUrl.slice(-1) == "/") { + baseUrl = baseUrl.slice(0, -1); + } + + var index; + searchinput.addEventListener('input', show_results, true); + suggestions.addEventListener('click', accept_suggestion, true); + + + // in page results when press enter or click search icon from search box + function closeSearchNow() { + const main = document.querySelector("main"); + main.innerHTML = window.main + } + + function goSearchNow() { + const main = document.querySelector("main"); + if (!window.main) { + window.main = main.innerHTML + }; + var results = document.getElementById("suggestions");// suggestions div generated by search box + + var ResultsClone = results.cloneNode(true);// make a clone of the results, so that we can alter it + ResultsClone.id = "results";// alter the id of our clone, so that we can apply different css style + + var headerDiv = document.createElement("div");// create a div element + + var headerContent = '

    '.concat(document.getElementById("searchinput").value, "

    ");// header to use at top of results page + + headerDiv.innerHTML = headerContent;// document element div (headerDiv), set the inner contents to our header html (headerContent) + + ResultsClone.insertBefore(headerDiv, ResultsClone.firstChild);//insert our header div at the top of the page + + main.innerHTML = ResultsClone.outerHTML;//display ResultsClone.outerHTML as the page + results.innerHTML = "";// clear the suggestions div popup + document.getElementById("searchinput").value = "";// clear the search input box + document.body.contains(document.closeSearch) && (document.closeSearch.onsubmit = function() { closeSearchNow() }) + return false + } + + /* Close search suggestion popup list */ + function closeAllLists(elmnt) { + var suggestions = document.getElementById("suggestions"); + while (suggestions.firstChild) { + suggestions.removeChild(suggestions.firstChild); + } + } + + + var index = elasticlunr.Index.load(window.searchIndex); + + async function show_results() { + var value = this.value.trim(); + var options = { + bool: "OR", + fields: { + title: {boost: 2}, + body: {boost: 1}, + } + }; + var results = index.search(value, options); + + var entry, childs = suggestions.childNodes; + var i = 0, len = results.length; + var items = value.split(/\s+/); + suggestions.classList.remove('d-none'); + + results.forEach(function(page) { + if (page.doc.body !== '') { + entry = document.createElement('div'); + + entry.innerHTML = ''; + + a = entry.querySelector('a'), + t = entry.querySelector('span:first-child'), + d = entry.querySelector('span:nth-child(2)'); + a.href = page.ref; + t.textContent = page.doc.title; + d.innerHTML = makeTeaser(page.doc.body, items); + + suggestions.appendChild(entry); + } + }); + + while(childs.length > len){ + suggestions.removeChild(childs[i]) + } + + } + + function accept_suggestion(){ + + while(suggestions.lastChild){ + + suggestions.removeChild(suggestions.lastChild); + } + + return false; + } + // Get the string bytes from binary + function getByteByBinary(binaryCode) { + // Binary system, starts with `0b` in ES6 + // Octal number system, starts with `0` in ES5 and starts with `0o` in ES6 + // Hexadecimal, starts with `0x` in both ES5 and ES6 + var byteLengthDatas = [0, 1, 2, 3, 4]; + var len = byteLengthDatas[Math.ceil(binaryCode.length / 8)]; + return len; + } + + // Get the string bytes from hexadecimal + function getByteByHex(hexCode) { + return getByteByBinary(parseInt(hexCode, 16).toString(2)); + } + // Get substring by bytes + // If using JavaScript inline substring method, it will return error codes + // Source: https://www.52pojie.cn/thread-1059814-1-1.html + function substringByByte(str, maxLength) { + var result = ""; + var flag = false; + var len = 0; + var length = 0; + var length2 = 0; + for (var i = 0; i < str.length; i++) { + var code = str.codePointAt(i).toString(16); + if (code.length > 4) { + i++; + if ((i + 1) < str.length) { + flag = str.codePointAt(i + 1).toString(16) == "200d"; + } + } + if (flag) { + len += getByteByHex(code); + if (i == str.length - 1) { + length += len; + if (length <= maxLength) { + result += str.substr(length2, i - length2 + 1); + } else { + break + } + } + } else { + if (len != 0) { + length += len; + length += getByteByHex(code); + if (length <= maxLength) { + result += str.substr(length2, i - length2 + 1); + length2 = i + 1; + } else { + break + } + len = 0; + continue; + } + length += getByteByHex(code); + if (length <= maxLength) { + if (code.length <= 4) { + result += str[i] + } else { + result += str[i - 1] + str[i] + } + length2 = i + 1; + } else { + break + } + } + } + return result; + } + /* Taken from mdbook + // The strategy is as follows: + // First, assign a value to each word in the document: + // Words that correspond to search terms (stemmer aware): 40 + // Normal words: 2 + // First word in a sentence: 8 + // Then use a sliding window with a constant number of words and count the + // sum of the values of the words within the window. Then use the window that got the + // maximum sum. If there are multiple maximas, then get the last one. + // Enclose the terms in . + */ + function makeTeaser(body, terms) { + var TERM_WEIGHT = 40; + var NORMAL_WORD_WEIGHT = 2; + var FIRST_WORD_WEIGHT = 8; + var TEASER_MAX_WORDS = 30; + + var stemmedTerms = terms.map(function (w) { + return elasticlunr.stemmer(w.toLowerCase()); + }); + var termFound = false; + var index = 0; + var weighted = []; // contains elements of ["word", weight, index_in_document] + + // split in sentences, then words + var sentences = body.toLowerCase().split(". "); + for (var i in sentences) { + var words = sentences[i].split(/[\s\n]/); + var value = FIRST_WORD_WEIGHT; + for (var j in words) { + + var word = words[j]; + + if (word.length > 0) { + for (var k in stemmedTerms) { + if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) { + value = TERM_WEIGHT; + termFound = true; + } + } + weighted.push([word, value, index]); + value = NORMAL_WORD_WEIGHT; + } + + index += word.length; + index += 1; // ' ' or '.' if last word in sentence + } + + index += 1; // because we split at a two-char boundary '. ' + } + + if (weighted.length === 0) { + if (body.length !== undefined && body.length > TEASER_MAX_WORDS * 10) { + return body.substring(0, TEASER_MAX_WORDS * 10) + '...'; + } else { + return body; + } + } + + var windowWeights = []; + var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS); + // We add a window with all the weights first + var curSum = 0; + for (var i = 0; i < windowSize; i++) { + curSum += weighted[i][1]; + } + windowWeights.push(curSum); + + for (var i = 0; i < weighted.length - windowSize; i++) { + curSum -= weighted[i][1]; + curSum += weighted[i + windowSize][1]; + windowWeights.push(curSum); + } + + // If we didn't find the term, just pick the first window + var maxSumIndex = 0; + if (termFound) { + var maxFound = 0; + // backwards + for (var i = windowWeights.length - 1; i >= 0; i--) { + if (windowWeights[i] > maxFound) { + maxFound = windowWeights[i]; + maxSumIndex = i; + } + } + } + + var teaser = []; + var startIndex = weighted[maxSumIndex][2]; + for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) { + var word = weighted[i]; + if (startIndex < word[2]) { + // missing text from index to start of `word` + teaser.push(body.substring(startIndex, word[2])); + startIndex = word[2]; + } + + // add around search terms + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + + startIndex = word[2] + word[0].length; + // Check the string is ascii characters or not + var re = /^[\x00-\xff]+$/ + if (word[1] !== TERM_WEIGHT && word[0].length >= 12 && !re.test(word[0])) { + // If the string's length is too long, it maybe a Chinese/Japance/Korean article + // if using substring method directly, it may occur error codes on emoji chars + var strBefor = body.substring(word[2], startIndex); + var strAfter = substringByByte(strBefor, 12); + teaser.push(strAfter); + } else { + teaser.push(body.substring(word[2], startIndex)); + } + + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + } + teaser.push("…"); + return teaser.join(""); + } + document.goSearch.onsubmit = function() { return goSearchNow() }; + }()); + } +}; diff --git a/js/searchjavaugly.js b/js/searchjavaugly.js new file mode 100644 index 0000000..9ff71d8 --- /dev/null +++ b/js/searchjavaugly.js @@ -0,0 +1,354 @@ +window.onload = function() { + if (document.body.contains(document.goSearch)) { + document.goSearch.onsubmit = function() { return goSearchNow() }; + + /* + Source: + - https://github.com/nextapps-de/flexsearch#index-documents-field-search + - https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html + - http://elasticlunr.com/ + - https://github.com/getzola/zola/blob/master/docs/static/search.js + - https://github.com/aaranxu/adidoks/blob/main/static/js/search.js + */ + (function(){ + function inputFocus(e) { + + if (e.keyCode === 191//forward slash + && document.activeElement.tagName !== "INPUT" + && document.activeElement.tagName !== "TEXTAREA") { + e.preventDefault(); + searchinput.focus(); + suggestions.classList.remove('d-none'); + } + + if (e.keyCode === 27 ) {//escape + searchinput.blur(); + suggestions.classList.add('d-none'); + closeAllLists(); + } + + const focusableSuggestions= suggestions.querySelectorAll('a'); + if (suggestions.classList.contains('d-none') + || focusableSuggestions.length === 0) { + return; + } + const focusable= [...focusableSuggestions]; + const index = focusable.indexOf(document.activeElement); + + let nextIndex = 0; + + if (e.keyCode === 38) {//up arrow + e.preventDefault(); + nextIndex= index > 0 ? index-1 : 0; + focusableSuggestions[nextIndex].focus(); + } + else if (e.keyCode === 40) {//down arrow + e.preventDefault(); + nextIndex= index+1 < focusable.length ? index+1 : index; + focusableSuggestions[nextIndex].focus(); + } + + } + + var suggestions = document.getElementById("suggestions"); + var searchinput = document.getElementById("searchinput"); + document.addEventListener("keydown", inputFocus); + document.addEventListener("click", function(event) {suggestions.contains(event.target) || suggestions.classList.add("d-none")}); + + var lang = document.documentElement.getAttribute("lang"); + var langOnly = lang.substring(0, 2); + var baseUrl = document.querySelector("meta[name='base']").getAttribute("content"); + if (baseUrl.slice(-1) == "/") { + baseUrl = baseUrl.slice(0, -1); + } + + var index; + searchinput.addEventListener('input', show_results, true); + suggestions.addEventListener('click', accept_suggestion, true); + + + // in page results when press enter or click search icon from search box + function closeSearchNow() { + const main = document.querySelector("main"); + main.innerHTML = window.main + } + + function goSearchNow() { + const main = document.querySelector("main"); + if (!window.main) { + window.main = main.innerHTML + }; + var results = document.getElementById("suggestions");// suggestions div generated by search box + + var ResultsClone = results.cloneNode(true);// make a clone of the results, so that we can alter it + ResultsClone.id = "results";// alter the id of our clone, so that we can apply different css style + + var headerDiv = document.createElement("div");// create a div element + + var headerContent = '

    '.concat(document.getElementById("searchinput").value, "

    ");// header to use at top of results page + + headerDiv.innerHTML = headerContent;// document element div (headerDiv), set the inner contents to our header html (headerContent) + + ResultsClone.insertBefore(headerDiv, ResultsClone.firstChild);//insert our header div at the top of the page + + main.innerHTML = ResultsClone.outerHTML;//display ResultsClone.outerHTML as the page + results.innerHTML = "";// clear the suggestions div popup + document.getElementById("searchinput").value = "";// clear the search input box + document.body.contains(document.closeSearch) && (document.closeSearch.onsubmit = function() { closeSearchNow() }) + return false + } + + /* Close search suggestion popup list */ + function closeAllLists(elmnt) { + var suggestions = document.getElementById("suggestions"); + while (suggestions.firstChild) { + suggestions.removeChild(suggestions.firstChild); + } + } + + + var index = elasticlunr.Index.load(window.searchIndex); + + async function show_results() { + var value = this.value.trim(); + var options = { + bool: "OR", + fields: { + title: {boost: 2}, + body: {boost: 1}, + } + }; + var results = index.search(value, options); + + var entry, childs = suggestions.childNodes; + var i = 0, len = results.length; + var items = value.split(/\s+/); + suggestions.classList.remove('d-none'); + + results.forEach(function(page) { + if (page.doc.body !== '') { + entry = document.createElement('div'); + + entry.innerHTML = ''; + + a = entry.querySelector('a'), + t = entry.querySelector('span:first-child'), + d = entry.querySelector('span:nth-child(2)'); + a.href = page.ref + 'index.html'; + t.textContent = page.doc.title; + d.innerHTML = makeTeaser(page.doc.body, items); + + suggestions.appendChild(entry); + } + }); + + while(childs.length > len){ + suggestions.removeChild(childs[i]) + } + + } + + function accept_suggestion(){ + + while(suggestions.lastChild){ + + suggestions.removeChild(suggestions.lastChild); + } + + return false; + } + // Get the string bytes from binary + function getByteByBinary(binaryCode) { + // Binary system, starts with `0b` in ES6 + // Octal number system, starts with `0` in ES5 and starts with `0o` in ES6 + // Hexadecimal, starts with `0x` in both ES5 and ES6 + var byteLengthDatas = [0, 1, 2, 3, 4]; + var len = byteLengthDatas[Math.ceil(binaryCode.length / 8)]; + return len; + } + + // Get the string bytes from hexadecimal + function getByteByHex(hexCode) { + return getByteByBinary(parseInt(hexCode, 16).toString(2)); + } + // Get substring by bytes + // If using JavaScript inline substring method, it will return error codes + // Source: https://www.52pojie.cn/thread-1059814-1-1.html + function substringByByte(str, maxLength) { + var result = ""; + var flag = false; + var len = 0; + var length = 0; + var length2 = 0; + for (var i = 0; i < str.length; i++) { + var code = str.codePointAt(i).toString(16); + if (code.length > 4) { + i++; + if ((i + 1) < str.length) { + flag = str.codePointAt(i + 1).toString(16) == "200d"; + } + } + if (flag) { + len += getByteByHex(code); + if (i == str.length - 1) { + length += len; + if (length <= maxLength) { + result += str.substr(length2, i - length2 + 1); + } else { + break + } + } + } else { + if (len != 0) { + length += len; + length += getByteByHex(code); + if (length <= maxLength) { + result += str.substr(length2, i - length2 + 1); + length2 = i + 1; + } else { + break + } + len = 0; + continue; + } + length += getByteByHex(code); + if (length <= maxLength) { + if (code.length <= 4) { + result += str[i] + } else { + result += str[i - 1] + str[i] + } + length2 = i + 1; + } else { + break + } + } + } + return result; + } + /* Taken from mdbook + // The strategy is as follows: + // First, assign a value to each word in the document: + // Words that correspond to search terms (stemmer aware): 40 + // Normal words: 2 + // First word in a sentence: 8 + // Then use a sliding window with a constant number of words and count the + // sum of the values of the words within the window. Then use the window that got the + // maximum sum. If there are multiple maximas, then get the last one. + // Enclose the terms in . + */ + function makeTeaser(body, terms) { + var TERM_WEIGHT = 40; + var NORMAL_WORD_WEIGHT = 2; + var FIRST_WORD_WEIGHT = 8; + var TEASER_MAX_WORDS = 30; + + var stemmedTerms = terms.map(function (w) { + return elasticlunr.stemmer(w.toLowerCase()); + }); + var termFound = false; + var index = 0; + var weighted = []; // contains elements of ["word", weight, index_in_document] + + // split in sentences, then words + var sentences = body.toLowerCase().split(". "); + for (var i in sentences) { + var words = sentences[i].split(/[\s\n]/); + var value = FIRST_WORD_WEIGHT; + for (var j in words) { + + var word = words[j]; + + if (word.length > 0) { + for (var k in stemmedTerms) { + if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) { + value = TERM_WEIGHT; + termFound = true; + } + } + weighted.push([word, value, index]); + value = NORMAL_WORD_WEIGHT; + } + + index += word.length; + index += 1; // ' ' or '.' if last word in sentence + } + + index += 1; // because we split at a two-char boundary '. ' + } + + if (weighted.length === 0) { + if (body.length !== undefined && body.length > TEASER_MAX_WORDS * 10) { + return body.substring(0, TEASER_MAX_WORDS * 10) + '...'; + } else { + return body; + } + } + + var windowWeights = []; + var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS); + // We add a window with all the weights first + var curSum = 0; + for (var i = 0; i < windowSize; i++) { + curSum += weighted[i][1]; + } + windowWeights.push(curSum); + + for (var i = 0; i < weighted.length - windowSize; i++) { + curSum -= weighted[i][1]; + curSum += weighted[i + windowSize][1]; + windowWeights.push(curSum); + } + + // If we didn't find the term, just pick the first window + var maxSumIndex = 0; + if (termFound) { + var maxFound = 0; + // backwards + for (var i = windowWeights.length - 1; i >= 0; i--) { + if (windowWeights[i] > maxFound) { + maxFound = windowWeights[i]; + maxSumIndex = i; + } + } + } + + var teaser = []; + var startIndex = weighted[maxSumIndex][2]; + for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) { + var word = weighted[i]; + if (startIndex < word[2]) { + // missing text from index to start of `word` + teaser.push(body.substring(startIndex, word[2])); + startIndex = word[2]; + } + + // add around search terms + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + + startIndex = word[2] + word[0].length; + // Check the string is ascii characters or not + var re = /^[\x00-\xff]+$/ + if (word[1] !== TERM_WEIGHT && word[0].length >= 12 && !re.test(word[0])) { + // If the string's length is too long, it maybe a Chinese/Japance/Korean article + // if using substring method directly, it may occur error codes on emoji chars + var strBefor = body.substring(word[2], startIndex); + var strAfter = substringByByte(strBefor, 12); + teaser.push(strAfter); + } else { + teaser.push(body.substring(word[2], startIndex)); + } + + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + } + teaser.push("…"); + return teaser.join(""); + } + document.goSearch.onsubmit = function() { return goSearchNow() }; + }()); + } +}; diff --git a/js/stork.js b/js/stork.js new file mode 100644 index 0000000..b464ecd --- /dev/null +++ b/js/stork.js @@ -0,0 +1,2 @@ +var stork;(()=>{"use strict";var e={214:(e,t,n)=>{let r;n.r(t),n.d(t,{default:()=>_,wasm_register_index:()=>v,wasm_search:()=>y,wasm_stork_version:()=>w});const o=new Array(32).fill(void 0);function s(e){return o[e]}o.push(void 0,null,!0,!1);let i=o.length;let a=0,l=null;function u(){return null!==l&&l.buffer===r.memory.buffer||(l=new Uint8Array(r.memory.buffer)),l}let c=new TextEncoder("utf-8");const d="function"==typeof c.encodeInto?function(e,t){return c.encodeInto(e,t)}:function(e,t){const n=c.encode(e);return t.set(n),{read:e.length,written:n.length}};function h(e,t,n){if(void 0===n){const n=c.encode(e),r=t(n.length);return u().subarray(r,r+n.length).set(n),a=n.length,r}let r=e.length,o=t(r);const s=u();let i=0;for(;i127)break;s[o+i]=t}if(i!==r){0!==i&&(e=e.slice(i)),o=n(o,r,r=i+3*e.length);const t=u().subarray(o+i,o+r);i+=d(e,t).written}return a=i,o}let f=null;function g(){return null!==f&&f.buffer===r.memory.buffer||(f=new Int32Array(r.memory.buffer)),f}let p=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});function m(e,t){return p.decode(u().subarray(e,e+t))}function v(e,t){try{const d=r.__wbindgen_add_to_stack_pointer(-16);var n=h(e,r.__wbindgen_malloc,r.__wbindgen_realloc),o=a,s=function(e,t){const n=t(1*e.length);return u().set(e,n/1),a=e.length,n}(t,r.__wbindgen_malloc),i=a;r.wasm_register_index(d,n,o,s,i);var l=g()[d/4+0],c=g()[d/4+1];return m(l,c)}finally{r.__wbindgen_add_to_stack_pointer(16),r.__wbindgen_free(l,c)}}function y(e,t){try{const c=r.__wbindgen_add_to_stack_pointer(-16);var n=h(e,r.__wbindgen_malloc,r.__wbindgen_realloc),o=a,s=h(t,r.__wbindgen_malloc,r.__wbindgen_realloc),i=a;r.wasm_search(c,n,o,s,i);var l=g()[c/4+0],u=g()[c/4+1];return m(l,u)}finally{r.__wbindgen_add_to_stack_pointer(16),r.__wbindgen_free(l,u)}}function w(){try{const n=r.__wbindgen_add_to_stack_pointer(-16);r.wasm_stork_version(n);var e=g()[n/4+0],t=g()[n/4+1];return m(e,t)}finally{r.__wbindgen_add_to_stack_pointer(16),r.__wbindgen_free(e,t)}}p.decode();const _=async function e(t){void 0===t&&(t=new URL("stork_bg.wasm",function(e){const t=n.p;let r="";return(!t||t.indexOf("://")<0)&&(r+=window.location.protocol+"//"+window.location.host),r+=t||"/",r+e}("node_modules/stork-search/stork.js")));const l={wbg:{}};l.wbg.__wbg_new_693216e109162396=function(){return function(e){i===o.length&&o.push(o.length+1);const t=i;return i=o[t],o[t]=e,t}(new Error)},l.wbg.__wbg_stack_0ddaca5d1abfb52f=function(e,t){var n=h(s(t).stack,r.__wbindgen_malloc,r.__wbindgen_realloc),o=a;g()[e/4+1]=o,g()[e/4+0]=n},l.wbg.__wbg_error_09919627ac0992f5=function(e,t){try{console.error(m(e,t))}finally{r.__wbindgen_free(e,t)}},l.wbg.__wbindgen_object_drop_ref=function(e){!function(e){const t=s(e);(function(e){e<36||(o[e]=i,i=e)})(e)}(e)},("string"==typeof t||"function"==typeof Request&&t instanceof Request||"function"==typeof URL&&t instanceof URL)&&(t=fetch(t));const{instance:u,module:c}=await async function(e,t){if("function"==typeof Response&&e instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(e,t)}catch(t){if("application/wasm"==e.headers.get("Content-Type"))throw t;console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",t)}const n=await e.arrayBuffer();return await WebAssembly.instantiate(n,t)}{const n=await WebAssembly.instantiate(e,t);return n instanceof WebAssembly.Instance?{instance:n,module:e}:n}}(await t,l);return r=u.exports,e.__wbindgen_wasm_module=c,r}},914:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.calculateOverriddenConfig=t.defaultConfig=void 0;var r=n(445),o=n(466);t.defaultConfig={showProgress:!0,printIndexInfo:!1,showScores:!1,showCloseButton:!0,minimumQueryLength:3,forceOverwrite:!1,resultNoun:{singular:"file",plural:"files"},onQueryUpdate:void 0,onResultSelected:void 0,onResultsHidden:void 0,onInputCleared:void 0,transformResultUrl:function(e){return e}},t.calculateOverriddenConfig=function(e){var n=(0,o.difference)(Object.keys(e),Object.keys(t.defaultConfig));if(n.length>0){var s=(0,o.plural)(n.length,"key","keys"),i=JSON.stringify(n);return new r.default("Invalid ".concat(s," in config object: ").concat(i))}for(var a=Object.assign({},t.defaultConfig),l=0,u=Object.keys(t.defaultConfig);l{Object.defineProperty(t,"__esModule",{value:!0}),t.existsBeyondContainerBounds=t.setText=t.clear=t.add=t.create=void 0,t.create=function(e,t){var n=document.createElement(e);return t.classNames&&n.setAttribute("class",t.classNames.join(" ")),n},t.add=function(e,t,n){n.insertAdjacentElement(t,e)},t.clear=function(e){for(;e&&e.firstChild;)e.removeChild(e.firstChild)},t.setText=function(e,t){var n=document.createTextNode(t);e&&e.firstChild?e.replaceChild(n,e.firstChild):e&&e.appendChild(n)},t.existsBeyondContainerBounds=function(e,t){var n=e.getBoundingClientRect(),r=t.getBoundingClientRect();return n.bottom>r.bottom||n.top{Object.defineProperty(t,"__esModule",{value:!0}),t.Entity=void 0;var r=n(139),o=n(771),s=n(214),i=n(445),a=function(){function e(e,t,n){var r=this;this._state="initialized",this.downloadProgress=0,this.results=[],this.totalResultCount=0,this.eventListenerFunctions={},this.highlightedResult=0,this.resultsVisible=!1,this.hoverSelectEnabled=!0,this.setDownloadProgress=function(e){r.state="loading",r.downloadProgress=e,r.config.showProgress&&r.render()},this.name=e,this.url=t,this.config=n}return Object.defineProperty(e.prototype,"state",{get:function(){return this._state},set:function(e){this._state=e,this.render()},enumerable:!1,configurable:!0}),e.prototype.getCurrentMessage=function(){if(!this.domManager)return null;var e=this.domManager.getQuery();return"error"===this.state?"Error! Check the browser console.":"ready"!=this.state?"Loading...":(null==e?void 0:e.length){Object.defineProperty(t,"__esModule",{value:!0}),t.EntityDom=void 0;var r=n(227),o=n(9),s={results:[],resultsVisible:!1,showScores:!1,message:null,showProgress:!1,progress:1,state:"ready"},i=function(){function e(e,t){var n,o,i=this;this.scrollAnchorPoint="end",this.entity=t;var a=[{selector:'input[data-stork="'.concat(e,'"]'),elementName:"input"},{selector:'div[data-stork="'.concat(e,'-output"]'),elementName:"output"}].map((function(t){var n=document.querySelector(t.selector);if(!n)throw new Error('Could not register search box "'.concat(e,'": ').concat(t.elementName," element not found. Make sure an element matches the query selector `").concat(t.selector,"`"));return n})),l=a[0],u=a[1];this.elements={input:l,output:u,list:(0,r.create)("ul",{classNames:["stork-results"]}),attribution:(0,r.create)("div",{classNames:["stork-attribution"]}),progress:(0,r.create)("div",{classNames:["stork-progress"]}),message:(0,r.create)("div",{classNames:["stork-message"]}),closeButton:(0,r.create)("button",{classNames:["stork-close-button"]})},this.elements.input.removeEventListener("input",this.entity.eventListenerFunctions.inputInputEvent),this.elements.input.removeEventListener("keydown",this.entity.eventListenerFunctions.inputKeydownEvent),this.entity.eventListenerFunctions={inputInputEvent:function(e){i.handleInputEvent(e)},inputKeydownEvent:function(e){i.handleKeyDownEvent(e)}},this.elements.input.addEventListener("input",this.entity.eventListenerFunctions.inputInputEvent),this.elements.input.addEventListener("keydown",this.entity.eventListenerFunctions.inputKeydownEvent),null===(n=this.elements.list)||void 0===n||n.addEventListener("mousemove",(function(){i.hoverSelectEnabled=!0})),this.elements.attribution.innerHTML='Powered by Stork',this.elements.closeButton.innerHTML='\n\n\n\n\n\n\n\n',this.entity.config.showProgress&&(0,r.add)(this.elements.progress,"afterend",this.elements.input),null===(o=this.elements.closeButton)||void 0===o||o.addEventListener("click",(function(){i.elements.input.value="",i.elements.input.focus(),i.render(s);var e=[i.entity.config.onInputCleared,i.entity.config.onResultsHidden],t=e[0],n=e[1];t&&t(),n&&n()}))}return e.prototype.clearDom=function(){var e;(0,r.clear)(this.elements.output),(0,r.clear)(this.elements.list),null===(e=this.elements.closeButton)||void 0===e||e.remove(),this.elements.output.classList.remove("stork-output-visible")},e.prototype.render=function(e){var t,n=this,s=this.elements.input.value;if(this.clearDom(),this.lastRenderState=e,e.showProgress){var i=function(){switch(e.state){case"ready":case"error":return 1;case"initialized":case"loading":return.9*e.progress+.05}}();i<1?(this.elements.progress.style.width="".concat(100*i,"%"),this.elements.progress.style.opacity="1"):(this.elements.progress.style.width="100%",this.elements.progress.style.opacity="0")}if("error"===e.state&&this.elements.input.classList.add("stork-error"),this.getQuery().length>0&&e.resultsVisible&&(this.elements.output.classList.add("stork-output-visible"),(0,r.add)(this.elements.message,"beforeend",this.elements.output)),e.message&&(0,r.setText)(this.elements.message,e.message),(null===(t=e.results)||void 0===t?void 0:t.length)>0&&e.resultsVisible){(0,r.add)(this.elements.list,"beforeend",this.elements.output);for(var a=function(t){var s=e.results[t],i={selected:t===l.highlightedResult,showScores:e.showScores},a=(0,o.resultToListItem)(s,i);(0,r.add)(a,"beforeend",l.elements.list),a.addEventListener("mousemove",(function(){n.hoverSelectEnabled&&t!==n.highlightedResult&&n.changeHighlightedResult({to:t,shouldScrollTo:!1})})),a.addEventListener("mouseleave",(function(){n.hoverSelectEnabled&&t===n.highlightedResult&&n.changeHighlightedResult({to:-1,shouldScrollTo:!1})})),a.addEventListener("click",(function(e){e.preventDefault(),n.selectResult()}))},l=this,u=0;u0&&this.entity.config.showCloseButton&&(0,r.add)(this.elements.closeButton,"afterend",this.elements.input)},e.prototype.selectResult=function(){if(null!=this.highlightedResult){var e=this.entity.results[this.highlightedResult];this.entity.config.onResultSelected?Promise.resolve(this.entity.config.onResultSelected(this.getQuery(),e)).finally((function(){window.location.assign(e.entry.url)})):window.location.assign(e.entry.url)}},e.prototype.changeHighlightedResult=function(e){var t,n=this.highlightedResult,o=Math.max(-1,Math.min(this.entity.results.length-1,e.to));this.highlightedResult=o,this.scrollAnchorPoint=(n||0)0){var n;this.elements.input.value="",this.render(s),(n=this.entity.config.onInputCleared)&&n()}break;default:return}},e.prototype.handleInputEvent=function(e){this.entity.performSearch(e.target.value)},e.prototype.getQuery=function(){return this.elements.input.value},e}();t.EntityDom=i},129:function(e,t,n){var r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n{Object.defineProperty(t,"__esModule",{value:!0}),t.loadIndexFromUrl=void 0,t.loadIndexFromUrl=function(e,t){var n=new XMLHttpRequest;n.addEventListener("load",(function(e){var n=e.target,r=n.status,o=n.response;0!==r?r<200||r>299?t.error():t.load(o):t.progress(e.loaded/e.total)})),n.addEventListener("error",(function(){t.error()})),n.addEventListener("progress",(function(e){t.progress(e.loaded/e.total)})),n.responseType="arraybuffer",n.open("GET",e),n.send()}},480:function(e,t,n){var r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n{Object.defineProperty(t,"__esModule",{value:!0}),t.highlight=void 0,t.highlight=function(e,t){function n(e,t,n){return e.substr(0,t)+n+e.substr(t)}for(var r=0,o=0,s=t;o',l="";e=n(e,i.beginning+r,a),r+=a.length,e=n(e,i.end+r,l),r+=l.length}return e}},9:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.resultToListItem=void 0;var r=n(112);t.resultToListItem=function(e,t){var n=document.createElement("template");return n.innerHTML='\n
  • \n \n
    \n

    ').concat((0,r.highlight)(e.entry.title,e.title_highlight_ranges||[]),"

    \n ").concat(t.showScores?"".concat(e.score,""):"","\n
    \n ").concat(e.excerpts.length>0?'
    ':"","\n ").concat(e.excerpts.map((function(e){return'

    \n ...'.concat((0,r.highlight)(e.text,e.highlight_ranges||[]),"...\n

    \n ").concat(t.showScores?"".concat(e.score,""):"","\n
    ")})).join(""),"\n ").concat(e.excerpts.length>0?"
    ":"","\n
    \n
  • "),n.content.firstElementChild}},139:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.resolveSearch=void 0;var r=n(214),o=n(445);t.resolveSearch=function(e,t){var n=null,s=null;try{n=(0,r.wasm_search)(e,t),s=JSON.parse(n)}catch(e){throw new o.default("Could not parse data from wasm_search. If you see this, please file a bug: https://jil.im/storkbug "+n)}if(!s)throw new o.default("Data was an empty object");if(s.error)throw new o.default("Could not perform search: the WASM binary failed to return search results.\n You might not be serving your search index properly.\n If you think this is an error, please file a bug: https://jil.im/storkbug\n \n The WASM binary came back with:\n ".concat(s.error));return s}},445:function(e,t){var n,r=this&&this.__extends||(n=function(e,t){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},n(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=e}n(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)});Object.defineProperty(t,"__esModule",{value:!0});var o=function(e){function t(t){var n=e.call(this,t)||this;return n.name="StorkError",n}return r(t,e),t}(Error);t.default=o},466:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.plural=t.difference=t.htmlToElement=void 0,t.htmlToElement=function(e){var t=document.createElement("template");return e=e.trim(),t.innerHTML=e,t.content.firstChild},t.difference=function(e,t){var n=new Set(e),r=new Set(t),o=new Set(Array.from(n).filter((function(e){return!r.has(e)})));return Array.from(o)},t.plural=function(e,t,n){return 1==e?t:n}},34:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.validateIndexParams=void 0;var r=n(445);t.validateIndexParams=function(e,t){return"string"!=typeof e?new r.default("Index registration name must be a string."):"string"!=typeof t?new r.default("URL must be a string."):null}},258:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.debug=t.loadWasm=t.runAfterWasmLoaded=void 0;var r=n(214),o=n(445),s="https://files.stork-search.net/releases/v".concat("1.5.0","/stork.wasm"),i=null,a=null,l=[],u=[];t.loadWasm=function(e){if(void 0===e&&(e=null),a)return a;var t=e||s;i=t;var n=(0,r.default)(t).then((function(){return c(),t})).catch((function(){throw d(),new o.default("Error while loading WASM at ".concat(t))}));return a=n,n},t.runAfterWasmLoaded=function(e,t){return a?(a.then((function(){return e()})).catch((function(){return t()})),a):(l.push(e),u.push(t),null)};var c=function(){l.forEach((function(e){e()})),l=[]},d=function(){u.forEach((function(e){e()})),u=[]};t.debug=function(){return{wasmSourceUrl:i,wasmLoadPromise:a,queueLength:l.length}}}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var s=t[r]={exports:{}};return e[r].call(s.exports,s,s.exports,n),s.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;n.g.importScripts&&(e=n.g.location+"");var t=n.g.document;if(!e&&t&&(t.currentScript&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");r.length&&(e=r[r.length-1].src)}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),n.p=e})();var r=n(480);stork=r})(); +//# sourceMappingURL=stork.js.map \ No newline at end of file diff --git a/js/stork_config.js b/js/stork_config.js new file mode 100644 index 0000000..3c589c2 --- /dev/null +++ b/js/stork_config.js @@ -0,0 +1,25 @@ +function loadStork() { + var baseUrl = document.querySelector("meta[name='base']").getAttribute("content"); + if (baseUrl.slice(-1) == "/") { + baseUrl = baseUrl.slice(0, -1); + } + stork.initialize(baseUrl + "/stork.wasm").then(() => { + console.log("Finished downloading WASM"); + }) + .catch(e => { + console.error(e); + }); // download WASM + stork.register("stork",baseUrl + "/stork.st"); +} +var loaded = false; +window.onload = function() { + document.body.contains(document.goSearch) && (document.goSearch.onsubmit = function() { return goSearchNow() }) + document.getElementById('searchinput').onfocus = function() { + if (!loaded) { + loadStork(); + loaded = true; + document.body.contains(document.goSearch) && (document.goSearch.onsubmit = function() { return goSearchNow() }) + } + document.getElementById('searchinput').onfocus = ''; + } +}; diff --git a/js/sw_load.js b/js/sw_load.js new file mode 100644 index 0000000..0759338 --- /dev/null +++ b/js/sw_load.js @@ -0,0 +1,14 @@ +if ("serviceWorker" in navigator) { + navigator.serviceWorker + .register("/sw.min.js?v=3.11.0", + { scope: "/" }) + .then(() => { + console.info("SW Loaded"); + }, err => console.error("SW error: ", err)); + + navigator.serviceWorker + .ready + .then(() => { + console.info("SW Ready"); + }); +} diff --git a/js/sw_load.min.js b/js/sw_load.min.js new file mode 100644 index 0000000..13e7454 --- /dev/null +++ b/js/sw_load.min.js @@ -0,0 +1 @@ +"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.min.js?v=3.11.0",{scope:"/"}).then(()=>{},e=>{}),navigator.serviceWorker.ready.then(()=>{})); \ No newline at end of file diff --git a/js/theme.js b/js/theme.js new file mode 100644 index 0000000..ec10638 --- /dev/null +++ b/js/theme.js @@ -0,0 +1,4 @@ +// enforce local storage setting but also fallback to user-agent preferences +if (localStorage.getItem('theme') === 'switch' || (!localStorage.getItem('theme') && !window.matchMedia("(prefers-color-scheme: dark)").matches)) { + document.documentElement.classList.add('switch'); +} diff --git a/js/theme.min.js b/js/theme.min.js new file mode 100644 index 0000000..8804552 --- /dev/null +++ b/js/theme.min.js @@ -0,0 +1 @@ +"switch"!==localStorage.getItem("theme")&&(localStorage.getItem("theme")||window.matchMedia("(prefers-color-scheme: dark)").matches)||document.documentElement.classList.add("switch"); \ No newline at end of file diff --git a/js/theme_button.js b/js/theme_button.js new file mode 100644 index 0000000..b60f85e --- /dev/null +++ b/js/theme_button.js @@ -0,0 +1,7 @@ +// switch theme mode +if (document.getElementById('mode')) { + document.getElementById('mode').addEventListener('click', () => { + document.documentElement.classList.toggle('switch'); + localStorage.setItem('theme', document.documentElement.classList.contains('switch') ? 'switch' : 'default'); + }); +} diff --git a/js/theme_light.js b/js/theme_light.js new file mode 100644 index 0000000..cea48ac --- /dev/null +++ b/js/theme_light.js @@ -0,0 +1,4 @@ +// enforce local storage setting but also fallback to user-agent preferences +if (localStorage.getItem('theme') === 'switch' || (!localStorage.getItem('theme') && !window.matchMedia("(prefers-color-scheme: light)").matches)) { + document.documentElement.classList.add('switch'); +} diff --git a/js/theme_light.min.js b/js/theme_light.min.js new file mode 100644 index 0000000..fca2f11 --- /dev/null +++ b/js/theme_light.min.js @@ -0,0 +1 @@ +"switch"!==localStorage.getItem("theme")&&(localStorage.getItem("theme")||window.matchMedia("(prefers-color-scheme: light)").matches)||document.documentElement.classList.add("switch"); \ No newline at end of file diff --git a/js/tinysearch.js b/js/tinysearch.js new file mode 100644 index 0000000..9ee0cc9 --- /dev/null +++ b/js/tinysearch.js @@ -0,0 +1,244 @@ +// in page results when press enter or click search icon from search box +function closeSearchNow() { + const main = document.querySelector("main"); + main.innerHTML = window.main +} +function goSearchNow() { + const main = document.querySelector("main"); + if (!window.main) { + window.main = main.innerHTML + }; + var results = document.getElementById("suggestions");// suggestions div generated by search box + + var ResultsClone = results.cloneNode(true);// make a clone of the results, so that we can alter it + ResultsClone.id = "results";// alter the id of our clone, so that we can apply different css style + + var headerDiv = document.createElement("div");// create a div element + + var headerContent = '

    '.concat(document.getElementById("searchinput").value, "

    ");// header to use at top of results page + + headerDiv.innerHTML = headerContent;// document element div (headerDiv), set the inner contents to our header html (headerContent) + + ResultsClone.insertBefore(headerDiv, ResultsClone.firstChild);//insert our header div at the top of the page + + main.innerHTML = ResultsClone.outerHTML;//display ResultsClone.outerHTML as the page + results.innerHTML = "";// clear the suggestions div popup + document.getElementById("searchinput").value = "";// clear the search input box + document.body.contains(document.closeSearch) && (document.closeSearch.onsubmit = function() { closeSearchNow() }) + return false +} +var loaded = false; +window.onload = function() { + document.body.contains(document.goSearch) && (document.goSearch.onsubmit = function() { return goSearchNow() }) + document.getElementById('searchinput').onfocus = function() { + if (!loaded) { + lazyLoad(); + loaded = true; + document.body.contains(document.goSearch) && (document.goSearch.onsubmit = function() { return goSearchNow() }) + } + document.getElementById('searchinput').onfocus = ''; + } +}; + +async function lazyLoad() { + var baseUrl = document.querySelector("meta[name='base']").getAttribute("content"); + if (baseUrl.slice(-1) == "/") { + baseUrl = baseUrl.slice(0, -1); + } + await init(baseUrl + "/tinysearch_engine_bg.wasm"); +} + +/* Close search suggestion popup list */ +function closeAllLists(elmnt) { + var suggestions = document.getElementById("suggestions"); + while (suggestions.firstChild) { + suggestions.removeChild(suggestions.firstChild); + } +} + +function markTerm(input, term) { + return input.replace(new RegExp('(^|)(' + term + ')(|$)','ig'), '$1$2$3'); +} + +function autocomplete(inp) { + + inp.addEventListener("input", function (e) { + var suggestions, entry, i, val = this.value; + + /*close any already open lists of autocompleted values*/ + closeAllLists(); + if (!val) { + return false; + } + + suggestions = document.getElementById("suggestions");// suggestions div, generated by search box + + let arr = search(val, 99);//limit results + + for (i = 0; i < arr.length; i++) { + let elem = arr[i]; + + entry = document.createElement("DIV"); + entry.innerHTML = ''; + var a, t, d; + a = entry.querySelector('a'), + t = entry.querySelector('span:first-child'), + d = entry.querySelector('span:nth-child(2)'); + a.href = `${elem[1]}?q=${encodeURIComponent(val)}`;//a link + t.innerHTML = markTerm(elem[0], val);//title + d.innerHTML = markTerm(elem[2], val);//description + + suggestions.appendChild(entry); + } + }) +} +var searchinput = document.getElementById("searchinput"); +function suggestionFocus(e) { + if (e.keyCode === 191//forward slash + && document.activeElement.tagName !== "INPUT" + && document.activeElement.tagName !== "TEXTAREA") { + e.preventDefault(); + searchinput.focus(); + suggestions.classList.remove('d-none'); + } + + if (e.keyCode === 27 ) {//escape + searchinput.blur(); + suggestions.classList.add('d-none'); + closeAllLists(); + } + + const focusableSuggestions= suggestions.querySelectorAll('a'); + if (suggestions.classList.contains('d-none') + || focusableSuggestions.length === 0) { + return; + } + const focusable= [...focusableSuggestions]; + const index = focusable.indexOf(document.activeElement); + + let nextIndex = 0; + + if (e.keyCode === 38) {//up arrow + e.preventDefault(); + nextIndex= index > 0 ? index-1 : 0; + focusableSuggestions[nextIndex].focus(); + } + else if (e.keyCode === 40) {//down arrow + e.preventDefault(); + nextIndex= index+1 < focusable.length ? index+1 : index; + focusableSuggestions[nextIndex].focus(); + } + +} +document.addEventListener("keydown", suggestionFocus); + +let wasm, cachedTextDecoder = (autocomplete(document.getElementById("searchinput")), new TextDecoder("utf-8", { + ignoreBOM: !0, + fatal: !0 + })), + cachegetUint8Memory0 = (cachedTextDecoder.decode(), null); + +function getUint8Memory0() { + return cachegetUint8Memory0 = null !== cachegetUint8Memory0 && cachegetUint8Memory0.buffer === wasm.memory.buffer ? cachegetUint8Memory0 : new Uint8Array(wasm.memory.buffer) +} + +function getStringFromWasm0(e, t) { + return cachedTextDecoder.decode(getUint8Memory0().subarray(e, e + t)) +} +const heap = new Array(32).fill(void 0); +heap.push(void 0, null, !0, !1); +let heap_next = heap.length; + +function addHeapObject(e) { + heap_next === heap.length && heap.push(heap.length + 1); + var t = heap_next; + return heap_next = heap[t], heap[t] = e, t +} +let WASM_VECTOR_LEN = 0, + cachedTextEncoder = new TextEncoder("utf-8"); +const encodeString = "function" == typeof cachedTextEncoder.encodeInto ? function(e, t) { + return cachedTextEncoder.encodeInto(e, t) +} : function(e, t) { + var n = cachedTextEncoder.encode(e); + return t.set(n), { + read: e.length, + written: n.length + } +}; + +function passStringToWasm0(e, t, n) { + if (void 0 === n) { + const n = cachedTextEncoder.encode(e), + a = t(n.length); + return getUint8Memory0().subarray(a, a + n.length).set(n), WASM_VECTOR_LEN = n.length, a + } + let a = e.length, + o = t(a); + const i = getUint8Memory0(); + let r = 0; + for (; r < a; r++) { + const t = e.charCodeAt(r); + if (127 < t) break; + i[o + r] = t + } + if (r !== a) { + 0 !== r && (e = e.slice(r)), o = n(o, a, a = r + 3 * e.length); + const t = getUint8Memory0().subarray(o + r, o + a); + r += encodeString(e, t).written + } + return WASM_VECTOR_LEN = r, o +} + +function getObject(e) { + return heap[e] +} + +function dropObject(e) { + e < 36 || (heap[e] = heap_next, heap_next = e) +} + +function takeObject(e) { + var t = getObject(e); + return dropObject(e), t +} + +function search(e, t) { + var e = passStringToWasm0(e, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc), + n = WASM_VECTOR_LEN; + return takeObject(wasm.search(e, n, t)) +} +async function load(e, t) { + if ("function" == typeof Response && e instanceof Response) { + if ("function" == typeof WebAssembly.instantiateStreaming) try { + return await WebAssembly.instantiateStreaming(e, t) + } catch (t) { + if ("application/wasm" == e.headers.get("Content-Type")) throw t; + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", t) + } + var n = await e.arrayBuffer(); + return WebAssembly.instantiate(n, t) + } + n = await WebAssembly.instantiate(e, t); + return n instanceof WebAssembly.Instance ? { + instance: n, + module: e + } : n +} +async function init(e) { + var baseUrl = document.querySelector("meta[name='base']").getAttribute("content"); + if (baseUrl.slice(-1) == "/") { + baseUrl = baseUrl.slice(0, -1); + } + void 0 === e && (e = new URL(baseUrl + "/tinysearch_engine_bg.wasm")); + const t = { + wbg: {} + }; + t.wbg.__wbindgen_json_parse = function(e, t) { + return addHeapObject(JSON.parse(getStringFromWasm0(e, t))) + }; + var { + instance: e, + module: n + } = await load(await (e = "string" == typeof e || "function" == typeof Request && e instanceof Request || "function" == typeof URL && e instanceof URL ? fetch(e) : e), t); + return wasm = e.exports, init.__wbindgen_wasm_module = n, wasm +} diff --git a/katex.min.css b/katex.min.css new file mode 100644 index 0000000..444a00c --- /dev/null +++ b/katex.min.css @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.15.6"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/m1024.png b/m1024.png new file mode 100644 index 0000000..f733670 Binary files /dev/null and b/m1024.png differ diff --git a/m128.png b/m128.png new file mode 100644 index 0000000..428f863 Binary files /dev/null and b/m128.png differ diff --git a/m192.png b/m192.png new file mode 100644 index 0000000..0983cd8 Binary files /dev/null and b/m192.png differ diff --git a/m384.png b/m384.png new file mode 100644 index 0000000..5909ebb Binary files /dev/null and b/m384.png differ diff --git a/m48.png b/m48.png new file mode 100644 index 0000000..e7136b4 Binary files /dev/null and b/m48.png differ diff --git a/m512.png b/m512.png new file mode 100644 index 0000000..21daff2 Binary files /dev/null and b/m512.png differ diff --git a/m72.png b/m72.png new file mode 100644 index 0000000..763db52 Binary files /dev/null and b/m72.png differ diff --git a/m96.png b/m96.png new file mode 100644 index 0000000..7089028 Binary files /dev/null and b/m96.png differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..65d9670 --- /dev/null +++ b/manifest.json @@ -0,0 +1,77 @@ +{ + "name": "Abridge Zola Theme", + "short_name": "Abridge", + "description": "Fast and Lightweight Zola Theme", + "background_color": "#111111", + "theme_color": "#333333", + "display": "standalone", + "orientation": "any", + "start_url": "/", + "scope": "/", + "categories": ["developer", "development", "productivity"], + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "/apple-touch-icon.png", + "sizes": "180x180", + "type": "image/png" + }, + { + "src": "/m48.png", + "sizes": "48x48", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/m72.png", + "sizes": "72x72", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/m96.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/m128.png", + "sizes": "128x128", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/m192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/m384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/m512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/m1024.png", + "sizes": "1024x1024", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/manifest.min.json b/manifest.min.json new file mode 100644 index 0000000..e6bf4ec --- /dev/null +++ b/manifest.min.json @@ -0,0 +1 @@ +{"name":"Abridge Zola Theme","short_name":"Abridge","description":"Fast and Lightweight Zola Theme","background_color":"#111111","theme_color":"#333333","display":"standalone","orientation":"any","start_url":"/","scope":"/","categories":["developer","development","productivity"],"icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"},{"src":"/apple-touch-icon.png","sizes":"180x180","type":"image/png"},{"src":"/m48.png","sizes":"48x48","type":"image/png","purpose":"maskable"},{"src":"/m72.png","sizes":"72x72","type":"image/png","purpose":"maskable"},{"src":"/m96.png","sizes":"96x96","type":"image/png","purpose":"maskable"},{"src":"/m128.png","sizes":"128x128","type":"image/png","purpose":"maskable"},{"src":"/m192.png","sizes":"192x192","type":"image/png","purpose":"maskable"},{"src":"/m384.png","sizes":"384x384","type":"image/png","purpose":"maskable"},{"src":"/m512.png","sizes":"512x512","type":"image/png","purpose":"maskable"},{"src":"/m1024.png","sizes":"1024x1024","type":"image/png","purpose":"maskable"}]} \ No newline at end of file diff --git a/mstile-150x150.png b/mstile-150x150.png new file mode 100644 index 0000000..f18dedf Binary files /dev/null and b/mstile-150x150.png differ diff --git a/nixos-server-1/index.html b/nixos-server-1/index.html new file mode 100644 index 0000000..2e1e78a --- /dev/null +++ b/nixos-server-1/index.html @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + NixOS as a server, part 1: Impermanence | Guekka's blog + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    NixOS as a server, part 1: Impermanence

    + + Guekka February 20, 2023 [Projects] #nix #self-hosting + + + + +

    A few months ago, I woke up with the idea of hosting my own services. I went through a lot of tries. LXC, Debian, Alpine, (rootless or not) Docker, podman, portainer…

    +

    But no solution felt perfect. Until I decided to have a try at hosting using NixOS.

    +

    I’m going to assume you know about NixOS and have some prior experience. However, for a small summary: NixOS is a Linux distribution revolving around the Nix package manager. Its main advantage is having a reproducible environment through a declarative configuration. This means that you can copy an entire computer configuration easily: if it works somewhere, it will work anywhere.

    +

    My main focus point is reproducibility, so that’s why we’ll start with configuring impermanence.

    +

    What’s impermanence?

    +

    Originally, a philosophic concept. But in our case, impermanence means erasing the / drive at each reboot. You read that right, erasing almost everything at each reboot. This part stands on the shoulders of those who did it before me:

    + +

    The goal is the following: over years, configuration files accumulate. Sometimes editing /etc is required, because of a bug or an obscure configuration. NixOS allows us to avoid this manual file editing, but it does not force us to do so. We can still have a lot of important state, breaking the reproducibility promise.

    +

    So what can we do instead? Erase everything, at each reboot. This way, we’ll be sure the only source of truth is our configuration.

    +

    Installing the system

    +

    I’m currently using a quickemu VM. This is not a recommenced setup and is only done for testing. Configuration file:

    +
    #!/usr/bin/quickemu --vm
    +guest_os="linux"
    +disk_img="nixos-22.11-minimal/disk.qcow2"
    +iso="nixos-22.11-minimal/latest-nixos-minimal-x86_64-linux.iso"
    +disk_size="50G"
    +ram="4G"
    +
    +

    Let’s first format it:

    +
    DISK=/dev/vda
    +
    +parted "$DISK" -- mklabel gpt
    +parted "$DISK" -- mkpart ESP fat32 1MiB 1GiB
    +parted "$DISK" -- set 1 boot on
    +mkfs.vfat "$DISK"1
    +
    +
    parted "$DISK" -- mkpart Swap linux-swap 1GiB 9GiB
    +mkswap -L Swap "$DISK"2
    +swapon "$DISK"2
    +
    +
    +

    Using swap in 2023!?

    +
    +

    Yes.

    +
    parted "$DISK" -- mkpart primary 9GiB 100%
    +mkfs.btrfs -L Butter "$DISK"3
    +
    +

    While the impermanence module recommends using tmpfs for /, I chose to use btrfs: I do not have RAM to waste. Furthermore, this will allow us to use a nice script we’ll see later on.

    +

    Let’s create btrfs subvolumes:

    +
    mount "$DISK"3 /mnt
    +btrfs subvolume create /mnt/root
    +btrfs subvolume create /mnt/home
    +btrfs subvolume create /mnt/nix
    +btrfs subvolume create /mnt/persist
    +btrfs subvolume create /mnt/log
    +
    +

    And now, the crucial part:

    +
    btrfs subvolume snapshot -r /mnt/root /mnt/root-blank
    +
    +

    We just took a snapshot of that empty volume. We will restore it at each reboot. +We can now mount the subvolumes and let nixos-generate-config do its job

    +
    mount -o subvol=root,compress=zstd,noatime "$DISK"3 /mnt
    +
    +mkdir /mnt/home
    +mount -o subvol=home,compress=zstd,noatime "$DISK"3 /mnt/home
    +
    +mkdir /mnt/nix
    +mount -o subvol=nix,compress=zstd,noatime "$DISK"3 /mnt/nix
    +
    +mkdir /mnt/persist
    +mount -o subvol=persist,compress=zstd,noatime "$DISK"3 /mnt/persist
    +
    +mkdir -p /mnt/var/log
    +mount -o subvol=log,compress=zstd,noatime "$DISK"3 /mnt/var/log
    +
    +mkdir /mnt/boot
    +mount "$DISK"1 /mnt/boot
    +
    +nixos-generate-config --root /mnt
    +
    +

    Lastly, we only have to edit the generated configuration files at /mnt/etc/nixos.

    +

    My final configuration is available here. You can follow all the steps by looking at the commits.

    +

    Configuring the system

    +
      +
    • Checking that we have the correct mount options in /mnt/etc/nixos/hardware-configuration.nix.
    • +
    +

    I’ve added "compress=zstd" "noatime" to all filesystems. We also need to add neededForBoot to /var/log and /persist.

    +
      +
    • Replacing default values in configuration.nix
    • +
    +

    I’ve enabled networkmanager, removed most suggested options and enabled system.copySystemConfiguration.

    +

    This last option copies the current configuration to /run/current_system/configuration.nix. You should not rely on it: keep your configuration in a git repository. But it can serve as some kind of last chance.

    +
      +
    • Declaring a user, including ssh
    • +
    +
    users.mutableUsers = false;
    +users.users.user = {
    + isNormalUser = true;
    + extraGroups = [ "wheel" ];
    +
    + openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICWVNch9BcjkMqS/Xwep+GN4HwqyRIjr3Cuw7mHpqsKr nixos" ];
    +
    + # passwordFile needs to be in a volume marked with `neededForBoot = true`
    + passwordFile = "/persist/passwords/user";
    +};
    +
    +

    Here we have completely disabled imperative user modification. This does not matter much, as imperative changes would be erased anyway at start. +We thus need to provide a password. We’re using passwordFile for that: a path to a file containing the hashed password.

    +

    Here’s how to generate that file: sudo mkpasswd -m sha-512 "hunter2" > /mnt/persist/passwords/user.

    +

    The SSH key was generated using `ssh-keygen -t ed25519 -C “nixos”.

    +
      +
    • Enabling openSSH +We’re going to use Xe’s configuration:
    • +
    +
      services.openssh = {
    +   enable = true;
    +   passwordAuthentication = false;
    +   allowSFTP = false; # Don't set this if you need sftp
    +   challengeResponseAuthentication = false;
    +   extraConfig = ''
    +     AllowTcpForwarding yes
    +     X11Forwarding no
    +     AllowAgentForwarding no
    +     AllowStreamLocalForwarding no
    +     AuthenticationMethods publickey
    +   '';
    +  };
    +
    +

    This reduces attack surface, for example by disabling stream-local forwarding and disabling password authentification.

    +
    +

    This will be enough for now. Let’s install the system before going to the next step: sudo nixos-install --root /mnt && sudo reboot. You should be able to connect by SSH using the previously defined key, or login using the password you defined in /persist/passwords/user.

    +

    Configuring impermanence

    +

    We’ve created our volumes, we’ve configured the system… But I promised we would reset our system at each reboot. Let’s do that now! +We’re going to use the following script, credit of mt-caret. Do not forget to replace vda3 with your data partition.

    +

    16/07/23 update: it was brought to my attention that postDeviceCommands can cause data loss. +While I did not experience any issue, I have updated the script to use a safer alternative.

    +
      boot.initrd = {
    +    enable = true;
    +    supportedFilesystems = [ "btrfs" ];
    +
    +    systemd.services.restore-root = {
    +      description = "Rollback btrfs rootfs";
    +      wantedBy = [ "initrd.target" ];
    +      requires = [
    +        "dev-vda3"
    +      ];
    +      after = [
    +        "dev-vda3"
    +        # for luks
    +        "systemd-cryptsetup@${config.networking.hostName}.service"
    +      ];
    +      before = [ "sysroot.mount" ];
    +      unitConfig.DefaultDependencies = "no";
    +      serviceConfig.Type = "oneshot";
    +      script = ''
    +        mkdir -p /mnt
    +
    +        # We first mount the btrfs root to /mnt
    +        # so we can manipulate btrfs subvolumes.
    +        mount -o subvol=/ /dev/vda3 /mnt
    +
    +        # While we're tempted to just delete /root and create
    +        # a new snapshot from /root-blank, /root is already
    +        # populated at this point with a number of subvolumes,
    +        # which makes `btrfs subvolume delete` fail.
    +        # So, we remove them first.
    +        #
    +        # /root contains subvolumes:
    +        # - /root/var/lib/portables
    +        # - /root/var/lib/machines
    +        #
    +        # I suspect these are related to systemd-nspawn, but
    +        # since I don't use it I'm not 100% sure.
    +        # Anyhow, deleting these subvolumes hasn't resulted
    +        # in any issues so far, except for fairly
    +        # benign-looking errors from systemd-tmpfiles.
    +        btrfs subvolume list -o /mnt/root |
    +        cut -f9 -d' ' |
    +        while read subvolume; do
    +          echo "deleting /$subvolume subvolume..."
    +          btrfs subvolume delete "/mnt/$subvolume"
    +        done &&
    +        echo "deleting /root subvolume..." &&
    +        btrfs subvolume delete /mnt/root
    +
    +        echo "restoring blank /root subvolume..."
    +        btrfs subvolume snapshot /mnt/root-blank /mnt/root
    +
    +        # Once we're done rolling back to a blank snapshot,
    +        # we can unmount /mnt and continue on the boot process.
    +        umount /mnt
    +      '';
    +    };
    +  };
    +
    +

    We can then specify the files we want to keep.

    +

    But which files do we want to keep? Let’s find out. Thanks to another useful script of mt-caret, we can list the differences between our current / and the blank state:

    +
    #!/usr/bin/env bash
    +# fs-diff.sh
    +set -euo pipefail
    +
    +OLD_TRANSID=$(sudo btrfs subvolume find-new /mnt/root-blank 9999999)
    +OLD_TRANSID=${OLD_TRANSID#transid marker was }
    +
    +sudo btrfs subvolume find-new "/mnt/root" "$OLD_TRANSID" |
    +sed '$d' |
    +cut -f17- -d' ' |
    +sort |
    +uniq |
    +while read path; do
    +  path="/$path"
    +  if [ -L "$path" ]; then
    +    : # The path is a symbolic link, so is probably handled by NixOS already
    +  elif [ -d "$path" ]; then
    +    : # The path is a directory, ignore
    +  else
    +    echo "$path"
    +  fi
    +done
    +
    +

    Used like this:

    +
    sudo mkdir /mnt ; sudo mount -o subvol=/ /dev/vda3 /mnt ; ./fs-diff.sh
    +
    +

    Here’s the result of mine:

    +
    /etc/.clean
    +/etc/group
    +/etc/machine-id
    +/etc/nixos/configuration.nix
    +/etc/nixos/hardware-configuration.nix
    +/etc/passwd
    +/etc/resolv.conf
    +/etc/shadow
    +/etc/ssh/authorized_keys.d/user
    +/etc/ssh/ssh_host_ed25519_key
    +/etc/ssh/ssh_host_ed25519_key.pub
    +/etc/ssh/ssh_host_rsa_key
    +/etc/ssh/ssh_host_rsa_key.pub
    +/etc/subgid
    +/etc/subuid
    +/etc/sudoers
    +/etc/.updated
    +/root/.nix-channels
    +/root/.nix-defexpr/channels
    +/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s8.lease
    +/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease
    +/var/lib/NetworkManager/NetworkManager-intern.conf
    +/var/lib/NetworkManager/secret_key
    +/var/lib/NetworkManager/timestamps
    +/var/lib/nixos/auto-subuid-map
    +/var/lib/nixos/declarative-groups
    +/var/lib/nixos/declarative-users
    +/var/lib/nixos/gid-map
    +/var/lib/nixos/uid-map
    +/var/lib/systemd/catalog/database
    +/var/lib/systemd/random-seed
    +/var/.updated
    +
    +

    That’s not too bad!

    +

    Out of these, there’s almost nothing I want to preserve.

    +

    Let’s make use of the impermanence module. We need to download it:

    +
    let
    +  impermanence = builtins.fetchTarball "https://github.com/nix-community/impermanence/archive/master.tar.gz";
    +in
    +{
    +imports = [ "${impermanence}/nixos.nix" ./hardware-configuration.nix ]
    +// the whole configuration
    +}
    +
    +

    And now, we can just tell it the files and directories that we want:

    +
      # configure impermanence
    +  environment.persistence."/persist" = {
    +    directories = [
    +      "/etc/nixos"
    +    ];
    +    files = [
    +      "/etc/machine-id"
    +      "/etc/ssh/ssh_host_ed25519_key"
    +      "/etc/ssh/ssh_host_ed25519_key.pub"
    +      "/etc/ssh/ssh_host_rsa_key"
    +      "/etc/ssh/ssh_host_rsa_key.pub"
    +  };
    +
    +  security.sudo.extraConfig = ''
    +    # rollback results in sudo lectures after each reboot
    +    Defaults lecture = never
    +  '';
    +
    +

    What an ergonomic interface.

    +
    +

    Wait, did you just say Nix was ergonomic?

    +
    +

    Well, yes. Sometimes.

    +
    +

    I have not saved my network manager configuration, but you may need to.

    +

    When new files are set to be preserved, it is necessary to copy them manually to /persist:

    +
    sudo nixos-rebuild boot
    +
    +sudo mkdir /persist/etc
    +
    +sudo cp -r {,/persist}/etc/nixos
    +sudo cp {,/persist}/etc/machine-id
    +
    +sudo mkdir /persist/etc/ssh
    +
    +sudo cp {,/persist}/etc/ssh/ssh_host_ed25519_key
    +sudo cp {,/persist}/etc/ssh/ssh_host_ed25519_key.pub
    +sudo cp {,/persist}/etc/ssh/ssh_host_rsa_key
    +sudo cp {,/persist}/etc/ssh/ssh_host_rsa_key.pub
    +
    +

    Now, if we reboot and list files again:

    +
    /etc/.clean
    +/etc/group
    +/etc/passwd
    +/etc/resolv.conf
    +/etc/shadow
    +/etc/ssh/authorized_keys.d/user
    +/etc/subgid
    +/etc/subuid
    +/etc/sudoers
    +/etc/.updated
    +/root/.nix-channels
    +/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease
    +/var/lib/NetworkManager/NetworkManager-intern.conf
    +/var/lib/NetworkManager/secret_key
    +/var/lib/NetworkManager/timestamps
    +/var/lib/nixos/auto-subuid-map
    +/var/lib/nixos/declarative-groups
    +/var/lib/nixos/declarative-users
    +/var/lib/nixos/gid-map
    +/var/lib/nixos/uid-map
    +/var/lib/systemd/catalog/database
    +/var/lib/systemd/random-seed
    +/var/.updated
    +
    +

    Success! The files we persisted are no longer showing up.

    +

    What about our home directory?

    +

    It is possible to setup the impermanence module for our home directory. However, I did not want to go through home-manager installation. Furthermore, a home directory is meant to be stateful.

    +

    In our case, we are creating a server, so it would still make sense to configure it. If you are interested, have a look at tmpfs at home.

    +

    Next steps

    +

    In the next part, we will make our server more secure by making it only available through Tailscale. We will also setup our first service.

    +
    +

    I hope you’ve enjoyed this article! Thanks for reading to the end!

    + + + + + + + + + + +
    +
    + + + + + diff --git a/nixos-server-2/index.html b/nixos-server-2/index.html new file mode 100644 index 0000000..0ddfa44 --- /dev/null +++ b/nixos-server-2/index.html @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + NixOS as a server, part 2: Flake, tailscale | Guekka's blog + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    NixOS as a server, part 2: Flake, tailscale

    + + Guekka May 17, 2023 [Projects] #nix #self-hosting + + + + +

    In the previous part, we configured our NixOS server to use impermanence. I have made a few changes since, most notably moving to a proper VM in Proxmox.

    +

    The following instructions might lack some details, but you can follow the GitHub repo to see the full code.

    +

    Moving to flakes

    +
    +

    If you already know about flakes, you can safely ignore this part.

    +
    +

    Have you heard about Nix flakes? If you have been in the Nix ecosystem for more than a few days, most likely. They’re the shiny new way to write Nix code, still experimental but used everywhere. +Their main advantage over traditional Nix is purity, mainly with their defined inputs and outputs.

    +

    Remember when I told you Nix was reproducible? It was a lie. Let me explain myself: when writing Nix code, we always have some kind of input. For example, nixpkgs will be required almost all the time. There are two ways to obtain it.

    +
      +
    • fetch it: import builtins.fetchTarball "https://github.com/nixos/nixpkgs/archive/nixos-22.11.tar.gz";
    • +
    • or more commonly, use channels: import <nixpkgs> {}
    • +
    +

    This second way uses a globally-defined configuration, which can change externally to our Nix files. We thus lose complete reproducibility. Instead, flakes allow us to avoid channels by specifying inputs alongside Nix configuration, as well as blocking some actions that could hinder reproducibility.

    +

    For a more in depth introduction, have a look at the wiki.

    +

    Now, why do we want to migrate to flakes? We do not have external requirements, do we? +Well, yes, we do. Apart from the obvious nixpkgs dependency, which is configured system-wide, the impermanence module is being imported:

    +
      impermanence = builtins.fetchTarball "https://github.com/Nix-community/impermanence/archive/master.tar.gz";
    +
    +

    This fetchTarball call is bad, by the way, as we do not specify the expected hash. We could be a victim of a man-in-the-middle attack and not notice it.

    +

    Now that I intend to add more modules, and possibly use the unstable channel, it is better to migrate. Let’s see what our entry point would look like:

    +
    {
    +  # what is consumed (previously provided by channels and fetchTarball)
    +  inputs = {
    +    nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; # (1)
    +    impermanence.url = "github:Nix-community/impermanence";
    +  };
    +
    +  # what will be produced (i.e. the build)
    +  outputs = { nixpkgs, ... }@inputs: { # (2)
    +    nixosConfigurations = { # (3)
    +      server = nixpkgs.lib.nixosSystem { # (4)
    +        packages = nixpkgs.legacyPackages.x86_64-linux; # (5)
    +        specialArgs = inputs; # forward inputs to modules
    +        modules = [
    +          ./configuration.Nix
    +        ];
    +      };
    +    };
    +  };
    +}
    +
    +

    That’s a lot to understand at once. Let’s study it one line at a time. +Firstly, we have to understand this file is simply describing outputs as a function taking inputs. Like in mathematics, we create the same output given the same input: a pure function, would say functional programmers.

    +

    (1) is defining an input: we simply give it an url. That line can be translated as *Grab the nixos-22.11 branch from the GitHub repo nixpkgs owned by NixOS.

    +

    (2) is defining the outputs function. Most complicated things are defined using functions in Nix. It takes a named attribute set argument as an input. So this syntax:

    +
    { nixpkgs, ... }@inputs: nixpkgs
    +
    +

    is the same as:

    +
    inputs: inputs.nixpkgs
    +
    +

    In both cases, we’re accessing the nixpkgs property of the inputs set.

    +

    But in the first case, we don’t have to repeat inputs. everywhere. In JS, you would call that destructuring: it is just making inner elements easier to access. If you have troubles understanding the Nix syntax, I personally like FasterThanLime article.

    +

    (3): NixOS configuration have to be placed specifically in the nixosConfigurations set.

    +

    (4) is the place where we actually define the system. We call the nixosSystem function and pass it some arguments. Yes, the whole system is an output too!

    +

    (5): we give the packages instance to our system. In our case, we are passing the default packages, but we might want to modify them before. We also have to specify our architecture (x86_64).

    +

    That’s pretty much it. With that flake.Nix in /etc/nixos, nixos-rebuild will work as before. However, if you’re using git, beware that your files all need to be under version control or Nix will not see them.

    +

    Secrets with Sops

    +

    In order to set up Tailscale, we will use a pre-auth key. This allows us to connect to our server without interaction. However, we must hide this key, or other people could join our Tailscale network, which could obviously have dangerous consequences.

    +

    There are 2 well-known solutions : agenix and sops-nix. I’ve chosen sops for no particular reason. +The first step will be to add it to our flake. See, we already get a use for it!

    +

    Importing sops-nix

    +

    Let’s change our inputs:

    +
      inputs = {
    +    # ...
    +    sops-nix = {
    +      url = "github:mic92/sops-nix";
    +      inputs.nixpkgs.follows ="nixpkgs";
    +    };
    +  };
    +
    +

    Follows

    +

    What’s up with this follows? sops-nix already depends on nixpkgs, but it might use a different revision than ours. Making it use our own has several advantages:

    +
      +
    • improve consistency
    • +
    • reduce the number of evaluations required
    • +
    +

    And how do we know if a package has inputs that need to be redirected? That’s the neat thing, we don’t. Either we have to look at the upstream flake.nix, or we can call nix flake info and get a graph like so:

    +
    Resolved URL:  git+file:///etc/nixos
    +Locked URL:    git+file:///etc/nixos
    +Path:          /Nix/store/4b14z6ki7av3kid69sp5vgf50wzd3a73-source
    +Last modified: 2023-04-17 14:04:13
    +Inputs:
    +├───impermanence: github:Nix-community/impermanence/6138e
    +├───nixpkgs: github:NixOS/nixpkgs/39fa0
    +└───sops-Nix: github:mic92/sops-nix/de651
    +    ├───nixpkgs follows input 'nixpkgs'
    +    └───nixpkgs-stable: github:NixOS/nixpkgs/1040c
    +
    +

    We can notice sops-nix also has a nixpkgs-stable input, that we might as well redirect.

    +

    Generating a key

    +

    sops-nix works by encrypting our secrets with private keys. +We thus need to provide it with the keys we will use. We can generate an age key, or get one from our SSH host key. +Each secrets group can have different allowed keys, so that one user cannot access another’s secrets. +I will use the SSH host key for my server:

    +
    $ nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'
    +age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh
    +
    +

    We now have to write .sops.yaml file in order to configure which keys can access which secrets.

    +
    keys:
    +  - &horus age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh
    +creation_rules:
    +  - path_regex: hosts/horus/secrets.yaml$
    +    key_groups:
    +    - age:
    +      - *horus
    +  - path_regex: hosts/common/secrets.yaml$
    +    key_groups:
    +    - age:
    +      - *horus
    +
    +

    That’s it for decryption. However, we need to write secrets too. For that, we can get the corresponding private key:

    +
    nix-shell -p ssh-to-age --run "sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key | install -D -m 400 /dev/stdin ~/.config/sops/age/keys.txt"
    +
    +

    That install bit is here to create the directory if it doesn’t exist and set the right permissions.

    +
    +

    Isn’t this insecure? The key is not password-locked.

    +
    +

    Indeed, if someone has access to our user account, they can read that key and decrypt the secrets. However, we can probably assume our user already has access to the local secrets, so it doesn’t matter much. Our goal is to be able to put these secrets on a public GitHub, not to protect them locally.

    +

    Configuring sops-nix

    +

    Our last step is to configure sops. +We’re going to get fancy here, as I’m stealing borrowing a module from Misterio’s config. In the future, this will often happen, as his config happens to be a great resource. Let’s have a look at sops.nix:

    +
    { sops-nix, lib, config, ... }:
    +let
    +  isEd25519 = k: k.type == "ed25519";
    +  getKeyPath = k: k.path;
    +  keys = builtins.filter isEd25519 config.services.openssh.hostKeys;
    +in
    +{
    +  imports = [
    +    sops-nix.nixosModules.sops
    +  ];
    +
    +  sops = {
    +    age.sshKeyPaths = map getKeyPath keys;
    +  };
    +}
    +
    +

    This looks complicated, but it is not. First, we are declaring some functions in the let block.

    +
      +
    • isEd25519 simply tells if an SSH key uses ed25519
    • +
    • getKeyPath gets the path of an SSH key
    • +
    • keys is the list of ed25519 keys, taken from openssh
    • +
    +

    Then we import sops. Finally, we give it the keys we collected earlier. This avoids hardcoding keys, which is great!

    +

    We can now import this module in our config:

    +
      imports =
    +    [
    +      impermanence.nixosModule
    +      ./hardware-configuration.Nix
    +      ../../modules/sops.nix
    +    ];
    +
    +

    sops-nix is now ready to use. Do not forget to rebuild the config.

    +

    Our first secret

    +

    Let’s write a secret:

    +
    mkdir -p hosts/horus
    +nix-shell -p sops --run "sops hosts/horus/secrets.yaml"
    +
    +

    An editor should open. We can now write secrets, using yaml. Once we’re done, we can save the file. Example content:

    +
    tailscale_key: e2b6595884993e001da58d2995af65df489582a702e3a2f3
    +
    +

    We now have to tell sops this secret exists. So we declare it somewhere in our configuration:

    +
    sops.secrets.tailscale_key = {
    +  sopsFile = ./secrets.yaml;
    +};
    +
    +

    And that’s all! To use it, we simply have to use config.sops.secrets.tailscale_key.path where we need it. Beware that this will not give you the secret, but a path to a file containing the raw secret, for security reasons. Otherwise, the secret would be in the Nix store, and thus accessible to any user on the system.

    +

    Note: adding a new host

    +

    If you ever need to add a new host, you will need to update your secrets with sops updatekeys your_secret. This command has to be on a system with already authorized keys.

    +

    Tailscale

    +

    We can finally get to a real feature, setting up Tailscale. +For those of you who haven’t heard of it, Tailscale is a private meshed network, allowing you to connect to your machines privately and securely through Wireguard, a VPN protocol, without exposing them to the world. +This means being able to close port 22, while still being able to SSH into your computer.

    +

    Furthermore, Tailscale offers some additional features, such as a fancy file sending tool or hole punching, which allows you to connect to your computer even if it is behind a NAT. I won’t go into details here, but you can read more about it on their website.

    +

    I’ve chosen to write a full-fledged NixOS module for Tailscale, as it is a service that needs to be configured and started. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!

    +

    Boilerplate for NixOS modules

    +

    We’re going to write a module, so we need to create a directory for it:

    +
    mkdir -p modules/nixos
    +
    +

    Inside, we’ll need a default.nix file:

    +
    {
    +  tailscale-autoconnect = import ./tailscale-autoconnect.nix;
    +}
    +
    +

    By convention, this file is automatically imported when you import a directory. Then, in our flake.nix, we can import our module:

    +
    outputs = # ...
    +{
    +  nixosModules = import ./modules/nixos;
    +}
    +
    +

    As before, the nixosModules attribute has a special meaning.

    +

    Finally, we have to import the module we’re writing in our configuration:

    +
      imports =
    +    [
    +      # ...
    +      outputs.nixosModules.tailscale-autoconnect
    +    ];
    +
    +

    Writing the module

    +

    We’re going to write a module to start Tailscale and connect to it automatically. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!

    +

    First, we need to create a tailscale-autoconnect.nix file in our modules/nixos directory. We’ll start with the boilerplate:

    +
    { config, lib, pkgs, ... }:
    +{
    +  with lib; let
    +    cfg = config.services.tailscaleAutoconnect; 
    +  in {
    +    options = {
    +      services.tailscaleAutoconnect = {
    +        enable = mkEnableOption "tailscaleAutoconnect";
    +      };
    +    };
    +
    +    config = mkIf cfg.services.tailscaleAutoconnect.enable {
    +      # ...
    +    };
    +  };
    +}
    +
    +

    This is the basic structure of a module. We declare an option, and then we use it to conditionally change the configuration. So:

    +
      +
    • What we write in options is the option declaration
    • +
    • What we write in config is the consequence of the option being enabled, the configuration change
    • +
    +

    Let’s declare all the options first.

    +
      options.services.tailscaleAutoconnect = {
    +    enable = mkEnableOption "tailscaleAutoconnect";
    +    authkeyFile = mkOption {
    +      type = types.str;
    +      description = "The authkey to use for authentication with Tailscale";
    +    };
    +
    +    loginServer = mkOption {
    +      type = types.str;
    +      default = "";
    +      description = "The login server to use for authentication with Tailscale";
    +    };
    +
    +    advertiseExitNode = mkOption {
    +      type = types.bool;
    +      default = false;
    +      description = "Whether to advertise this node as an exit node";
    +    };
    +
    +    exitNode = mkOption {
    +      type = types.str;
    +      default = "";
    +      description = "The exit node to use for this node";
    +    };
    +
    +    exitNodeAllowLanAccess = mkOption {
    +      type = types.bool;
    +      default = false;
    +      description = "Whether to allow LAN access to this node";
    +    };
    +  };
    +
    +

    This looks like a lot of code, but we’re simply declaring options. We need to give them a type, and we can also give a default value and a description. +Now, the actually useful code:

    +
      config = mkIf cfg.enable {
    +    assertions = [
    +      {
    +        assertion = cfg.authkeyFile != "";
    +        message = "authkeyFile must be set";
    +      }
    +      {
    +        assertion = cfg.exitNodeAllowLanAccess -> cfg.exitNode != "";
    +        message = "exitNodeAllowLanAccess must be false if exitNode is not set";
    +      }
    +      {
    +        assertion = cfg.advertiseExitNode -> cfg.exitNode == "";d
    +        message = "advertiseExitNode must be false if exitNode is set";
    +      }
    +    ];
    +
    +    systemd.services.tailscale-autoconnect = {
    +      description = "Automatic connection to Tailscale";
    +
    +      # make sure tailscale is running before trying to connect to tailscale
    +      after = ["network-pre.target" "tailscale.service"];
    +      wants = ["network-pre.target" "tailscale.service"];
    +      wantedBy = ["multi-user.target"];
    +
    +      serviceConfig.Type = "oneshot";
    +
    +      script = with pkgs; ''
    +        # wait for tailscaled to settle
    +        sleep 2
    +
    +        # check if we are already authenticated to tailscale
    +        status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)"
    +        # if status is not null, then we are already authenticated
    +        echo "tailscale status: $status"
    +        if [ "$status" != "NeedsLogin" ]; then
    +            exit 0
    +        fi
    +
    +        # otherwise authenticate with tailscale
    +        # timeout after 10 seconds to avoid hanging the boot process
    +        ${coreutils}/bin/timeout 10 ${tailscale}/bin/tailscale up \
    +          ${lib.optionalString (cfg.loginServer != "") "--login-server=${cfg.loginServer}"} \
    +          --authkey=$(cat "${cfg.authkeyFile}")
    +
    +        # we have to proceed in two steps because some options are only available
    +        # after authentication
    +        ${coreutils}/bin/timeout 10 ${tailscale}/bin/tailscale up \
    +          ${lib.optionalString (cfg.loginServer != "") "--login-server=${cfg.loginServer}"} \
    +          ${lib.optionalString (cfg.advertiseExitNode) "--advertise-exit-node"} \
    +          ${lib.optionalString (cfg.exitNode != "") "--exit-node=${cfg.exitNode}"} \
    +          ${lib.optionalString (cfg.exitNodeAllowLanAccess) "--exit-node-allow-lan-access"}
    +      '';
    +    };
    +
    +    networking.firewall = {
    +      trustedInterfaces = [ "tailscale0" ];
    +      allowedUDPPorts = [ config.services.tailscale.port ];
    +    };
    +
    +    services.tailscale = {
    +      enable = true;
    +      useRoutingFeatures = if cfg.advertiseExitNode then "server" else "client";
    +    };
    +  };
    +
    +

    First, the assertions. They’re here to make sure that the user doesn’t make any mistake when configuring the module. For example, a user cannot both advertise an exit node and set an exit node. +Then, the service. We’re using systemd to run a script that will connect to Tailscale. The after, wants and wantedBy options make the script run after the network is up and after Tailscale daemon is started. The Type option is here to make sure that the script is run only once. The script itself is a bit long, but it’s just a bunch of bash commands. It’s pretty straightforward. First, we wait for the Tailscale daemon to settle. Then, we check if we’re already authenticated. If we are, we exit. Otherwise, we authenticate. Finally, we connect to Tailscale. We have to do it in two steps because some options are only available after authentication.

    +

    At the end, we configure the firewall to allow Tailscale traffic, and we enable the Tailscale service.

    +

    Now, an example of how to use this module:

    +
    { outputs, ...}:
    +{
    +  imports = [
    +    outputs.nixosModules.tailscale-autoconnect
    +  ];
    +
    +  services.tailscaleAutoconnect = {
    +    enable = true;
    +    authkeyFile = config.sops.secrets.tailscale_key.path;
    +    loginServer = "https://login.tailscale.com";
    +    exitNode = "some-node-id";
    +    exitNodeAllowLanAccess = true;
    +  };
    +
    +  sops.secrets.tailscale_key = {
    +    sopsFile = ./secrets.yaml;
    +  };
    +
    +  environment.persistence = {
    +    "/persist".directories = ["/var/lib/tailscale"];
    +  };
    +}
    +
    +

    The module is imported and configured. We also use the sops secret we created earlier. Finally, we persist the Tailscale state, so that we don’t have to authenticate again after a reboot. This is especially important if the authkey can expire.

    +
    +

    That’s all for this post. Thanks for reading! If you have any question, feel free to ask in the comments. The final code can be found here.

    + + + + + + + + + + + +
    +
    + + + + + diff --git a/nojs.css b/nojs.css new file mode 100644 index 0000000..7e0ba6d --- /dev/null +++ b/nojs.css @@ -0,0 +1 @@ +.js{display:none} \ No newline at end of file diff --git a/page/1/index.html b/page/1/index.html new file mode 100644 index 0000000..c24a5fa --- /dev/null +++ b/page/1/index.html @@ -0,0 +1,6 @@ + + + + +Redirect +

    Click here to be redirected.

    diff --git a/posts/index.html b/posts/index.html new file mode 100644 index 0000000..38fce8a --- /dev/null +++ b/posts/index.html @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Guekka's blog + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    +
    +
    + Recent +
    +
    + + +
    + + + diff --git a/posts/page/1/index.html b/posts/page/1/index.html new file mode 100644 index 0000000..3433426 --- /dev/null +++ b/posts/page/1/index.html @@ -0,0 +1,6 @@ + + + + +Redirect +

    Click here to be redirected.

    diff --git a/privacy/index.html b/privacy/index.html new file mode 100644 index 0000000..b8ccea4 --- /dev/null +++ b/privacy/index.html @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Privacy Policy | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    Privacy

    +
      +
    • This site does not set or use cookies.
    • +
    • This site does not store data in the browser to be shared, sent, or sold to third-parties.
    • +
    • No personal information is shared, sent, or sold to third-parties.
    • +
    +

    Effective Date: 1st Jan 2022

    + +
    +
    + + + diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..c2d7b8e --- /dev/null +++ b/robots.txt @@ -0,0 +1,5 @@ + +Sitemap: https://guekka.github.io/sitemap.xml +User-Agent: * +Allow: / +Host: https://guekka.github.io diff --git a/safari-pinned-tab.svg b/safari-pinned-tab.svg new file mode 100644 index 0000000..2640d41 --- /dev/null +++ b/safari-pinned-tab.svg @@ -0,0 +1,1321 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/search_index.en.json b/search_index.en.json new file mode 100644 index 0000000..58b103e --- /dev/null +++ b/search_index.en.json @@ -0,0 +1 @@ +{"fields":["title","description","body"],"pipeline":["trimmer","stopWordFilter","stemmer"],"ref":"id","version":"0.9.5","index":{"body":{"root":{"docs":{},"df":0,"1":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"6":{"docs":{},"df":0,"/":{"docs":{},"df":0,"0":{"docs":{},"df":0,"7":{"docs":{},"df":0,"/":{"docs":{},"df":0,"2":{"docs":{},"df":0,"3":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}},"2":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1,"0":{"docs":{},"df":0,"2":{"docs":{},"df":0,"2":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1},"3":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"2":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,".":{"docs":{},"df":0,"1":{"docs":{},"df":0,"1":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,".":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,".":{"docs":{},"df":0,"g":{"docs":{},"df":0,"z":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}}},"3":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"4":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"5":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"1":{"docs":{},"df":0,"2":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"c":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.6457513110645907}},"df":1}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"u":{"docs":{},"df":0,"m":{"docs":{},"df":0,"u":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"u":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}},"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2,"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"v":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}}}},"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"f":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}}},"g":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"l":{"docs":{},"df":0,"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"w":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}}},"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"g":{"docs":{},"df":0,"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"p":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"d":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":1}}}}},"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"y":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,";":{"docs":{},"df":0,"&":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{},"df":0,"p":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"n":{"docs":{},"df":0,"o":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"’":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"y":{"docs":{},"df":0,"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"y":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"h":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}},"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"r":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}},"g":{"docs":{},"df":0,"u":{"docs":{},"df":0,"m":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}},"s":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"t":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}},"u":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}},"t":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"b":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}}},"u":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":1,"i":{"docs":{},"df":0,"f":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"k":{"docs":{},"df":0,"e":{"docs":{},"df":0,"y":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"n":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,".":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}},"m":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}},"v":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"o":{"docs":{},"df":0,"i":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}}}},"b":{"docs":{},"df":0,"a":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2},"s":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"i":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":1,"f":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}}},"h":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"w":{"docs":{},"df":0,"e":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":2}}}}},"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}},"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"c":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"o":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"p":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}},"r":{"docs":{},"df":0,"r":{"docs":{},"df":0,"o":{"docs":{},"df":0,"w":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"g":{"docs":{},"df":0,"h":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"w":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}}}},"t":{"docs":{},"df":0,"r":{"docs":{},"df":0,"f":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}}},"u":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{},"df":0,"s":{"docs":{},"df":0,".":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"b":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}}}},"n":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"c":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":2,"a":{"docs":{},"df":0,"l":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}},"s":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}},"t":{"docs":{},"df":0,"h":{"docs":{},"df":0,"e":{"docs":{},"df":0,"d":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}}},"u":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"h":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.23606797749979}},"df":2},"n":{"docs":{},"df":0,"e":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}}}}},"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"o":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}},"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"o":{"docs":{},"df":0,"d":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":1}},"l":{"docs":{},"df":0,"l":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"m":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"u":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"y":{"docs":{},"df":0,"/":{"docs":{},"df":0,"i":{"docs":{},"df":0,"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}},"p":{"docs":{},"df":0,"l":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"i":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{},"df":0,"=":{"docs":{},"df":0,"z":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}},"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}}},"n":{"docs":{},"df":0,"c":{"docs":{},"df":0,"e":{"docs":{},"df":0,"p":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"d":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"f":{"docs":{},"df":0,"i":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.23606797749979}},"df":2,".":{"docs":{},"df":0,"s":{"docs":{},"df":0,"o":{"docs":{},"df":0,"p":{"docs":{},"df":0,"s":{"docs":{},"df":0,".":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{},"df":0,"s":{"docs":{},"df":0,".":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"s":{"docs":{},"df":0,"c":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{},"df":0,"e":{"docs":{},"df":0,"_":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{},"df":0,"y":{"docs":{},"df":0,".":{"docs":{},"df":0,"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":4.123105625617661},"https://guekka.github.io/nixos-server-2/":{"tf":4.242640687119285}},"df":2,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,".":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}}}}}}}}}}}}},"n":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}}}},"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"q":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"i":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"b":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}},"o":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"v":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"o":{"docs":{},"df":0,"k":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}},"r":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"s":{"docs":{},"df":0,"p":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":2.23606797749979}},"df":2}},"d":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"u":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}},"u":{"docs":{},"df":0,"r":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}}}}}}},"d":{"docs":{},"df":0,"a":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"n":{"docs":{},"df":0,"g":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"r":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"t":{"docs":{},"df":0,"a":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/privacy/":{"tf":1.0}},"df":2},"e":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.4142135623730951}},"df":1}},"y":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"e":{"docs":{},"df":0,"b":{"docs":{},"df":0,"i":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"c":{"docs":{},"df":0,"i":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}}},"r":{"docs":{},"df":0,"y":{"docs":{},"df":0,"p":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}},"f":{"docs":{},"df":0,"a":{"docs":{},"df":0,"u":{"docs":{},"df":0,"l":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2,".":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"s":{"docs":{},"df":0,"c":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"b":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"p":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{},"df":0,"r":{"docs":{},"df":0,"u":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}},"i":{"docs":{},"df":0,"f":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}}}}}}},"s":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}}},"t":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"b":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}},"o":{"docs":{},"df":0,"c":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"n":{"docs":{},"df":0,"’":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}}}}},"n":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2},"’":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}}},"w":{"docs":{},"df":0,"n":{"docs":{},"df":0,"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"a":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"v":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.23606797749979},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"r":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}},"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"l":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"s":{"docs":{},"df":0,"y":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"d":{"docs":{},"df":0,"2":{"docs":{},"df":0,"5":{"docs":{},"df":0,"5":{"docs":{},"df":0,"1":{"docs":{},"df":0,"9":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}}}},"g":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}},"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/about/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":2,"o":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"f":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}}},"l":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"n":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}},"c":{"docs":{},"df":0,"r":{"docs":{},"df":0,"y":{"docs":{},"df":0,"p":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"y":{"docs":{},"df":0,"p":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2},"j":{"docs":{},"df":0,"o":{"docs":{},"df":0,"y":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"g":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"v":{"docs":{},"df":0,"i":{"docs":{},"df":0,"r":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.23606797749979}},"df":1}},"g":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"o":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}}}}},"s":{"docs":{},"df":0,"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"/":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"v":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"e":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"r":{"docs":{},"df":0,"y":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}},"w":{"docs":{},"df":0,"h":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}}}},"x":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}}}},"i":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}},"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1,"m":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"i":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"o":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}},"f":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"e":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"l":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"t":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"b":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}},"w":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}},"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":3.4641016151377544},"https://guekka.github.io/nixos-server-2/":{"tf":3.1622776601683795}},"df":2,"s":{"docs":{},"df":0,"y":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}},"n":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}},"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.8284271247461903}},"df":2,"l":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.8284271247461903}},"df":1,".":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}}}}}}},"e":{"docs":{},"df":0,"d":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"o":{"docs":{},"df":0,"c":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"l":{"docs":{},"df":0,"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"w":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}}}},"r":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"g":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"u":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"u":{"docs":{},"df":0,"l":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}},"n":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.6457513110645907}},"df":1}}}}}},"r":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"m":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}}}}},"t":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"g":{"docs":{},"df":0,"_":{"docs":{},"df":0,"k":{"docs":{},"df":0,"a":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}},"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}},"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"k":{"docs":{},"df":0,"e":{"docs":{},"df":0,"y":{"docs":{},"df":0,"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}},"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"h":{"docs":{},"df":0,"u":{"docs":{},"df":0,"b":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}}}},"v":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":1,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"b":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.23606797749979},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"o":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"h":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"p":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"u":{"docs":{},"df":0,"e":{"docs":{},"df":0,"k":{"docs":{},"df":0,"k":{"docs":{},"df":0,"a":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}}},"’":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}},"h":{"docs":{},"df":0,"a":{"docs":{},"df":0,"p":{"docs":{},"df":0,"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"r":{"docs":{},"df":0,"d":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"s":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"v":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"n":{"docs":{},"df":0,"’":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"l":{"docs":{},"df":0,"p":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2,"’":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}}},"i":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1,"d":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"n":{"docs":{},"df":0,"d":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"m":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.23606797749979}},"df":1}},"p":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}}},"t":{"docs":{},"df":0,"t":{"docs":{},"df":0,"p":{"docs":{},"df":0,"s":{"docs":{},"df":0,":":{"docs":{},"df":0,"/":{"docs":{},"df":0,"/":{"docs":{},"df":0,"g":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{},"df":0,"u":{"docs":{},"df":0,"b":{"docs":{},"df":0,".":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"m":{"docs":{},"df":0,"/":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"o":{"docs":{},"df":0,"s":{"docs":{},"df":0,"/":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"p":{"docs":{},"df":0,"k":{"docs":{},"df":0,"g":{"docs":{},"df":0,"s":{"docs":{},"df":0,"/":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{},"df":0,"i":{"docs":{},"df":0,"v":{"docs":{},"df":0,"e":{"docs":{},"df":0,"/":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"2":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"i":{"docs":{},"df":0,"a":{"docs":{},"df":0,"s":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"d":{"docs":{},"df":0,"e":{"docs":{},"df":0,"a":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"g":{"docs":{},"df":0,"n":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"m":{"docs":{},"df":0,"m":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.8284271247461903},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}}}},"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":3.4641016151377544}},"df":3}}},"r":{"docs":{},"df":0,"o":{"docs":{},"df":0,"v":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"n":{"docs":{},"df":0,"c":{"docs":{},"df":0,"l":{"docs":{},"df":0,"u":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"d":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"f":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"r":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"r":{"docs":{},"df":0,"u":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}},"n":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":3.4641016151377544}},"df":1}}},"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"i":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2},"n":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"r":{"docs":{},"df":0,"u":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"f":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"r":{"docs":{},"df":0,"o":{"docs":{},"df":0,"d":{"docs":{},"df":0,"u":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"d":{"docs":{},"df":0,"2":{"docs":{},"df":0,"5":{"docs":{},"df":0,"5":{"docs":{},"df":0,"1":{"docs":{},"df":0,"9":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"n":{"docs":{},"df":0,"’":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"s":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"t":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"l":{"docs":{},"df":0,"f":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"’":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":1}},"’":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":3},"v":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}},"j":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}},"o":{"docs":{},"df":0,"b":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"k":{"docs":{},"df":0,"e":{"docs":{},"df":0,"e":{"docs":{},"df":0,"p":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}},"y":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":4.47213595499958}},"df":2,"g":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"i":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"n":{"docs":{},"df":0,"o":{"docs":{},"df":0,"w":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2,"n":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}},"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"l":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"e":{"docs":{},"df":0,"g":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}}}}},"t":{"docs":{},"df":0,"’":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.449489742783178},"https://guekka.github.io/nixos-server-2/":{"tf":2.8284271247461903}},"df":2}}},"i":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"n":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1},"u":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"o":{"docs":{},"df":0,"c":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}},"k":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"g":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"n":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"o":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}},"s":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"t":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":3}},"t":{"docs":{},"df":0,";":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"p":{"docs":{},"df":0,"k":{"docs":{},"df":0,"g":{"docs":{},"df":0,"s":{"docs":{},"df":0,"&":{"docs":{},"df":0,"g":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}}},"x":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"d":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":3,"l":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"k":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}},"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"a":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}},"u":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}}},"t":{"docs":{},"df":0,"h":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"s":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"i":{"docs":{},"df":0,"d":{"docs":{},"df":0,"d":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"g":{"docs":{},"df":0,"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"n":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"’":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"k":{"docs":{},"df":0,"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{},"df":0,"w":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"/":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{},"df":0,"c":{"docs":{},"df":0,"/":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"s":{"docs":{},"df":0,"/":{"docs":{},"df":0,"h":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{},"df":0,"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"/":{"docs":{},"df":0,"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{},"df":0,"w":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{},"df":0,"s":{"docs":{},"df":0,"/":{"docs":{},"df":0,"u":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}}}}}}}}},"o":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1,"i":{"docs":{},"df":0,"f":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"u":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":4.123105625617661}},"df":2,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"/":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}},"n":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.23606797749979}},"df":3}},"u":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}},"v":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1},"u":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"y":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"l":{"docs":{},"df":0,"f":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"n":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"c":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"e":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":3.4641016151377544}},"df":2,"e":{"docs":{},"df":0,"d":{"docs":{},"df":0,"f":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"b":{"docs":{},"df":0,"o":{"docs":{},"df":0,"o":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}},"t":{"docs":{},"df":0,"w":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"a":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}},"w":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2},"x":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}}},"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"x":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":4.47213595499958}},"df":2,"(":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}},"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":3.4641016151377544},"https://guekka.github.io/nixos-server-2/":{"tf":2.8284271247461903}},"df":2,"s":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"f":{"docs":{},"df":0,"i":{"docs":{},"df":0,"g":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"m":{"docs":{},"df":0,"o":{"docs":{},"df":0,"d":{"docs":{},"df":0,"u":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"s":{"docs":{},"df":0,"y":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"p":{"docs":{},"df":0,"k":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":1}}}}},"o":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"d":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"i":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"w":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.449489742783178},"https://guekka.github.io/nixos-server-2/":{"tf":3.0}},"df":2}},"u":{"docs":{},"df":0,"m":{"docs":{},"df":0,"b":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"o":{"docs":{},"df":0,"b":{"docs":{},"df":0,"s":{"docs":{},"df":0,"c":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"v":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"f":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"s":{"docs":{},"df":0,"s":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"i":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1},"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":3.0}},"df":2}}}}},"r":{"docs":{},"df":0,"d":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"i":{"docs":{},"df":0,"g":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{},"df":0,"h":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"w":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}}},"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1,"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.23606797749979}},"df":1}}}}},"v":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"w":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"k":{"docs":{},"df":0,"a":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}}}},"g":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"o":{"docs":{},"df":0,"i":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.4142135623730951}},"df":1,"c":{"docs":{},"df":0,"u":{"docs":{},"df":0,"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"s":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1,"w":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"f":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}},"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}},"e":{"docs":{},"df":0,"o":{"docs":{},"df":0,"p":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"r":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"m":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"/":{"docs":{},"df":0,"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{},"df":0,"w":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{},"df":0,"s":{"docs":{},"df":0,"/":{"docs":{},"df":0,"u":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}},"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0},"https://guekka.github.io/privacy/":{"tf":1.0}},"df":2}}}}},"h":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"s":{"docs":{},"df":0,"o":{"docs":{},"df":0,"p":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}},"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"o":{"docs":{},"df":0,"d":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"i":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.7320508075688772}},"df":1}}}},"r":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"s":{"docs":{},"df":0,"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0},"https://guekka.github.io/posts/":{"tf":1.0}},"df":2,"d":{"docs":{},"df":0,"e":{"docs":{},"df":0,"v":{"docs":{},"df":0,"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"m":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}},"r":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"v":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}}},"t":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"v":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}},"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"v":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.7320508075688772}},"df":1}},"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":1}}}},"o":{"docs":{},"df":0,"b":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"c":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}},"g":{"docs":{},"df":0,"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"m":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"t":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"v":{"docs":{},"df":0,"i":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"x":{"docs":{},"df":0,"m":{"docs":{},"df":0,"o":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"u":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"n":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"o":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0},"https://guekka.github.io/privacy/":{"tf":1.0}},"df":2}}},"q":{"docs":{},"df":0,"u":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"w":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"s":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"b":{"docs":{},"df":0,"o":{"docs":{},"df":0,"o":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.6457513110645907},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"u":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}},"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"m":{"docs":{},"df":0,"m":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"d":{"docs":{},"df":0,"i":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}},"u":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"l":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"m":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{},"df":0,"b":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"v":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}},"o":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1,"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"r":{"docs":{},"df":0,"o":{"docs":{},"df":0,"d":{"docs":{},"df":0,"u":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}}}}}},"q":{"docs":{},"df":0,"u":{"docs":{},"df":0,"i":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}}}},"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"u":{"docs":{},"df":0,"l":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"u":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}},"v":{"docs":{},"df":0,"i":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"v":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"i":{"docs":{},"df":0,"g":{"docs":{},"df":0,"h":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}},"o":{"docs":{},"df":0,"o":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1,"l":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"u":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1,"/":{"docs":{},"df":0,"c":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{},"df":0,"_":{"docs":{},"df":0,"s":{"docs":{},"df":0,"y":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{},"df":0,"/":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"f":{"docs":{},"df":0,"i":{"docs":{},"df":0,"g":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,".":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}},"s":{"docs":{},"df":0,"a":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"m":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}},"v":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"c":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"p":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}}}}},"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":4.242640687119285}},"df":1}}},"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}},"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2},"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"t":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.4142135623730951}},"df":1}},"r":{"docs":{},"df":0,"v":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}},"i":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.6457513110645907},"https://guekka.github.io/privacy/":{"tf":1.0}},"df":3,"t":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"u":{"docs":{},"df":0,"p":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0}},"df":1}}},"v":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"h":{"docs":{},"df":0,"a":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"r":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.4142135623730951}},"df":1}}},"i":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"l":{"docs":{},"df":0,"d":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"w":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"i":{"docs":{},"df":0,"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":2.23606797749979}},"df":1}}}},"t":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.7320508075688772}},"df":1}}},"k":{"docs":{},"df":0,"y":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/about/":{"tf":1.4142135623730951}},"df":1}}}}},"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"n":{"docs":{},"df":0,"a":{"docs":{},"df":0,"p":{"docs":{},"df":0,"s":{"docs":{},"df":0,"h":{"docs":{},"df":0,"o":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"o":{"docs":{},"df":0,"f":{"docs":{},"df":0,"t":{"docs":{},"df":0,"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}}},"l":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.4142135623730951}},"df":1},"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"m":{"docs":{},"df":0,"e":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}},"w":{"docs":{},"df":0,"h":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}}},"p":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":3.7416573867739413}},"df":1,"s":{"docs":{},"df":0,".":{"docs":{},"df":0,"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"y":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"u":{"docs":{},"df":0,"r":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":2}}}},"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"f":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}}}}}},"s":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.23606797749979}},"df":2}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}},"t":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"p":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}},"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}}},"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0},"https://guekka.github.io/privacy/":{"tf":1.0}},"df":2}}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"g":{"docs":{},"df":0,"h":{"docs":{},"df":0,"t":{"docs":{},"df":0,"f":{"docs":{},"df":0,"o":{"docs":{},"df":0,"r":{"docs":{},"df":0,"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}}},"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"u":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"u":{"docs":{},"df":0,"d":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"u":{"docs":{},"df":0,"b":{"docs":{},"df":0,"v":{"docs":{},"df":0,"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"u":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}}}}},"c":{"docs":{},"df":0,"c":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"s":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"d":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}},"g":{"docs":{},"df":0,"g":{"docs":{},"df":0,"e":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"m":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"r":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2},"f":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}},"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"p":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"y":{"docs":{},"df":0,"n":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"x":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.449489742783178},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2,".":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"p":{"docs":{},"df":0,"y":{"docs":{},"df":0,"s":{"docs":{},"df":0,"y":{"docs":{},"df":0,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{},"df":0,"m":{"docs":{},"df":0,"c":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{},"df":0,"f":{"docs":{},"df":0,"i":{"docs":{},"df":0,"g":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}}}}}}}}}}}}},"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"s":{"docs":{},"df":0,"c":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":4.123105625617661}},"df":2}}}}}},"k":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"h":{"docs":{},"df":0,"n":{"docs":{},"df":0,"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}}}}},"l":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"h":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"t":{"docs":{},"df":0,"’":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}}},"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"’":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"y":{"docs":{},"df":0,"’":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"i":{"docs":{},"df":0,"n":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}},"r":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.4142135623730951}},"df":1}}},"o":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"u":{"docs":{},"df":0,"s":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/about/":{"tf":1.0}},"df":1}}}}}},"r":{"docs":{},"df":0,"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"g":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}},"u":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":2}},"i":{"docs":{},"df":0,"m":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}},"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,"f":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772}},"df":1}}},"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"o":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"l":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"r":{"docs":{},"df":0,"a":{"docs":{},"df":0,"d":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"f":{"docs":{},"df":0,"f":{"docs":{},"df":0,"i":{"docs":{},"df":0,"c":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"n":{"docs":{},"df":0,"s":{"docs":{},"df":0,"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"i":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"u":{"docs":{},"df":0,"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"w":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}},"y":{"docs":{},"df":0,"p":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"u":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1,"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.7320508075688772}},"df":1}}}}}}}},"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"b":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}},"p":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2,"d":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2,"e":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{},"df":0,"y":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"s":{"docs":{},"df":0,"t":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"r":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"s":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-1/":{"tf":4.0},"https://guekka.github.io/nixos-server-2/":{"tf":4.795831523312719},"https://guekka.github.io/privacy/":{"tf":1.0}},"df":4,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":2.449489742783178}},"df":2}}}},"v":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{},"df":0,"u":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"r":{"docs":{},"df":0,"/":{"docs":{},"df":0,"l":{"docs":{},"df":0,"o":{"docs":{},"df":0,"g":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}},"d":{"docs":{},"df":0,"a":{"docs":{},"df":0,"3":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"o":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{},"df":0,"i":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2},"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"u":{"docs":{},"df":0,"m":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}}},"p":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"w":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":2.23606797749979},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2,"e":{"docs":{},"df":0,"d":{"docs":{},"df":0,"b":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"y":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}},"e":{"docs":{},"df":0,"b":{"docs":{},"df":0,"s":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"l":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":2.0}},"df":2}},"n":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"’":{"docs":{},"df":0,"l":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2}},"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.7320508075688772},"https://guekka.github.io/nixos-server-2/":{"tf":3.0}},"df":2},"v":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951}},"df":1}}},"h":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"’":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}},"i":{"docs":{},"df":0,"d":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"k":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"g":{"docs":{},"df":0,"u":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}},"t":{"docs":{},"df":0,"h":{"docs":{},"df":0,"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}}}},"o":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}},"n":{"docs":{},"df":0,"’":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"k":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2},"l":{"docs":{},"df":0,"d":{"docs":{"https://guekka.github.io/about/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}},"t":{"docs":{},"df":0,"h":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":1}}}},"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":3.872983346207417}},"df":1}}}}},"x":{"docs":{},"df":0,"8":{"docs":{},"df":0,"6":{"docs":{},"df":0,"_":{"docs":{},"df":0,"6":{"docs":{},"df":0,"4":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1,"’":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"y":{"docs":{},"df":0,"a":{"docs":{},"df":0,"m":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}},"e":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.4142135623730951},"https://guekka.github.io/nixos-server-2/":{"tf":1.4142135623730951}},"df":2,"a":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"r":{"docs":{},"df":0,"_":{"docs":{},"df":0,"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"r":{"docs":{},"df":0,"e":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}},"’":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"v":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}},"description":{"root":{"docs":{},"df":0,"1":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"2":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"a":{"docs":{},"df":0,"f":{"docs":{},"df":0,"f":{"docs":{},"df":0,"e":{"docs":{},"df":0,"c":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}}}},"d":{"docs":{},"df":0,"a":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}},"f":{"docs":{},"df":0,"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"i":{"docs":{},"df":0,"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}},"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}},"o":{"docs":{},"df":0,"u":{"docs":{},"df":0,"t":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}}}},"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"g":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}},"r":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.7320508075688772}},"df":1}}}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/posts/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"v":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.4142135623730951}},"df":1}}}}}},"u":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}},"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"v":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}},"i":{"docs":{},"df":0,"t":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"s":{"docs":{},"df":0,"c":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}},"title":{"root":{"docs":{},"df":0,"1":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1},"2":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1},"f":{"docs":{},"df":0,"l":{"docs":{},"df":0,"a":{"docs":{},"df":0,"k":{"docs":{},"df":0,"e":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}},"i":{"docs":{},"df":0,"m":{"docs":{},"df":0,"p":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"m":{"docs":{},"df":0,"a":{"docs":{},"df":0,"n":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0}},"df":1}}}}}}}},"n":{"docs":{},"df":0,"i":{"docs":{},"df":0,"x":{"docs":{},"df":0,"o":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}},"p":{"docs":{},"df":0,"a":{"docs":{},"df":0,"r":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}},"o":{"docs":{},"df":0,"l":{"docs":{},"df":0,"i":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}},"s":{"docs":{},"df":0,"t":{"docs":{"https://guekka.github.io/posts/":{"tf":1.0}},"df":1}}},"r":{"docs":{},"df":0,"i":{"docs":{},"df":0,"v":{"docs":{},"df":0,"a":{"docs":{},"df":0,"c":{"docs":{},"df":0,"i":{"docs":{"https://guekka.github.io/privacy/":{"tf":1.0}},"df":1}}}}}}},"s":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{},"df":0,"v":{"docs":{},"df":0,"e":{"docs":{},"df":0,"r":{"docs":{"https://guekka.github.io/nixos-server-1/":{"tf":1.0},"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":2}}}}}},"t":{"docs":{},"df":0,"a":{"docs":{},"df":0,"i":{"docs":{},"df":0,"l":{"docs":{},"df":0,"s":{"docs":{},"df":0,"c":{"docs":{},"df":0,"a":{"docs":{},"df":0,"l":{"docs":{"https://guekka.github.io/nixos-server-2/":{"tf":1.0}},"df":1}}}}}}}}}}},"documentStore":{"save":true,"docs":{"https://guekka.github.io/":{"body":"","description":"","id":"https://guekka.github.io/","title":""},"https://guekka.github.io/about/":{"body":"About\nHi. I’m Edgar, more often known as Guekka, G’k or G_ka. I like Nix(OS), Rust, C++, and a lot of other technologies.\nMy most important contribution to the software world is an automation tool called Cathedral Assets Optimizer (source) which is used by thousands of people. Its main purpose is helping the process of “porting” a mod between Skyrim Legendary Edition and Skyrim Special Edition.\n","description":"","id":"https://guekka.github.io/about/","title":"About"},"https://guekka.github.io/archive/":{"body":"","description":"","id":"https://guekka.github.io/archive/","title":""},"https://guekka.github.io/nixos-server-1/":{"body":"A few months ago, I woke up with the idea of hosting my own services. I went through a lot of tries. LXC, Debian, Alpine, (rootless or not) Docker, podman, portainer…\nBut no solution felt perfect. Until I decided to have a try at hosting using NixOS.\nI’m going to assume you know about NixOS and have some prior experience. However, for a small summary: NixOS is a Linux distribution revolving around the Nix package manager. Its main advantage is having a reproducible environment through a declarative configuration. This means that you can copy an entire computer configuration easily: if it works somewhere, it will work anywhere.\nMy main focus point is reproducibility, so that’s why we’ll start with configuring impermanence.\nWhat’s impermanence?\nOriginally, a philosophic concept. But in our case, impermanence means erasing the / drive at each reboot. You read that right, erasing almost everything at each reboot. This part stands on the shoulders of those who did it before me:\n\nErase your darlings: immutable infrastructure for mutable systems - Graham Christensen\nNixOS ❄: tmpfs as root\nEncypted Btrfs Root with Opt-in State on NixOS\nParanoid NixOS Setup - Xe Iaso\nnix-community/impermanence: NixOS module\n\nThe goal is the following: over years, configuration files accumulate. Sometimes editing /etc is required, because of a bug or an obscure configuration. NixOS allows us to avoid this manual file editing, but it does not force us to do so. We can still have a lot of important state, breaking the reproducibility promise.\nSo what can we do instead? Erase everything, at each reboot. This way, we’ll be sure the only source of truth is our configuration.\nInstalling the system\nI’m currently using a quickemu VM. This is not a recommenced setup and is only done for testing. Configuration file:\n\nLet’s first format it:\n\n\n\nUsing swap in 2023!?\n\nYes.\n\nWhile the impermanence module recommends using tmpfs for /, I chose to use btrfs: I do not have RAM to waste. Furthermore, this will allow us to use a nice script we’ll see later on.\nLet’s create btrfs subvolumes:\n\nAnd now, the crucial part:\n\nWe just took a snapshot of that empty volume. We will restore it at each reboot.\nWe can now mount the subvolumes and let nixos-generate-config do its job\n\nLastly, we only have to edit the generated configuration files at /mnt/etc/nixos.\nMy final configuration is available here. You can follow all the steps by looking at the commits.\nConfiguring the system\n\nChecking that we have the correct mount options in /mnt/etc/nixos/hardware-configuration.nix.\n\nI’ve added \"compress=zstd\" \"noatime\" to all filesystems. We also need to add neededForBoot to /var/log and /persist.\n\nReplacing default values in configuration.nix\n\nI’ve enabled networkmanager, removed most suggested options and enabled system.copySystemConfiguration.\nThis last option copies the current configuration to /run/current_system/configuration.nix. You should not rely on it: keep your configuration in a git repository. But it can serve as some kind of last chance.\n\nDeclaring a user, including ssh\n\n\nHere we have completely disabled imperative user modification. This does not matter much, as imperative changes would be erased anyway at start.\nWe thus need to provide a password. We’re using passwordFile for that: a path to a file containing the hashed password.\nHere’s how to generate that file: sudo mkpasswd -m sha-512 \"hunter2\" > /mnt/persist/passwords/user.\nThe SSH key was generated using `ssh-keygen -t ed25519 -C “nixos”.\n\nEnabling openSSH\nWe’re going to use Xe’s configuration:\n\n\nThis reduces attack surface, for example by disabling stream-local forwarding and disabling password authentification.\n\nThis will be enough for now. Let’s install the system before going to the next step: sudo nixos-install --root /mnt && sudo reboot. You should be able to connect by SSH using the previously defined key, or login using the password you defined in /persist/passwords/user.\nConfiguring impermanence\nWe’ve created our volumes, we’ve configured the system… But I promised we would reset our system at each reboot. Let’s do that now!\nWe’re going to use the following script, credit of mt-caret. Do not forget to replace vda3 with your data partition.\n16/07/23 update: it was brought to my attention that postDeviceCommands can cause data loss.\nWhile I did not experience any issue, I have updated the script to use a safer alternative.\n\nWe can then specify the files we want to keep.\nBut which files do we want to keep? Let’s find out. Thanks to another useful script of mt-caret, we can list the differences between our current / and the blank state:\n\nUsed like this:\n\nHere’s the result of mine:\n\nThat’s not too bad!\nOut of these, there’s almost nothing I want to preserve.\nLet’s make use of the impermanence module. We need to download it:\n\nAnd now, we can just tell it the files and directories that we want:\n\nWhat an ergonomic interface.\n\nWait, did you just say Nix was ergonomic?\n\nWell, yes. Sometimes.\n\nI have not saved my network manager configuration, but you may need to.\nWhen new files are set to be preserved, it is necessary to copy them manually to /persist:\n\nNow, if we reboot and list files again:\n\nSuccess! The files we persisted are no longer showing up.\nWhat about our home directory?\nIt is possible to setup the impermanence module for our home directory. However, I did not want to go through home-manager installation. Furthermore, a home directory is meant to be stateful.\nIn our case, we are creating a server, so it would still make sense to configure it. If you are interested, have a look at tmpfs at home.\nNext steps\nIn the next part, we will make our server more secure by making it only available through Tailscale. We will also setup our first service.\n\nI hope you’ve enjoyed this article! Thanks for reading to the end!\n","description":"","id":"https://guekka.github.io/nixos-server-1/","title":"NixOS as a server, part 1: Impermanence"},"https://guekka.github.io/nixos-server-2/":{"body":"In the previous part, we configured our NixOS server to use impermanence. I have made a few changes since, most notably moving to a proper VM in Proxmox.\nThe following instructions might lack some details, but you can follow the GitHub repo to see the full code.\nMoving to flakes\n\nIf you already know about flakes, you can safely ignore this part.\n\nHave you heard about Nix flakes? If you have been in the Nix ecosystem for more than a few days, most likely. They’re the shiny new way to write Nix code, still experimental but used everywhere.\nTheir main advantage over traditional Nix is purity, mainly with their defined inputs and outputs. \nRemember when I told you Nix was reproducible? It was a lie. Let me explain myself: when writing Nix code, we always have some kind of input. For example, nixpkgs will be required almost all the time. There are two ways to obtain it.\n\nfetch it: import builtins.fetchTarball \"https://github.com/nixos/nixpkgs/archive/nixos-22.11.tar.gz\";\nor more commonly, use channels: import <nixpkgs> {}\n\nThis second way uses a globally-defined configuration, which can change externally to our Nix files. We thus lose complete reproducibility. Instead, flakes allow us to avoid channels by specifying inputs alongside Nix configuration, as well as blocking some actions that could hinder reproducibility.\nFor a more in depth introduction, have a look at the wiki.\nNow, why do we want to migrate to flakes? We do not have external requirements, do we?\nWell, yes, we do. Apart from the obvious nixpkgs dependency, which is configured system-wide, the impermanence module is being imported:\n\nThis fetchTarball call is bad, by the way, as we do not specify the expected hash. We could be a victim of a man-in-the-middle attack and not notice it.\nNow that I intend to add more modules, and possibly use the unstable channel, it is better to migrate. Let’s see what our entry point would look like:\n\nThat’s a lot to understand at once. Let’s study it one line at a time.\nFirstly, we have to understand this file is simply describing outputs as a function taking inputs. Like in mathematics, we create the same output given the same input: a pure function, would say functional programmers.\n(1) is defining an input: we simply give it an url. That line can be translated as *Grab the nixos-22.11 branch from the GitHub repo nixpkgs owned by NixOS.\n(2) is defining the outputs function. Most complicated things are defined using functions in Nix. It takes a named attribute set argument as an input. So this syntax:\n\nis the same as:\n\nIn both cases, we’re accessing the nixpkgs property of the inputs set.\nBut in the first case, we don’t have to repeat inputs. everywhere. In JS, you would call that destructuring: it is just making inner elements easier to access. If you have troubles understanding the Nix syntax, I personally like FasterThanLime article.\n(3): NixOS configuration have to be placed specifically in the nixosConfigurations set.\n(4) is the place where we actually define the system. We call the nixosSystem function and pass it some arguments. Yes, the whole system is an output too!\n(5): we give the packages instance to our system. In our case, we are passing the default packages, but we might want to modify them before. We also have to specify our architecture (x86_64).\nThat’s pretty much it. With that flake.Nix in /etc/nixos, nixos-rebuild will work as before. However, if you’re using git, beware that your files all need to be under version control or Nix will not see them.\nSecrets with Sops\nIn order to set up Tailscale, we will use a pre-auth key. This allows us to connect to our server without interaction. However, we must hide this key, or other people could join our Tailscale network, which could obviously have dangerous consequences.\nThere are 2 well-known solutions : agenix and sops-nix. I’ve chosen sops for no particular reason.\nThe first step will be to add it to our flake. See, we already get a use for it!\nImporting sops-nix\nLet’s change our inputs:\n\nFollows\nWhat’s up with this follows? sops-nix already depends on nixpkgs, but it might use a different revision than ours. Making it use our own has several advantages:\n\nimprove consistency\nreduce the number of evaluations required\n\nAnd how do we know if a package has inputs that need to be redirected? That’s the neat thing, we don’t. Either we have to look at the upstream flake.nix, or we can call nix flake info and get a graph like so:\n\nWe can notice sops-nix also has a nixpkgs-stable input, that we might as well redirect.\nGenerating a key\nsops-nix works by encrypting our secrets with private keys.\nWe thus need to provide it with the keys we will use. We can generate an age key, or get one from our SSH host key.\nEach secrets group can have different allowed keys, so that one user cannot access another’s secrets.\nI will use the SSH host key for my server:\n\nWe now have to write .sops.yaml file in order to configure which keys can access which secrets.\n\nThat’s it for decryption. However, we need to write secrets too. For that, we can get the corresponding private key:\n\nThat install bit is here to create the directory if it doesn’t exist and set the right permissions.\n\nIsn’t this insecure? The key is not password-locked.\n\nIndeed, if someone has access to our user account, they can read that key and decrypt the secrets. However, we can probably assume our user already has access to the local secrets, so it doesn’t matter much. Our goal is to be able to put these secrets on a public GitHub, not to protect them locally.\nConfiguring sops-nix\nOur last step is to configure sops.\nWe’re going to get fancy here, as I’m stealing borrowing a module from Misterio’s config. In the future, this will often happen, as his config happens to be a great resource. Let’s have a look at sops.nix:\n\nThis looks complicated, but it is not. First, we are declaring some functions in the let block.\n\nisEd25519 simply tells if an SSH key uses ed25519\ngetKeyPath gets the path of an SSH key\nkeys is the list of ed25519 keys, taken from openssh\n\nThen we import sops. Finally, we give it the keys we collected earlier. This avoids hardcoding keys, which is great!\nWe can now import this module in our config:\n\nsops-nix is now ready to use. Do not forget to rebuild the config.\nOur first secret\nLet’s write a secret:\n\nAn editor should open. We can now write secrets, using yaml. Once we’re done, we can save the file. Example content:\n\nWe now have to tell sops this secret exists. So we declare it somewhere in our configuration:\n\nAnd that’s all! To use it, we simply have to use config.sops.secrets.tailscale_key.path where we need it. Beware that this will not give you the secret, but a path to a file containing the raw secret, for security reasons. Otherwise, the secret would be in the Nix store, and thus accessible to any user on the system.\nNote: adding a new host\nIf you ever need to add a new host, you will need to update your secrets with sops updatekeys your_secret. This command has to be on a system with already authorized keys.\nTailscale\nWe can finally get to a real feature, setting up Tailscale.\nFor those of you who haven’t heard of it, Tailscale is a private meshed network, allowing you to connect to your machines privately and securely through Wireguard, a VPN protocol, without exposing them to the world.\nThis means being able to close port 22, while still being able to SSH into your computer.\nFurthermore, Tailscale offers some additional features, such as a fancy file sending tool or hole punching, which allows you to connect to your computer even if it is behind a NAT. I won’t go into details here, but you can read more about it on their website.\nI’ve chosen to write a full-fledged NixOS module for Tailscale, as it is a service that needs to be configured and started. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!\nBoilerplate for NixOS modules\nWe’re going to write a module, so we need to create a directory for it:\n\nInside, we’ll need a default.nix file:\n\nBy convention, this file is automatically imported when you import a directory. Then, in our flake.nix, we can import our module:\n\nAs before, the nixosModules attribute has a special meaning.\nFinally, we have to import the module we’re writing in our configuration:\n\nWriting the module\nWe’re going to write a module to start Tailscale and connect to it automatically. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!\nFirst, we need to create a tailscale-autoconnect.nix file in our modules/nixos directory. We’ll start with the boilerplate:\n\nThis is the basic structure of a module. We declare an option, and then we use it to conditionally change the configuration. So:\n\nWhat we write in options is the option declaration\nWhat we write in config is the consequence of the option being enabled, the configuration change\n\nLet’s declare all the options first.\n\nThis looks like a lot of code, but we’re simply declaring options. We need to give them a type, and we can also give a default value and a description.\nNow, the actually useful code:\n\nFirst, the assertions. They’re here to make sure that the user doesn’t make any mistake when configuring the module. For example, a user cannot both advertise an exit node and set an exit node.\nThen, the service. We’re using systemd to run a script that will connect to Tailscale. The after, wants and wantedBy options make the script run after the network is up and after Tailscale daemon is started. The Type option is here to make sure that the script is run only once. The script itself is a bit long, but it’s just a bunch of bash commands. It’s pretty straightforward. First, we wait for the Tailscale daemon to settle. Then, we check if we’re already authenticated. If we are, we exit. Otherwise, we authenticate. Finally, we connect to Tailscale. We have to do it in two steps because some options are only available after authentication.\nAt the end, we configure the firewall to allow Tailscale traffic, and we enable the Tailscale service.\nNow, an example of how to use this module:\n\nThe module is imported and configured. We also use the sops secret we created earlier. Finally, we persist the Tailscale state, so that we don’t have to authenticate again after a reboot. This is especially important if the authkey can expire.\n\nThat’s all for this post. Thanks for reading! If you have any question, feel free to ask in the comments. The final code can be found here.\n\n","description":"","id":"https://guekka.github.io/nixos-server-2/","title":"NixOS as a server, part 2: Flake, tailscale"},"https://guekka.github.io/pages/":{"body":"","description":"","id":"https://guekka.github.io/pages/","title":""},"https://guekka.github.io/posts/":{"body":"","description":"","id":"https://guekka.github.io/posts/","title":"posts"},"https://guekka.github.io/privacy/":{"body":"Privacy\n\nThis site does not set or use cookies.\nThis site does not store data in the browser to be shared, sent, or sold to third-parties.\nNo personal information is shared, sent, or sold to third-parties.\n\nEffective Date: 1st Jan 2022\n","description":"This page outlines the Privacy Policy for this site, and the date at which this policy was put into affect.","id":"https://guekka.github.io/privacy/","title":"Privacy Policy"}},"docInfo":{"https://guekka.github.io/":{"body":0,"description":0,"title":0},"https://guekka.github.io/about/":{"body":40,"description":0,"title":0},"https://guekka.github.io/archive/":{"body":0,"description":0,"title":0},"https://guekka.github.io/nixos-server-1/":{"body":546,"description":0,"title":5},"https://guekka.github.io/nixos-server-2/":{"body":973,"description":0,"title":6},"https://guekka.github.io/pages/":{"body":0,"description":0,"title":0},"https://guekka.github.io/posts/":{"body":0,"description":0,"title":1},"https://guekka.github.io/privacy/":{"body":26,"description":9,"title":2}},"length":8},"lang":"English"} \ No newline at end of file diff --git a/site.webmanifest b/site.webmanifest new file mode 100644 index 0000000..b20abb7 --- /dev/null +++ b/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..aaaaeba --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,44 @@ + + + + https://guekka.github.io/ + + + https://guekka.github.io/about/ + + + https://guekka.github.io/archive/ + + + https://guekka.github.io/categories/ + + + https://guekka.github.io/categories/projects/ + + + https://guekka.github.io/nixos-server-1/ + 2023-02-20 + + + https://guekka.github.io/nixos-server-2/ + 2023-05-17 + + + https://guekka.github.io/page/1/ + + + https://guekka.github.io/posts/ + + + https://guekka.github.io/privacy/ + + + https://guekka.github.io/tags/ + + + https://guekka.github.io/tags/nix/ + + + https://guekka.github.io/tags/self-hosting/ + + diff --git a/sw.js b/sw.js new file mode 100644 index 0000000..abc5a49 --- /dev/null +++ b/sw.js @@ -0,0 +1,191 @@ +class Pwa { + + constructor(self) { + this.scope = self; + const Version = new URL(location).searchParams.get("v"); + this.CACHE_VERSION = Version; + //this.BASE_CACHE_FILES=['/js/theme.min.js','/js/theme_light.min.js','/abridge.css','/js/abridge.min.js','/','/404.html','/offline/','/manifest.json']; + this.BASE_CACHE_FILES = ['/404.html','/_headers','/abridge.css','/android-chrome-192x192.png','/android-chrome-512x512.png','/apple-touch-icon.png','/atom.xml','/banner.png','/browserconfig.xml','/elasticlunr.min.js','/favicon-16x16.png','/favicon-32x32.png','/favicon.ico','/favicon.svg','/','/katex.min.css','/m1024.png','/m128.png','/m192.png','/m384.png','/m48.png','/m512.png','/m72.png','/m96.png','/manifest.json','/manifest.min.json','/mstile-150x150.png','/nojs.css','/robots.txt','/safari-pinned-tab.svg','/search_index.en.json','/search_index.es.json','/search_index.fr.json','/sitemap.xml','/about/','/archive/','/blog/','/contact/','/es/atom.xml','/es/','/fonts/KaTeX_AMS-Regular.woff2','/fonts/KaTeX_Caligraphic-Bold.woff2','/fonts/KaTeX_Caligraphic-Regular.woff2','/fonts/KaTeX_Fraktur-Bold.woff2','/fonts/KaTeX_Fraktur-Regular.woff2','/fonts/KaTeX_Main-Bold.woff2','/fonts/KaTeX_Main-BoldItalic.woff2','/fonts/KaTeX_Main-Italic.woff2','/fonts/KaTeX_Main-Regular.woff2','/fonts/KaTeX_Math-BoldItalic.woff2','/fonts/KaTeX_Math-Italic.woff2','/fonts/KaTeX_SansSerif-Bold.woff2','/fonts/KaTeX_SansSerif-Italic.woff2','/fonts/KaTeX_SansSerif-Regular.woff2','/fonts/KaTeX_Script-Regular.woff2','/fonts/KaTeX_Size1-Regular.woff2','/fonts/KaTeX_Size2-Regular.woff2','/fonts/KaTeX_Size3-Regular.woff2','/fonts/KaTeX_Size4-Regular.woff2','/fonts/KaTeX_Typewriter-Regular.woff2','/fonts/Roboto-Bold.woff2','/fonts/Roboto-Italic.woff2','/fonts/Roboto-Mono-Italic.woff2','/fonts/Roboto-Mono.woff2','/fonts/Roboto.woff2','/fr/atom.xml','/fr/','/images/ferris-gesture.svg','/images/ferris.svg','/js/abridge.min.js','/js/abridge_nopwa.min.js','/js/abridge_nosearch.min.js','/js/abridge_nosearch_nopwa.min.js','/js/codecopy.js','/js/elasticlunr.min.js','/js/email.js','/js/katex-auto-render.min.js','/js/katex.min.js','/js/katexbundle.min.js','/js/katexbundle.min.old.js','/js/katexoptions.js','/js/lunr.da.js','/js/lunr.da.min.js','/js/lunr.de.js','/js/lunr.de.min.js','/js/lunr.du.js','/js/lunr.du.min.js','/js/lunr.es.js','/js/lunr.es.min.js','/js/lunr.fi.js','/js/lunr.fi.min.js','/js/lunr.fr.js','/js/lunr.fr.min.js','/js/lunr.hu.js','/js/lunr.hu.min.js','/js/lunr.it.js','/js/lunr.it.min.js','/js/lunr.jp.js','/js/lunr.jp.min.js','/js/lunr.no.js','/js/lunr.no.min.js','/js/lunr.pt.js','/js/lunr.pt.min.js','/js/lunr.ro.js','/js/lunr.ro.min.js','/js/lunr.ru.js','/js/lunr.ru.min.js','/js/lunr.stemmer.support.js','/js/lunr.stemmer.support.min.js','/js/lunr.sv.js','/js/lunr.sv.min.js','/js/lunr.tr.js','/js/lunr.tr.min.js','/js/lunr.zh.js','/js/lunr.zh.min.js','/js/mathtex-script-type.min.js','/js/prestyle.js','/js/search.js','/js/search_elasticlunr.min.js','/js/search_elasticlunr_jindex.min.js','/js/search_stork.min.js','/js/search_tinysearch.min.js','/js/searchjava.js','/js/searchjavaugly.js','/js/stork.js','/js/stork_config.js','/js/sw_load.js','/js/sw_load.min.js','/js/theme.js','/js/theme.min.js','/js/theme_button.js','/js/theme_light.js','/js/theme_light.min.js','/js/tinysearch.js','/offline/','/overview-abridge/','/overview-abridge/lighthouse.png','/overview-code-blocks/','/overview-images/corro.svg','/overview-images/ferris-gesture.png','/overview-images/ferris-gesture.svg','/overview-images/ferris-happy.svg','/overview-images/ferris.svg','/overview-images/','/overview-markdown-and-style/','/overview-math/','/overview-rich-content/','/overview-rich-content/over9000-400.avif','/overview-rich-content/over9000-640.avif','/overview-rich-content/over9000-640.webp','/overview-rich-content/over9000-960.avif','/overview-rich-content/over9000.mp3','/overview-rich-content/over9000.ogg','/overview-rich-content/over9000_av1.mp4','/overview-rich-content/over9000_vp9.webm','/overview-showdata/','/privacy/','/tags/','/es/archive/','/es/blog/','/es/tags/','/fr/about/','/fr/archive/','/fr/blog/','/fr/contact/','/fr/offline/','/fr/overview-abridge/','/fr/overview-abridge/lighthouse.png','/fr/overview-code-blocks/','/fr/overview-images/corro.svg','/fr/overview-images/ferris-gesture.png','/fr/overview-images/ferris-gesture.svg','/fr/overview-images/ferris-happy.svg','/fr/overview-images/ferris.svg','/fr/overview-images/','/fr/overview-markdown-and-style/','/fr/overview-math/','/fr/overview-rich-content/','/fr/overview-rich-content/over9000-400.avif','/fr/overview-rich-content/over9000-640.avif','/fr/overview-rich-content/over9000-640.webp','/fr/overview-rich-content/over9000-960.avif','/fr/overview-rich-content/over9000.mp3','/fr/overview-rich-content/over9000.ogg','/fr/overview-rich-content/over9000_av1.mp4','/fr/overview-rich-content/over9000_vp9.webm','/fr/overview-showdata/','/fr/privacy/','/fr/tags/','/overview-images/img/ferris-gesture.svg','/overview-images/img/ferris.svg','/page/1/','/page/2/','/page/3/','/page/4/','/tags/audio/atom.xml','/tags/audio/','/tags/config/atom.xml','/tags/config/','/tags/data/atom.xml','/tags/data/','/tags/features/atom.xml','/tags/features/','/tags/images/atom.xml','/tags/images/','/tags/markdown/atom.xml','/tags/markdown/','/tags/mathematics/atom.xml','/tags/mathematics/','/tags/shortcodes/atom.xml','/tags/shortcodes/','/tags/video/atom.xml','/tags/video/','/video-streaming-sites/overview-embed-streamable/','/video-streaming-sites/overview-embed-vimeo/','/video-streaming-sites/overview-embed-youtube/','/blog/page/1/','/es/page/1/','/es/tags/features/atom.xml','/es/tags/features/','/es/tags/shortcodes/atom.xml','/es/tags/shortcodes/','/es/tags/video/atom.xml','/es/tags/video/','/es/video-streaming-sites/overview-embed-streamable/','/fr/overview-images/img/ferris-gesture.svg','/fr/overview-images/img/ferris.svg','/fr/page/1/','/fr/page/2/','/fr/page/3/','/fr/page/4/','/fr/tags/audio/atom.xml','/fr/tags/audio/','/fr/tags/config/atom.xml','/fr/tags/config/','/fr/tags/data/atom.xml','/fr/tags/data/','/fr/tags/features/atom.xml','/fr/tags/features/','/fr/tags/images/atom.xml','/fr/tags/images/','/fr/tags/markdown/atom.xml','/fr/tags/markdown/','/fr/tags/mathematics/atom.xml','/fr/tags/mathematics/','/fr/tags/shortcodes/atom.xml','/fr/tags/shortcodes/','/fr/tags/video/atom.xml','/fr/tags/video/','/fr/video-streaming-sites/overview-embed-streamable/','/fr/video-streaming-sites/overview-embed-vimeo/','/fr/video-streaming-sites/overview-embed-youtube/','/es/blog/page/1/','/fr/blog/page/1/']; + this.host = `${self.location.protocol}//${self.location.host}`; + console.info(`Host: ${this.host}`); + this.OFFLINE_PAGE = '/offline/'; + this.NOT_FOUND_PAGE = '/404.html'; + this.CACHE_NAME = `content-v${this.CACHE_VERSION}`; + // 3600=1hour, 28800=8hours, 86400=1day, 604800=1week, 1209600=2weeks + this.NORM_TTL = 0; + this.LONG_TTL = 0; + // keep the ttl on these lower: + this.TTL_NORM = ["sw.min.js", "sw_load.min.js"]; + // rarely change, may be a good idea to periodically refresh, incase I change these and forget to increment service worker version: + this.TTL_LONG = ["jpg", "jpeg", "png", "gif", "webp", "avif", "ico", "svg", "xsl", "txt"]; + // never change, cache forever unless service worker version is incremented: + this.TTL_EXEMPT = ["js", "css", "otf", "eot", "ttf", "woff", "woff2", "mp4", "webm", "mp3", "ogg"]; + // skip these extensions so they expire same time as html: st,wasm,json(search), xml(sitemap,atom,rss) + } + + canCache(url) { + if (url.startsWith("http://localhost")) { + return false; + } + const result = url.toString().startsWith(this.host); + return result; + } + + getFileExtension(url) { + const extension = url.split('.').reverse()[0].split('?')[0]; + return (extension.endsWith('/')) ? '/' : extension; + } + getFileName(url) { + const filename = url.substring(url.lastIndexOf('/') + 1).split('?')[0]; + return (filename.endsWith('/')) ? '/' : filename; + } + + getTTL(url) { + if (typeof url === 'string') { + const extension = this.getFileExtension(url); + const filename = this.getFileName(url); + + if (this.TTL_NORM.indexOf(filename) > -1) { + console.info(url + ' contains a TTL_NORM filename'); + return this.NORM_TTL; + } + if (this.TTL_LONG.indexOf(extension) > -1) { + console.info(url + ' contains a TTL_LONG extension'); + return this.LONG_TTL; + } + if (this.TTL_EXEMPT.indexOf(extension) > -1) { + console.info(url + ' contains a TTL_EXEMPT extension'); + return null; + } + console.info(url + ' TTL_NORM'); + return this.NORM_TTL; + } + return null; + } + + async installServiceWorker() { + try { + await caches.open(this.CACHE_NAME).then((cache) => { + return cache.addAll(this.BASE_CACHE_FILES); + }, err => console.error(`Error with ${this.CACHE_NAME}`, err)); + return this.scope.skipWaiting(); + } + catch (err) { + return console.error("Error with installation: ", err); + } + } + + cleanupLegacyCache() { + + const currentCaches = [this.CACHE_NAME]; + + return new Promise( + (resolve, reject) => { + caches.keys() + .then((keys) => keys.filter((key) => !~currentCaches.indexOf(key))) + .then((legacy) => { + if (legacy.length) { + Promise.all(legacy.map((legacyKey) => caches.delete(legacyKey)) + ).then(() => resolve()).catch((err) => { + console.error("Error in legacy cleanup: ", err); + reject(err); + }); + } else { + resolve(); + } + }).catch((err) => { + console.error("Error in legacy cleanup: ", err); + reject(err); + }); + }); + } + + async preCacheUrl(url) { + const cache = await caches.open(this.CACHE_NAME); + const response = await cache.match(url); + if (!response) { + return fetch(url).then(resp => cache.put(url, resp.clone())); + } + return null; + } + + register() { + this.scope.addEventListener('install', event => { + event.waitUntil( + Promise.all([ + this.installServiceWorker(), + this.scope.skipWaiting(), + ])); + console.info('SW Installed'); + }); + + this.scope.addEventListener('activate', event => { + event.waitUntil(Promise.all( + [this.cleanupLegacyCache(), + this.scope.clients.claim(), + this.scope.skipWaiting()]).catch((err) => { + console.error("Activation error: ", err); + event.skipWaiting(); + })); + }); + + this.scope.addEventListener('fetch', event => { + event.respondWith( + caches.open(this.CACHE_NAME).then(async cache => { + // check if this is NOT a resource we allow cacheing (some other domain), if so fetch it instead of cache. + if (!this.canCache(event.request.url)) { + return fetch(event.request); + } + // check the cache for the requested resource + const response = await cache.match(event.request); + if (response) { + const headers = response.headers.entries(); + let date = null; + for (let pair of headers) { + if (pair[0] === 'date') { + date = new Date(pair[1]); + break; + } + } + // date is not working, so ignore TTL and just serve the cached resource. + if (!date) { + return response; + } + const age = parseInt(((new Date().getTime() - date.getTime()) / 1000).toString()); + const ttl = this.getTTL(event.request.url); + if (ttl === null || (ttl && age < ttl)) { + // return the resource if it is not beyond the TTL + return response; + } + } + // if we made it here then we either did not have the cache, or the TTL was expired. + return fetch(event.request.clone()).then(resp => { + if (resp.status < 400) { + if (this.canCache(event.request.url)) { + cache.put(event.request, resp.clone()); + } + return resp; + } + else { + return cache.match(this.NOT_FOUND_PAGE); + } + }).catch(err => { + // if we made it here then we were unable to fetch the resource. + // maybe we were only fetching because of expired TTL, so use the cache regardless of TTL: + if (typeof event.request.url === 'string') { + console.info("url: "+event.request.url) + } + if (response) { + return response; + } + // if we made it here then we were unable to fetch the resource and do not have it cached. + console.error(`Error fetching ${event.request.url} resulted in offline`, err); + return cache.match(this.OFFLINE_PAGE); + }) + })); + }); + } +} + +const pwa = new Pwa(self); +pwa.register(); diff --git a/sw.min.js b/sw.min.js new file mode 100644 index 0000000..cee8d6f --- /dev/null +++ b/sw.min.js @@ -0,0 +1 @@ +class Pwa{constructor(e){this.scope=e;var s=new URL(location).searchParams.get("v");this.CACHE_VERSION=s,this.BASE_CACHE_FILES=["/404.html","/_headers","/abridge.css","/android-chrome-192x192.png","/android-chrome-512x512.png","/apple-touch-icon.png","/atom.xml","/banner.png","/browserconfig.xml","/elasticlunr.min.js","/favicon-16x16.png","/favicon-32x32.png","/favicon.ico","/favicon.svg","/","/katex.min.css","/m1024.png","/m128.png","/m192.png","/m384.png","/m48.png","/m512.png","/m72.png","/m96.png","/manifest.json","/manifest.min.json","/mstile-150x150.png","/nojs.css","/robots.txt","/safari-pinned-tab.svg","/search_index.en.json","/search_index.es.json","/search_index.fr.json","/sitemap.xml","/about/","/archive/","/blog/","/contact/","/es/atom.xml","/es/","/fonts/KaTeX_AMS-Regular.woff2","/fonts/KaTeX_Caligraphic-Bold.woff2","/fonts/KaTeX_Caligraphic-Regular.woff2","/fonts/KaTeX_Fraktur-Bold.woff2","/fonts/KaTeX_Fraktur-Regular.woff2","/fonts/KaTeX_Main-Bold.woff2","/fonts/KaTeX_Main-BoldItalic.woff2","/fonts/KaTeX_Main-Italic.woff2","/fonts/KaTeX_Main-Regular.woff2","/fonts/KaTeX_Math-BoldItalic.woff2","/fonts/KaTeX_Math-Italic.woff2","/fonts/KaTeX_SansSerif-Bold.woff2","/fonts/KaTeX_SansSerif-Italic.woff2","/fonts/KaTeX_SansSerif-Regular.woff2","/fonts/KaTeX_Script-Regular.woff2","/fonts/KaTeX_Size1-Regular.woff2","/fonts/KaTeX_Size2-Regular.woff2","/fonts/KaTeX_Size3-Regular.woff2","/fonts/KaTeX_Size4-Regular.woff2","/fonts/KaTeX_Typewriter-Regular.woff2","/fonts/Roboto-Bold.woff2","/fonts/Roboto-Italic.woff2","/fonts/Roboto-Mono-Italic.woff2","/fonts/Roboto-Mono.woff2","/fonts/Roboto.woff2","/fr/atom.xml","/fr/","/images/ferris-gesture.svg","/images/ferris.svg","/js/abridge.min.js","/js/abridge_nopwa.min.js","/js/abridge_nosearch.min.js","/js/abridge_nosearch_nopwa.min.js","/js/codecopy.js","/js/elasticlunr.min.js","/js/email.js","/js/katex-auto-render.min.js","/js/katex.min.js","/js/katexbundle.min.js","/js/katexbundle.min.old.js","/js/katexoptions.js","/js/lunr.da.js","/js/lunr.da.min.js","/js/lunr.de.js","/js/lunr.de.min.js","/js/lunr.du.js","/js/lunr.du.min.js","/js/lunr.es.js","/js/lunr.es.min.js","/js/lunr.fi.js","/js/lunr.fi.min.js","/js/lunr.fr.js","/js/lunr.fr.min.js","/js/lunr.hu.js","/js/lunr.hu.min.js","/js/lunr.it.js","/js/lunr.it.min.js","/js/lunr.jp.js","/js/lunr.jp.min.js","/js/lunr.no.js","/js/lunr.no.min.js","/js/lunr.pt.js","/js/lunr.pt.min.js","/js/lunr.ro.js","/js/lunr.ro.min.js","/js/lunr.ru.js","/js/lunr.ru.min.js","/js/lunr.stemmer.support.js","/js/lunr.stemmer.support.min.js","/js/lunr.sv.js","/js/lunr.sv.min.js","/js/lunr.tr.js","/js/lunr.tr.min.js","/js/lunr.zh.js","/js/lunr.zh.min.js","/js/mathtex-script-type.min.js","/js/prestyle.js","/js/search.js","/js/search_elasticlunr.min.js","/js/search_elasticlunr_jindex.min.js","/js/search_stork.min.js","/js/search_tinysearch.min.js","/js/searchjava.js","/js/searchjavaugly.js","/js/stork.js","/js/stork_config.js","/js/sw_load.js","/js/sw_load.min.js","/js/theme.js","/js/theme.min.js","/js/theme_button.js","/js/theme_light.js","/js/theme_light.min.js","/js/tinysearch.js","/offline/","/overview-abridge/","/overview-abridge/lighthouse.png","/overview-code-blocks/","/overview-images/corro.svg","/overview-images/ferris-gesture.png","/overview-images/ferris-gesture.svg","/overview-images/ferris-happy.svg","/overview-images/ferris.svg","/overview-images/","/overview-markdown-and-style/","/overview-math/","/overview-rich-content/","/overview-rich-content/over9000-400.avif","/overview-rich-content/over9000-640.avif","/overview-rich-content/over9000-640.webp","/overview-rich-content/over9000-960.avif","/overview-rich-content/over9000.mp3","/overview-rich-content/over9000.ogg","/overview-rich-content/over9000_av1.mp4","/overview-rich-content/over9000_vp9.webm","/overview-showdata/","/privacy/","/tags/","/es/archive/","/es/blog/","/es/tags/","/fr/about/","/fr/archive/","/fr/blog/","/fr/contact/","/fr/offline/","/fr/overview-abridge/","/fr/overview-abridge/lighthouse.png","/fr/overview-code-blocks/","/fr/overview-images/corro.svg","/fr/overview-images/ferris-gesture.png","/fr/overview-images/ferris-gesture.svg","/fr/overview-images/ferris-happy.svg","/fr/overview-images/ferris.svg","/fr/overview-images/","/fr/overview-markdown-and-style/","/fr/overview-math/","/fr/overview-rich-content/","/fr/overview-rich-content/over9000-400.avif","/fr/overview-rich-content/over9000-640.avif","/fr/overview-rich-content/over9000-640.webp","/fr/overview-rich-content/over9000-960.avif","/fr/overview-rich-content/over9000.mp3","/fr/overview-rich-content/over9000.ogg","/fr/overview-rich-content/over9000_av1.mp4","/fr/overview-rich-content/over9000_vp9.webm","/fr/overview-showdata/","/fr/privacy/","/fr/tags/","/overview-images/img/ferris-gesture.svg","/overview-images/img/ferris.svg","/page/1/","/page/2/","/page/3/","/page/4/","/tags/audio/atom.xml","/tags/audio/","/tags/config/atom.xml","/tags/config/","/tags/data/atom.xml","/tags/data/","/tags/features/atom.xml","/tags/features/","/tags/images/atom.xml","/tags/images/","/tags/markdown/atom.xml","/tags/markdown/","/tags/mathematics/atom.xml","/tags/mathematics/","/tags/shortcodes/atom.xml","/tags/shortcodes/","/tags/video/atom.xml","/tags/video/","/video-streaming-sites/overview-embed-streamable/","/video-streaming-sites/overview-embed-vimeo/","/video-streaming-sites/overview-embed-youtube/","/blog/page/1/","/es/page/1/","/es/tags/features/atom.xml","/es/tags/features/","/es/tags/shortcodes/atom.xml","/es/tags/shortcodes/","/es/tags/video/atom.xml","/es/tags/video/","/es/video-streaming-sites/overview-embed-streamable/","/fr/overview-images/img/ferris-gesture.svg","/fr/overview-images/img/ferris.svg","/fr/page/1/","/fr/page/2/","/fr/page/3/","/fr/page/4/","/fr/tags/audio/atom.xml","/fr/tags/audio/","/fr/tags/config/atom.xml","/fr/tags/config/","/fr/tags/data/atom.xml","/fr/tags/data/","/fr/tags/features/atom.xml","/fr/tags/features/","/fr/tags/images/atom.xml","/fr/tags/images/","/fr/tags/markdown/atom.xml","/fr/tags/markdown/","/fr/tags/mathematics/atom.xml","/fr/tags/mathematics/","/fr/tags/shortcodes/atom.xml","/fr/tags/shortcodes/","/fr/tags/video/atom.xml","/fr/tags/video/","/fr/video-streaming-sites/overview-embed-streamable/","/fr/video-streaming-sites/overview-embed-vimeo/","/fr/video-streaming-sites/overview-embed-youtube/","/es/blog/page/1/","/fr/blog/page/1/"],this.host=e.location.protocol+"//"+e.location.host,this.OFFLINE_PAGE="/offline/",this.NOT_FOUND_PAGE="/404.html",this.CACHE_NAME="content-v"+this.CACHE_VERSION,this.NORM_TTL=0,this.LONG_TTL=0,this.TTL_NORM=["sw.min.js","sw_load.min.js"],this.TTL_LONG=["jpg","jpeg","png","gif","webp","avif","ico","svg","xsl","txt"],this.TTL_EXEMPT=["js","css","otf","eot","ttf","woff","woff2","mp4","webm","mp3","ogg"]}canCache(e){return!e.startsWith("http://localhost")&&e.toString().startsWith(this.host)}getFileExtension(e){e=e.split(".").reverse()[0].split("?")[0];return e.endsWith("/")?"/":e}getFileName(e){e=e.substring(1+e.lastIndexOf("/")).split("?")[0];return e.endsWith("/")?"/":e}getTTL(e){var s;return"string"==typeof e?(s=this.getFileExtension(e),e=this.getFileName(e),~this.TTL_NORM.indexOf(e)?this.NORM_TTL:~this.TTL_LONG.indexOf(s)?this.LONG_TTL:~this.TTL_EXEMPT.indexOf(s)?null:this.NORM_TTL):null}async installServiceWorker(){try{return await caches.open(this.CACHE_NAME).then(e=>e.addAll(this.BASE_CACHE_FILES),e=>{}),this.scope.skipWaiting()}catch(e){}}cleanupLegacyCache(){let r=[this.CACHE_NAME];return new Promise((s,t)=>{caches.keys().then(e=>e.filter(e=>!~r.indexOf(e))).then(e=>{e.length?Promise.all(e.map(e=>caches.delete(e))).then(()=>s()).catch(e=>{t(e)}):s()}).catch(e=>{t(e)})})}async preCacheUrl(s){let t=await caches.open(this.CACHE_NAME);return await t.match(s)?null:fetch(s).then(e=>t.put(s,e.clone()))}register(){this.scope.addEventListener("install",e=>{e.waitUntil(Promise.all([this.installServiceWorker(),this.scope.skipWaiting()]))}),this.scope.addEventListener("activate",s=>{s.waitUntil(Promise.all([this.cleanupLegacyCache(),this.scope.clients.claim(),this.scope.skipWaiting()]).catch(e=>{s.skipWaiting()}))}),this.scope.addEventListener("fetch",o=>{o.respondWith(caches.open(this.CACHE_NAME).then(async s=>{if(!this.canCache(o.request.url))return fetch(o.request);let t=await s.match(o.request);if(t){var r;let e=null;for(r of t.headers.entries())if("date"===r[0]){e=new Date(r[1]);break}if(!e)return t;var i=parseInt(""+((new Date).getTime()-e.getTime())/1e3),a=this.getTTL(o.request.url);if(null===a||a&&ie.status<400?(this.canCache(o.request.url)&&s.put(o.request,e.clone()),e):s.match(this.NOT_FOUND_PAGE)).catch(e=>(o.request.url,t||s.match(this.OFFLINE_PAGE)))}))})}}let pwa=new Pwa(self);pwa.register(); \ No newline at end of file diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 0000000..4a45fca --- /dev/null +++ b/tags/index.html @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Tags | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + +
    + + + diff --git a/tags/nix/atom.xml b/tags/nix/atom.xml new file mode 100644 index 0000000..5fc582f --- /dev/null +++ b/tags/nix/atom.xml @@ -0,0 +1,786 @@ + + + Guekka's blog - nix + C++, Nix, Linux, Self-hosting, and more. + + + Zola + 2023-05-17T00:00:00+00:00 + https://guekka.github.io/tags/nix/atom.xml + + NixOS as a server, part 2: Flake, tailscale + 2023-05-17T00:00:00+00:00 + 2023-05-17T00:00:00+00:00 + + + + + Unknown + + + + + + https://guekka.github.io/nixos-server-2/ + + <p>In the <a rel="noopener" target="_blank" href="https://guekka.github.io/nixos-server-1/">previous part</a>, we configured our NixOS server to use impermanence. I have made a few changes since, most notably moving to a proper VM in Proxmox.</p> +<p>The following instructions might lack some details, but you can follow <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/commits/2-tailscale">the GitHub repo</a> to see the full code.</p> +<h1 id="moving-to-flakes">Moving to flakes</h1> +<blockquote> +<p>If you already know about flakes, you can safely ignore this part.</p> +</blockquote> +<p>Have you heard about Nix flakes? If you have been in the Nix ecosystem for more than a few days, most likely. They’re the shiny new way to write Nix code, still experimental but used everywhere. +Their main advantage over traditional Nix is <em>purity</em>, mainly with their defined <code>inputs</code> and <code>outputs</code>. </p> +<p>Remember when I told you Nix was reproducible? It was a lie. Let me explain myself: when writing Nix code, we always have some kind of input. For example, <code>nixpkgs</code> will be required almost all the time. There are two ways to obtain it.</p> +<ul> +<li>fetch it: <code>import builtins.fetchTarball &quot;https://github.com/nixos/nixpkgs/archive/nixos-22.11.tar.gz&quot;;</code></li> +<li>or more commonly, use <em>channels</em>: <code>import &lt;nixpkgs&gt; {}</code></li> +</ul> +<p>This second way uses a globally-defined configuration, which can change externally to our Nix files. We thus lose complete reproducibility. Instead, flakes allow us to avoid channels by specifying inputs alongside Nix configuration, as well as blocking some actions that could hinder reproducibility.</p> +<p>For a more in depth introduction, have a look at <a rel="noopener" target="_blank" href="https://nixos.wiki/wiki/Flakes#See_also">the wiki</a>.</p> +<p>Now, why do we want to migrate to flakes? We do not have external requirements, do we? +Well, yes, we do. Apart from the obvious <code>nixpkgs</code> dependency, which is configured system-wide, the impermanence module is being imported:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">impermanence</span> <span class="z-invalid z-illegal">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">fetchTarball</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://github.com/Nix-community/impermanence/archive/master.tar.gz<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This <code>fetchTarball</code> call is bad, by the way, as we do not specify the expected hash. We could be a victim of a man-in-the-middle attack and not notice it.</p> +<p>Now that I intend to add more modules, and possibly use the <code>unstable</code> channel, it is better to migrate. Let’s see what our entry point would look like:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># what is consumed (previously provided by channels and fetchTarball)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">inputs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixpkgs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:NixOS/nixpkgs/nixos-22.11<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># (1)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">impermanence</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:Nix-community/impermanence<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># what will be produced (i.e. the build)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">outputs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span>@<span class="z-variable z-parameter z-function z-3 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (2)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixosConfigurations</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (3)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">server</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosSystem</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (4)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">packages</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">legacyPackages</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">x86_64-linux</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># (5)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">specialArgs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">inputs</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># forward inputs to modules</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">modules</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">./configuration.Nix</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>That’s a lot to understand at once. Let’s study it one line at a time. +Firstly, we have to understand this file is simply describing <code>outputs</code> as a function taking <code>inputs</code>. Like in mathematics, we create the same output given the same input: a <em>pure</em> function, would say functional programmers.</p> +<p><code>(1)</code> is defining an input: we simply give it an url. That line can be translated as *Grab the <code>nixos-22.11</code> branch from the GitHub repo <code>nixpkgs</code> owned by <code>NixOS</code>.</p> +<p><code>(2)</code> is defining the <code>outputs</code> function. Most complicated things are defined using functions in Nix. It takes a <em>named attribute set</em> argument as an input. So this syntax:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span>@<span class="z-variable z-parameter z-function z-3 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span> +</span></code></pre> +<p>is the same as:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-function z-4 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">inputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixpkgs</span> +</span></code></pre> +<p>In both cases, we’re accessing the <code>nixpkgs</code> property of the <code>inputs</code> set.</p> +<p>But in the first case, we don’t have to repeat <code>inputs.</code> everywhere. In JS, you would call that <em>destructuring</em>: it is just making inner elements easier to access. If you have troubles understanding the Nix syntax, I personally like <a rel="noopener" target="_blank" href="https://fasterthanli.me/series/building-a-rust-service-with-Nix/part-9">FasterThanLime article</a>.</p> +<p><code>(3)</code>: NixOS configuration have to be placed specifically in the <code>nixosConfigurations</code> set.</p> +<p><code>(4)</code> is the place where we actually define the system. We call the <code>nixosSystem</code> function and pass it some arguments. Yes, the whole system is an <code>output</code> too!</p> +<p><code>(5)</code>: we give the packages instance to our system. In our case, we are passing the default packages, but we might want to modify them before. We also have to specify our architecture (<code>x86_64</code>).</p> +<p>That’s pretty much it. With that <code>flake.Nix</code> in <code>/etc/nixos</code>, <code>nixos-rebuild</code> will work as before. However, if you’re using git, beware that your files all need to be under version control or Nix will not see them.</p> +<h1 id="secrets-with-sops">Secrets with Sops</h1> +<p>In order to set up Tailscale, we will use a pre-auth key. This allows us to connect to our server without interaction. However, we must hide this key, or other people could join our Tailscale network, which could obviously have dangerous consequences.</p> +<p>There are 2 well-known solutions : agenix and sops-nix. I’ve chosen sops for no particular reason. +The first step will be to add it to our flake. See, we already get a use for it!</p> +<h2 id="importing-sops-nix">Importing <code>sops-nix</code></h2> +<p>Let’s change our <code>inputs</code>:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">inputs</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops-nix</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:mic92/sops-nix<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">inputs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">nixpkgs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">follows</span> <span class="z-keyword z-operator z-bind z-nix">=</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>nixpkgs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<h3 id="follows"><code>Follows</code></h3> +<p>What’s up with this <code>follows</code>? <code>sops-nix</code> already depends on <code>nixpkgs</code>, but it might use a different revision than ours. Making it use our own has several advantages:</p> +<ul> +<li>improve consistency</li> +<li>reduce the number of evaluations required</li> +</ul> +<p>And how do we know if a package has inputs that need to be redirected? That’s the neat thing, we don’t. Either we have to look at the upstream <code>flake.nix</code>, or we can call <code>nix flake info</code> and get a graph like so:</p> +<pre class="z-code"><code><span class="z-text z-plain">Resolved URL: git+file:///etc/nixos +</span><span class="z-text z-plain">Locked URL: git+file:///etc/nixos +</span><span class="z-text z-plain">Path: /Nix/store/4b14z6ki7av3kid69sp5vgf50wzd3a73-source +</span><span class="z-text z-plain">Last modified: 2023-04-17 14:04:13 +</span><span class="z-text z-plain">Inputs: +</span><span class="z-text z-plain">├───impermanence: github:Nix-community/impermanence/6138e +</span><span class="z-text z-plain">├───nixpkgs: github:NixOS/nixpkgs/39fa0 +</span><span class="z-text z-plain">└───sops-Nix: github:mic92/sops-nix/de651 +</span><span class="z-text z-plain"> ├───nixpkgs follows input &#39;nixpkgs&#39; +</span><span class="z-text z-plain"> └───nixpkgs-stable: github:NixOS/nixpkgs/1040c +</span></code></pre> +<p>We can notice <code>sops-nix</code> also has a <code>nixpkgs-stable</code> input, that we might as well redirect.</p> +<h2 id="generating-a-key">Generating a key</h2> +<p><code>sops-nix</code> works by encrypting our secrets with private keys. +We thus need to provide it with the keys we will use. We can generate an <code>age</code> key, or get one from our <code>SSH</code> host key. +Each secrets group can have different allowed keys, so that one user cannot access another’s secrets. +I will use the SSH host key for my server:</p> +<pre class="z-code"><code><span class="z-text z-plain">$ nix-shell -p ssh-to-age --run &#39;cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age&#39; +</span><span class="z-text z-plain">age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh +</span></code></pre> +<p>We now have to write <code>.sops.yaml</code> file in order to configure which keys can access which secrets.</p> +<pre data-lang="yaml" class="language-yaml z-code"><code class="language-yaml" data-lang="yaml"><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">keys</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-meta z-property z-yaml"><span class="z-keyword z-control z-property z-anchor z-yaml"><span class="z-punctuation z-definition z-anchor z-yaml">&amp;</span></span><span class="z-entity z-name z-other z-anchor z-yaml">horus</span></span> <span class="z-string z-unquoted z-plain z-out z-yaml">age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh</span> +</span><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">creation_rules</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">path_regex</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">hosts/horus/secrets.yaml$</span> +</span><span class="z-source z-yaml"> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">key_groups</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">age</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-keyword z-control z-flow z-alias z-yaml"><span class="z-punctuation z-definition z-alias z-yaml">*</span></span><span class="z-variable z-other z-alias z-yaml">horus</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">path_regex</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">hosts/common/secrets.yaml$</span> +</span><span class="z-source z-yaml"> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">key_groups</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">age</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-keyword z-control z-flow z-alias z-yaml"><span class="z-punctuation z-definition z-alias z-yaml">*</span></span><span class="z-variable z-other z-alias z-yaml">horus</span> +</span></code></pre> +<p>That’s it for decryption. However, we need to write secrets too. For that, we can get the corresponding private key:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nix-shell</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> ssh-to-age<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>run</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key | install -D -m 400 /dev/stdin ~/.config/sops/age/keys.txt<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span></code></pre> +<p>That <code>install</code> bit is here to create the directory if it doesn’t exist and set the right permissions.</p> +<blockquote> +<p>Isn’t this insecure? The key is not password-locked.</p> +</blockquote> +<p>Indeed, if someone has access to our user account, they can read that key and decrypt the secrets. However, we can probably assume our user already has access to the local secrets, so it doesn’t matter much. Our goal is to be able to put these secrets on a public GitHub, not to protect them locally.</p> +<h2 id="configuring-sops-nix">Configuring <code>sops-nix</code></h2> +<p>Our last step is to configure <code>sops</code>. +We’re going to get fancy here, as I’m <del>stealing</del> borrowing a module from Misterio’s config. In the future, this will often happen, as his config happens to be a great resource. Let’s have a look at <code>sops.nix</code>:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">sops-nix</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">lib</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">config</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">isEd25519</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-function z-4 z-nix">k</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">k</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">type</span> <span class="z-keyword z-operator z-nix">==</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>ed25519<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">getKeyPath</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-function z-4 z-nix">k</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">k</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">path</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">keys</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">filter</span> <span class="z-variable z-parameter z-name z-nix">isEd25519</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">openssh</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">hostKeys</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">in</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">sops-nix</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sops</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">age</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">sshKeyPaths</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">map</span> <span class="z-variable z-parameter z-name z-nix">getKeyPath</span> <span class="z-variable z-parameter z-name z-nix">keys</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>This looks complicated, but it is not. First, we are declaring some functions in the <code>let</code> block.</p> +<ul> +<li><code>isEd25519</code> simply tells if an SSH key uses <code>ed25519</code></li> +<li><code>getKeyPath</code> gets the path of an SSH key</li> +<li><code>keys</code> is the list of <code>ed25519</code> keys, taken from <code>openssh</code></li> +</ul> +<p>Then we import <code>sops</code>. Finally, we give it the keys we collected earlier. This avoids hardcoding keys, which is great!</p> +<p>We can now import this module in our config:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">imports</span> <span class="z-invalid z-illegal">=</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">impermanence</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModule</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">./hardware-configuration.Nix</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">../../modules/sops.nix</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p><code>sops-nix</code> is now ready to use. Do not forget to rebuild the config.</p> +<h2 id="our-first-secret">Our first secret</h2> +<p>Let’s write a secret:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> hosts/horus</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nix-shell</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> sops<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>run</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>sops hosts/horus/secrets.yaml<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span></code></pre> +<p>An editor should open. We can now write secrets, using yaml. Once we’re done, we can save the file. Example content:</p> +<pre data-lang="yaml" class="language-yaml z-code"><code class="language-yaml" data-lang="yaml"><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">tailscale_key</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">e2b6595884993e001da58d2995af65df489582a702e3a2f3</span> +</span></code></pre> +<p>We now have to tell <code>sops</code> this secret exists. So we declare it somewhere in our configuration:</p> +<pre class="z-code"><code><span class="z-text z-plain">sops.secrets.tailscale_key = { +</span><span class="z-text z-plain"> sopsFile = ./secrets.yaml; +</span><span class="z-text z-plain">}; +</span></code></pre> +<p>And that’s all! To use it, we simply have to use <code>config.sops.secrets.tailscale_key.path</code> where we need it. Beware that this will not give you the secret, but a path to a file containing the raw secret, for security reasons. Otherwise, the secret would be in the Nix store, and thus accessible to any user on the system.</p> +<h2 id="note-adding-a-new-host">Note: adding a new host</h2> +<p>If you ever need to add a new host, you will need to update your secrets with <code>sops updatekeys your_secret</code>. This command has to be on a system with already authorized keys.</p> +<h1 id="tailscale">Tailscale</h1> +<p>We can finally get to a real feature, setting up Tailscale. +For those of you who haven’t heard of it, Tailscale is a private meshed network, allowing you to connect to your machines privately and securely through Wireguard, a VPN protocol, without exposing them to the world. +This means being able to close port 22, while still being able to SSH into your computer.</p> +<p>Furthermore, Tailscale offers some additional features, such as a fancy file sending tool or hole punching, which allows you to connect to your computer even if it is behind a NAT. I won’t go into details here, but you can read more about it on <a rel="noopener" target="_blank" href="https://tailscale.com/">their website</a>.</p> +<p>I’ve chosen to write a full-fledged NixOS module for Tailscale, as it is a service that needs to be configured and started. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!</p> +<h2 id="boilerplate-for-nixos-modules">Boilerplate for NixOS modules</h2> +<p>We’re going to write a module, so we need to create a directory for it:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> modules/nixos</span> +</span></code></pre> +<p>Inside, we’ll need a <code>default.nix</code> file:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale-autoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">import</span> <span class="z-string z-unquoted z-path z-nix">./tailscale-autoconnect.nix</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>By convention, this file is automatically imported when you import a directory. Then, in our <code>flake.nix</code>, we can import our module:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">outputs</span> <span class="z-invalid z-illegal">=</span> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixosModules</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">import</span> <span class="z-string z-unquoted z-path z-nix">./modules/nixos</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>As before, the <code>nixosModules</code> attribute has a special meaning.</p> +<p>Finally, we have to import the module we’re writing in our configuration:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">imports</span> <span class="z-invalid z-illegal">=</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">outputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale-autoconnect</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<h2 id="writing-the-module">Writing the module</h2> +<p>We’re going to write a module to start Tailscale and connect to it automatically. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!</p> +<p>First, we need to create a <code>tailscale-autoconnect.nix</code> file in our <code>modules/nixos</code> directory. We’ll start with the boilerplate:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">config</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">lib</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">pkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-invalid z-illegal z-reserved z-nix">with</span> <span class="z-variable z-parameter z-function z-maybe z-nix">lib</span><span class="z-invalid z-illegal">;</span> <span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">cfg</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-keyword z-other z-nix">in</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">options</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscaleAutoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkEnableOption</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscaleAutoconnect<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">config</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkIf</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">enable</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"><span class="z-invalid z-illegal">}</span> +</span></code></pre> +<p>This is the basic structure of a module. We declare an option, and then we use it to conditionally change the configuration. So:</p> +<ul> +<li>What we write in <code>options</code> is the option declaration</li> +<li>What we write in <code>config</code> is the consequence of the option being enabled, the configuration change</li> +</ul> +<p>Let’s declare all the options first.</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">options</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkEnableOption</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscaleAutoconnect<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">authkeyFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The authkey to use for authentication with Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">loginServer</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The login server to use for authentication with Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">advertiseExitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">bool</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Whether to advertise this node as an exit node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The exit node to use for this node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">bool</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Whether to allow LAN access to this node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This looks like a lot of code, but we’re simply declaring options. We need to give them a type, and we can also give a default value and a description. +Now, the actually useful code:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">config</span> <span class="z-invalid z-illegal">=</span> <span class="z-variable z-parameter z-name z-nix">mkIf</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">enable</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertions</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">authkeyFile</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>authkeyFile must be set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-nix">-&gt;</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>exitNodeAllowLanAccess must be false if exitNode is not set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span> <span class="z-keyword z-operator z-nix">-&gt;</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">==</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span><span class="z-entity z-other z-attribute-name z-multipart z-nix">d</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>advertiseExitNode must be false if exitNode is set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">systemd</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale-autoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Automatic connection to Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># make sure tailscale is running before trying to connect to tailscale</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">after</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>network-pre.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wants</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>network-pre.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wantedBy</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>multi-user.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">serviceConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">Type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>oneshot<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">script</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-keyword z-other z-nix">with</span> <span class="z-variable z-parameter z-name z-nix">pkgs</span>; <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # wait for tailscaled to settle +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> sleep 2 +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # check if we are already authenticated to tailscale +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> status=&quot;$(<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale status -json | <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">jq</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/jq -r .BackendState)&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # if status is not null, then we are already authenticated +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;tailscale status: $status&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> if [ &quot;$status&quot; != &quot;NeedsLogin&quot; ]; then +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> exit 0 +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> fi +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # otherwise authenticate with tailscale +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # timeout after 10 seconds to avoid hanging the boot process +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">coreutils</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/timeout 10 <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale up \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--login-server=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> --authkey=$(cat &quot;<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">authkeyFile</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>&quot;) +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # we have to proceed in two steps because some options are only available +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # after authentication +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">coreutils</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/timeout 10 <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale up \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--login-server=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--advertise-exit-node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--exit-node=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNodeAllowLanAccess</span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--exit-node-allow-lan-access<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">networking</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">firewall</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">trustedInterfaces</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale0<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">allowedUDPPorts</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">port</span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">useRoutingFeatures</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-keyword z-other z-nix">if</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span> <span class="z-keyword z-other z-nix">th</span><span class="z-keyword z-other z-nix">en</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>server<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-keyword z-other z-nix">el</span><span class="z-keyword z-other z-nix">se</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>client<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>First, the assertions. They’re here to make sure that the user doesn’t make any mistake when configuring the module. For example, a user cannot both advertise an exit node and set an exit node. +Then, the service. We’re using systemd to run a script that will connect to Tailscale. The <code>after</code>, <code>wants</code> and <code>wantedBy</code> options make the script run after the network is up and after Tailscale daemon is started. The <code>Type</code> option is here to make sure that the script is run only once. The script itself is a bit long, but it’s just a bunch of bash commands. It’s pretty straightforward. First, we wait for the Tailscale daemon to settle. Then, we check if we’re already authenticated. If we are, we exit. Otherwise, we authenticate. Finally, we connect to Tailscale. We have to do it in two steps because some options are only available after authentication.</p> +<p>At the end, we configure the firewall to allow Tailscale traffic, and we enable the Tailscale service.</p> +<p>Now, an example of how to use this module:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">outputs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">...</span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">outputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale-autoconnect</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscaleAutoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">authkeyFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sops</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">secrets</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale_key</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">path</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">loginServer</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://login.tailscale.com<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>some-node-id<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">secrets</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale_key</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sopsFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-unquoted z-path z-nix">./secrets.yaml</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">environment</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">persistence</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">directories</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/var/lib/tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>The module is imported and configured. We also use the <code>sops</code> secret we created earlier. Finally, we persist the Tailscale state, so that we don’t have to authenticate again after a reboot. This is especially important if the authkey can expire.</p> +<hr /> +<p>That’s all for this post. Thanks for reading! If you have any question, feel free to ask in the comments. The final code can be found <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/tree/2-tailscale">here</a>.</p> +<!-- +# Our first service : a simple file server + +Our first service will be a basic web server. For that, we will use nginx. `nginx` is, obviously, a web server. However, it is often also used as a reverse proxy, forwarding the requests it gets to the internal services. `nginx.Nix`: +```nix +{ + services.nginx = { + enable = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + clientMaxBodySize = "300m"; + }; + networking.firewall.allowedTCPPorts = [ 80 443 ]; +} +``` +`web-server.Nix`: +```nix +{ + services.nginx.virtualHosts."e1.oze.li" = { + addSSL = true; + enableACME = true; + root = "/var/www/files"; + }; + + environment.persistence = { + "/persist".directories = [ "/var/www/files" ]; + }; +} +``` +We are enabling the `nginx` service. For now, it only serves `e1.oze.li`, our web server. You can notice the `addSSL` parameter, together with `enableACME`: thanks to them, we are getting a HTTPS certificate for free, provided by LetsEncrypt. We need to accept its terms. `acme.Nix`: +```nix + # Enable acme for usage with nginx vhosts + security.acme = { + defaults.email = "some@email.com"; + acceptTerms = true; + }; + + environment.persistence = { + "/persist".directories = [ "/var/lib/acme" ]; + }; +} +``` +That's all! That is so simple and straightforward. I couldn't imagine myself using only Docker now. +--> + + + + + NixOS as a server, part 1: Impermanence + 2023-02-20T00:00:00+00:00 + 2023-02-20T00:00:00+00:00 + + + + + Unknown + + + + + + https://guekka.github.io/nixos-server-1/ + + <p>A few months ago, I woke up with the idea of hosting my own services. I went through a lot of tries. LXC, Debian, Alpine, (rootless or not) Docker, podman, portainer…</p> +<p>But no solution felt perfect. Until I decided to have a try at hosting using NixOS.</p> +<p>I’m going to assume you know about NixOS and have some prior experience. However, for a small summary: NixOS is a Linux distribution revolving around the Nix package manager. Its main advantage is having a reproducible environment through a declarative configuration. This means that you can copy an entire computer configuration easily: if it works somewhere, it will work anywhere.</p> +<p>My main focus point is reproducibility, so that’s why we’ll start with configuring <em>impermanence</em>.</p> +<h2 id="what-s-impermanence">What’s impermanence?</h2> +<p>Originally, a philosophic concept. But in our case, impermanence means erasing the <code>/</code> drive at each reboot. You read that right, erasing <em>almost</em> everything at each reboot. This part stands on the shoulders of those who did it before me:</p> +<ul> +<li><a rel="noopener" target="_blank" href="https://grahamc.com/blog/erase-your-darlings">Erase your darlings: immutable infrastructure for mutable systems - Graham Christensen</a></li> +<li><a rel="noopener" target="_blank" href="https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/">NixOS ❄: tmpfs as root</a></li> +<li><a rel="noopener" target="_blank" href="https://mt-caret.github.io/blog/posts/2020-06-29-optin-state.html#fn6">Encypted Btrfs Root with Opt-in State on NixOS</a></li> +<li><a rel="noopener" target="_blank" href="https://xeiaso.net/blog/paranoid-nixos-2021-07-18">Paranoid NixOS Setup - Xe Iaso</a></li> +<li><a rel="noopener" target="_blank" href="https://github.com/nix-community/impermanence">nix-community/impermanence: NixOS module</a></li> +</ul> +<p>The goal is the following: over years, configuration files accumulate. Sometimes editing <code>/etc</code> is required, because of a bug or an obscure configuration. NixOS allows us to avoid this manual file editing, but it does not <em>force</em> us to do so. We can still have a lot of important state, breaking the reproducibility promise.</p> +<p>So what can we do instead? Erase everything, at each reboot. This way, we’ll be sure the only source of truth is our configuration.</p> +<h2 id="installing-the-system">Installing the system</h2> +<p>I’m currently using a <a rel="noopener" target="_blank" href="https://github.com/quickemu-project/quickemu">quickemu</a> VM. This is not a recommenced setup and is only done for testing. Configuration file:</p> +<pre data-lang="conf" class="language-conf z-code"><code class="language-conf" data-lang="conf"><span class="z-source z-genconfig"><span class="z-meta z-comment z-genconfig"><span class="z-comment z-line z-number-sign z-genconfig">#!/usr/bin/quickemu --vm +</span></span></span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">guest_os</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;linux&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">disk_img</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;nixos-22.11-minimal/disk.qcow2&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">iso</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;nixos-22.11-minimal/latest-nixos-minimal-x86_64-linux.iso&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">disk_size</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;50G&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">ram</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;4G&quot;</span> +</span></code></pre> +<p>Let’s first format it:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">DISK</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell">/dev/vda</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mklabel gpt</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart ESP fat32 1MiB 1GiB</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> set 1 boot on</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkfs.vfat</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>1</span> +</span></code></pre> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart Swap linux-swap 1GiB 9GiB</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkswap</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>L</span> Swap <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>2</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">swapon</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>2</span> +</span></code></pre> +<blockquote> +<p>Using swap in 2023!?</p> +</blockquote> +<p><a rel="noopener" target="_blank" href="https://chrisdown.name/2018/01/02/in-defence-of-swap.html">Yes</a>.</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart primary 9GiB 100<span class="z-meta z-group z-expansion z-job z-shell"><span class="z-punctuation z-definition z-variable z-job z-shell">%</span></span></span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkfs.btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>L</span> Butter <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3</span> +</span></code></pre> +<p>While the <code>impermanence</code> module recommends using <code>tmpfs</code> for <code>/</code>, I chose to use <code>btrfs</code>: I do not have RAM to waste. Furthermore, this will allow us to use a nice script we’ll see later on.</p> +<p>Let’s create <code>btrfs</code> subvolumes:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/root</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/home</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/nix</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/persist</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/log</span> +</span></code></pre> +<p>And now, the crucial part:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume snapshot<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>r</span> /mnt/root /mnt/root-blank</span> +</span></code></pre> +<p>We just took a snapshot of that empty volume. We will restore it at each reboot. +We can now mount the subvolumes and let <code>nixos-generate-config</code> do its job</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=root,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/home</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=home,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/home</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/nix</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=nix,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/nix</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/persist</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=persist,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/persist</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> /mnt/var/log</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=log,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/var/log</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/boot</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>1 /mnt/boot</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nixos-generate-config</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>root</span> /mnt</span> +</span></code></pre> +<p>Lastly, we only have to edit the generated configuration files at <code>/mnt/etc/nixos</code>.</p> +<p>My final configuration is available <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/tree/1-impermanence">here</a>. You can follow all the steps by looking at the <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/commits/1-impermanence">commits</a>.</p> +<h2 id="configuring-the-system">Configuring the system</h2> +<ul> +<li>Checking that we have the correct mount options in <code>/mnt/etc/nixos/hardware-configuration.nix</code>.</li> +</ul> +<p>I’ve added <code>&quot;compress=zstd&quot; &quot;noatime&quot;</code> to all filesystems. We also need to add <code>neededForBoot</code> to <code>/var/log</code> and <code>/persist</code>.</p> +<ul> +<li>Replacing default values in <code>configuration.nix</code></li> +</ul> +<p>I’ve enabled <code>networkmanager</code>, removed most suggested options and enabled <code>system.copySystemConfiguration</code>.</p> +<p>This last option copies the current configuration to <code>/run/current_system/configuration.nix</code>. You should not rely on it: keep your configuration in a git repository. But it can serve as some kind of last chance.</p> +<ul> +<li>Declaring a user, including ssh</li> +</ul> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">mutableUsers</span> <span class="z-invalid z-illegal">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">user</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">isNormalUser</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">extraGroups</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>wheel<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">openssh</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">authorizedKeys</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">keys</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICWVNch9BcjkMqS/Xwep+GN4HwqyRIjr3Cuw7mHpqsKr nixos<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># passwordFile needs to be in a volume marked with `neededForBoot = true`</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">passwordFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist/passwords/user<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>Here we have completely disabled imperative user modification. This does not matter much, as imperative changes would be erased anyway at start. +We thus need to provide a password. We’re using <code>passwordFile</code> for that: a path to a file containing the hashed password.</p> +<p>Here’s how to generate that file: <code>sudo mkpasswd -m sha-512 &quot;hunter2&quot; &gt; /mnt/persist/passwords/user</code>.</p> +<p>The SSH key was generated using `ssh-keygen -t ed25519 -C “nixos”.</p> +<ul> +<li>Enabling openSSH +We’re going to use Xe’s configuration:</li> +</ul> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">openssh</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">passwordAuthentication</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">allowSFTP</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># Don&#39;t set this if you need sftp</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">challengeResponseAuthentication</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">extraConfig</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowTcpForwarding yes +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> X11Forwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowAgentForwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowStreamLocalForwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AuthenticationMethods publickey +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This reduces attack surface, for example by disabling stream-local forwarding and disabling password authentification.</p> +<hr /> +<p>This will be enough for now. Let’s install the system before going to the next step: <code>sudo nixos-install --root /mnt &amp;&amp; sudo reboot</code>. You should be able to connect by SSH using the previously defined key, or login using the password you defined in <code>/persist/passwords/user</code>.</p> +<h2 id="configuring-impermanence">Configuring impermanence</h2> +<p>We’ve created our volumes, we’ve configured the system… But I promised we would reset our system at each reboot. Let’s do that now! +We’re going to use the following script, credit of mt-caret. Do not forget to replace <code>vda3</code> with your data partition.</p> +<p><strong>16/07/23 update</strong>: it was brought to my attention that <a rel="noopener" target="_blank" href="https://discourse.nixos.org/t/what-does-impermanence-add-over-built-in-functionality/27939/16">postDeviceCommands can cause data loss</a>. +While I did not experience any issue, I have updated the script to use a safer alternative.</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">boot</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">initrd</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">supportedFilesystems</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>btrfs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">systemd</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">restore-root</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Rollback btrfs rootfs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wantedBy</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>initrd.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">requires</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>dev-vda3<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">after</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>dev-vda3<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># for luks</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>systemd-cryptsetup@<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">networking</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">hostName</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">before</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>sysroot.mount<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">unitConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">DefaultDependencies</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>no<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">serviceConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">Type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>oneshot<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">script</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> mkdir -p /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # We first mount the btrfs root to /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # so we can manipulate btrfs subvolumes. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> mount -o subvol=/ /dev/vda3 /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # While we&#39;re tempted to just delete /root and create +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # a new snapshot from /root-blank, /root is already +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # populated at this point with a number of subvolumes, +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # which makes `btrfs subvolume delete` fail. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # So, we remove them first. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # /root contains subvolumes: +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # - /root/var/lib/portables +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # - /root/var/lib/machines +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # I suspect these are related to systemd-nspawn, but +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # since I don&#39;t use it I&#39;m not 100% sure. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # Anyhow, deleting these subvolumes hasn&#39;t resulted +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # in any issues so far, except for fairly +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # benign-looking errors from systemd-tmpfiles. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume list -o /mnt/root | +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> cut -f9 -d&#39; &#39; | +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> while read subvolume; do +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;deleting /$subvolume subvolume...&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume delete &quot;/mnt/$subvolume&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> done &amp;&amp; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;deleting /root subvolume...&quot; &amp;&amp; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume delete /mnt/root +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;restoring blank /root subvolume...&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume snapshot /mnt/root-blank /mnt/root +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # Once we&#39;re done rolling back to a blank snapshot, +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # we can unmount /mnt and continue on the boot process. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> umount /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>We can then specify the files we want to keep.</p> +<p>But which files do we want to keep? Let’s find out. Thanks to another useful script of mt-caret, we can list the differences between our current <code>/</code> and the blank state:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell">!/usr/bin/env bash</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> fs-diff.sh</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-support z-function z-set z-shell">set</span></span><span class="z-meta z-function-call z-arguments z-shell"> -euo pipefail</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">OLD_TRANSID</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-meta z-group z-expansion z-command z-parens z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> btrfs subvolume find-new /mnt/root-blank 9999999</span><span class="z-punctuation z-section z-parens z-end z-shell">)</span></span></span> +</span><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">OLD_TRANSID</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-expansion z-parameter z-begin z-shell">{</span></span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-variable z-other z-readwrite z-shell">OLD_TRANSID<span class="z-keyword z-operator z-expansion z-shell">#</span></span></span><span class="z-meta z-group z-expansion z-parameter z-shell">transid marker was </span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-section z-expansion z-parameter z-end z-shell">}</span></span></span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> btrfs subvolume find-new <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>/mnt/root<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">OLD_TRANSID</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sed</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&#39;</span>$d<span class="z-punctuation z-definition z-string z-end z-shell">&#39;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">cut</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>f17-</span><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>d</span><span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&#39;</span> <span class="z-punctuation z-definition z-string z-end z-shell">&#39;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sort</span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">uniq</span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-loop z-while z-shell">while</span> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-read z-shell">read</span></span><span class="z-meta z-function-call z-arguments z-shell"> path</span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-loop z-do z-shell">do</span> +</span><span class="z-source z-shell z-bash"> <span class="z-variable z-other z-readwrite z-assignment z-shell">path</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>/<span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-if z-shell">if</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell">-</span>L</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-conditional z-then z-shell">then</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-colon z-shell">:</span></span> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> The path is a symbolic link, so is probably handled by NixOS already</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-elseif z-shell">elif</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell">-</span>d</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-conditional z-then z-shell">then</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-colon z-shell">:</span></span> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> The path is a directory, ignore</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-else z-shell">else</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-echo z-shell">echo</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-end z-shell">fi</span> +</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-loop z-end z-shell">done</span> +</span></code></pre> +<p>Used like this:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /mnt</span> <span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mount<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=/ /dev/vda3 /mnt</span> <span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">./fs-diff.sh</span></span> +</span></code></pre> +<p>Here’s the result of mine:</p> +<pre class="z-code"><code><span class="z-text z-plain">/etc/.clean +</span><span class="z-text z-plain">/etc/group +</span><span class="z-text z-plain">/etc/machine-id +</span><span class="z-text z-plain">/etc/nixos/configuration.nix +</span><span class="z-text z-plain">/etc/nixos/hardware-configuration.nix +</span><span class="z-text z-plain">/etc/passwd +</span><span class="z-text z-plain">/etc/resolv.conf +</span><span class="z-text z-plain">/etc/shadow +</span><span class="z-text z-plain">/etc/ssh/authorized_keys.d/user +</span><span class="z-text z-plain">/etc/ssh/ssh_host_ed25519_key +</span><span class="z-text z-plain">/etc/ssh/ssh_host_ed25519_key.pub +</span><span class="z-text z-plain">/etc/ssh/ssh_host_rsa_key +</span><span class="z-text z-plain">/etc/ssh/ssh_host_rsa_key.pub +</span><span class="z-text z-plain">/etc/subgid +</span><span class="z-text z-plain">/etc/subuid +</span><span class="z-text z-plain">/etc/sudoers +</span><span class="z-text z-plain">/etc/.updated +</span><span class="z-text z-plain">/root/.nix-channels +</span><span class="z-text z-plain">/root/.nix-defexpr/channels +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s8.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/NetworkManager-intern.conf +</span><span class="z-text z-plain">/var/lib/NetworkManager/secret_key +</span><span class="z-text z-plain">/var/lib/NetworkManager/timestamps +</span><span class="z-text z-plain">/var/lib/nixos/auto-subuid-map +</span><span class="z-text z-plain">/var/lib/nixos/declarative-groups +</span><span class="z-text z-plain">/var/lib/nixos/declarative-users +</span><span class="z-text z-plain">/var/lib/nixos/gid-map +</span><span class="z-text z-plain">/var/lib/nixos/uid-map +</span><span class="z-text z-plain">/var/lib/systemd/catalog/database +</span><span class="z-text z-plain">/var/lib/systemd/random-seed +</span><span class="z-text z-plain">/var/.updated +</span></code></pre> +<p>That’s not too bad!</p> +<p>Out of these, there’s almost nothing I want to preserve.</p> +<p>Let’s make use of the <code>impermanence</code> module. We need to download it:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">impermanence</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">fetchTarball</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://github.com/nix-community/impermanence/archive/master.tar.gz<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">in</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"><span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">impermanence</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/nixos.nix<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-unquoted z-path z-nix">./hardware-configuration.nix</span> <span class="z-punctuation z-definition z-list z-nix">]</span> +</span><span class="z-source z-nix"><span class="z-keyword z-operator z-nix">//</span> <span class="z-variable z-parameter z-name z-nix">the</span> <span class="z-variable z-parameter z-name z-nix">whole</span> <span class="z-variable z-parameter z-name z-nix">configuration</span> +</span><span class="z-source z-nix"><span class="z-invalid z-illegal">}</span> +</span></code></pre> +<p>And now, we can just tell it the files and directories that we want:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># configure impermanence</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">environment</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">persistence</span><span class="z-keyword z-operator z-nix">.</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">directories</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/nixos<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">files</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/machine-id<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_ed25519_key<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_ed25519_key.pub<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_rsa_key<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_rsa_key.pub<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-invalid z-illegal">}</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">security</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sudo</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">extraConfig</span> <span class="z-invalid z-illegal">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # rollback results in sudo lectures after each reboot +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> Defaults lecture = never +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>What an ergonomic interface.</p> +<blockquote> +<p>Wait, did you just say Nix was ergonomic?</p> +</blockquote> +<p>Well, yes. Sometimes.</p> +<hr /> +<p>I have not saved my network manager configuration, but you may need to.</p> +<p>When new files are set to be preserved, <strong>it is necessary to copy them manually to <code>/persist</code></strong>:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> nixos-rebuild boot</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /persist/etc</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>r</span> <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/nixos</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/machine-id</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /persist/etc/ssh</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_ed25519_key</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_ed25519_key.pub</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_rsa_key</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_rsa_key.pub</span> +</span></code></pre> +<p>Now, if we reboot and list files again:</p> +<pre class="z-code"><code><span class="z-text z-plain">/etc/.clean +</span><span class="z-text z-plain">/etc/group +</span><span class="z-text z-plain">/etc/passwd +</span><span class="z-text z-plain">/etc/resolv.conf +</span><span class="z-text z-plain">/etc/shadow +</span><span class="z-text z-plain">/etc/ssh/authorized_keys.d/user +</span><span class="z-text z-plain">/etc/subgid +</span><span class="z-text z-plain">/etc/subuid +</span><span class="z-text z-plain">/etc/sudoers +</span><span class="z-text z-plain">/etc/.updated +</span><span class="z-text z-plain">/root/.nix-channels +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/NetworkManager-intern.conf +</span><span class="z-text z-plain">/var/lib/NetworkManager/secret_key +</span><span class="z-text z-plain">/var/lib/NetworkManager/timestamps +</span><span class="z-text z-plain">/var/lib/nixos/auto-subuid-map +</span><span class="z-text z-plain">/var/lib/nixos/declarative-groups +</span><span class="z-text z-plain">/var/lib/nixos/declarative-users +</span><span class="z-text z-plain">/var/lib/nixos/gid-map +</span><span class="z-text z-plain">/var/lib/nixos/uid-map +</span><span class="z-text z-plain">/var/lib/systemd/catalog/database +</span><span class="z-text z-plain">/var/lib/systemd/random-seed +</span><span class="z-text z-plain">/var/.updated +</span></code></pre> +<p>Success! The files we persisted are no longer showing up.</p> +<h3 id="what-about-our-home-directory">What about our home directory?</h3> +<p>It is possible to setup the impermanence module for our home directory. However, I did not want to go through <code>home-manager</code> installation. Furthermore, a home directory is meant to be stateful.</p> +<p>In our case, we are creating a server, so it would still make sense to configure it. If you are interested, have a look at <a rel="noopener" target="_blank" href="https://elis.nu/blog/2020/06/nixos-tmpfs-as-home/">tmpfs at home</a>.</p> +<h2 id="next-steps">Next steps</h2> +<p>In the next part, we will make our server more secure by making it only available through Tailscale. We will also setup our first service.</p> +<hr /> +<p>I hope you’ve enjoyed this article! Thanks for reading to the end!</p> + + + + diff --git a/tags/nix/index.html b/tags/nix/index.html new file mode 100644 index 0000000..59810b6 --- /dev/null +++ b/tags/nix/index.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + nix tag | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + +
    + + + diff --git a/tags/self-hosting/atom.xml b/tags/self-hosting/atom.xml new file mode 100644 index 0000000..e37be5b --- /dev/null +++ b/tags/self-hosting/atom.xml @@ -0,0 +1,786 @@ + + + Guekka's blog - self-hosting + C++, Nix, Linux, Self-hosting, and more. + + + Zola + 2023-05-17T00:00:00+00:00 + https://guekka.github.io/tags/self-hosting/atom.xml + + NixOS as a server, part 2: Flake, tailscale + 2023-05-17T00:00:00+00:00 + 2023-05-17T00:00:00+00:00 + + + + + Unknown + + + + + + https://guekka.github.io/nixos-server-2/ + + <p>In the <a rel="noopener" target="_blank" href="https://guekka.github.io/nixos-server-1/">previous part</a>, we configured our NixOS server to use impermanence. I have made a few changes since, most notably moving to a proper VM in Proxmox.</p> +<p>The following instructions might lack some details, but you can follow <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/commits/2-tailscale">the GitHub repo</a> to see the full code.</p> +<h1 id="moving-to-flakes">Moving to flakes</h1> +<blockquote> +<p>If you already know about flakes, you can safely ignore this part.</p> +</blockquote> +<p>Have you heard about Nix flakes? If you have been in the Nix ecosystem for more than a few days, most likely. They’re the shiny new way to write Nix code, still experimental but used everywhere. +Their main advantage over traditional Nix is <em>purity</em>, mainly with their defined <code>inputs</code> and <code>outputs</code>. </p> +<p>Remember when I told you Nix was reproducible? It was a lie. Let me explain myself: when writing Nix code, we always have some kind of input. For example, <code>nixpkgs</code> will be required almost all the time. There are two ways to obtain it.</p> +<ul> +<li>fetch it: <code>import builtins.fetchTarball &quot;https://github.com/nixos/nixpkgs/archive/nixos-22.11.tar.gz&quot;;</code></li> +<li>or more commonly, use <em>channels</em>: <code>import &lt;nixpkgs&gt; {}</code></li> +</ul> +<p>This second way uses a globally-defined configuration, which can change externally to our Nix files. We thus lose complete reproducibility. Instead, flakes allow us to avoid channels by specifying inputs alongside Nix configuration, as well as blocking some actions that could hinder reproducibility.</p> +<p>For a more in depth introduction, have a look at <a rel="noopener" target="_blank" href="https://nixos.wiki/wiki/Flakes#See_also">the wiki</a>.</p> +<p>Now, why do we want to migrate to flakes? We do not have external requirements, do we? +Well, yes, we do. Apart from the obvious <code>nixpkgs</code> dependency, which is configured system-wide, the impermanence module is being imported:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">impermanence</span> <span class="z-invalid z-illegal">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">fetchTarball</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://github.com/Nix-community/impermanence/archive/master.tar.gz<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This <code>fetchTarball</code> call is bad, by the way, as we do not specify the expected hash. We could be a victim of a man-in-the-middle attack and not notice it.</p> +<p>Now that I intend to add more modules, and possibly use the <code>unstable</code> channel, it is better to migrate. Let’s see what our entry point would look like:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># what is consumed (previously provided by channels and fetchTarball)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">inputs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixpkgs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:NixOS/nixpkgs/nixos-22.11<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># (1)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">impermanence</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:Nix-community/impermanence<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># what will be produced (i.e. the build)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">outputs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span>@<span class="z-variable z-parameter z-function z-3 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (2)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixosConfigurations</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (3)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">server</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosSystem</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> <span class="z-comment z-line z-number-sign z-nix"># (4)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">packages</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">legacyPackages</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">x86_64-linux</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># (5)</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">specialArgs</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">inputs</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># forward inputs to modules</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">modules</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">./configuration.Nix</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>That’s a lot to understand at once. Let’s study it one line at a time. +Firstly, we have to understand this file is simply describing <code>outputs</code> as a function taking <code>inputs</code>. Like in mathematics, we create the same output given the same input: a <em>pure</em> function, would say functional programmers.</p> +<p><code>(1)</code> is defining an input: we simply give it an url. That line can be translated as *Grab the <code>nixos-22.11</code> branch from the GitHub repo <code>nixpkgs</code> owned by <code>NixOS</code>.</p> +<p><code>(2)</code> is defining the <code>outputs</code> function. Most complicated things are defined using functions in Nix. It takes a <em>named attribute set</em> argument as an input. So this syntax:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">nixpkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span>@<span class="z-variable z-parameter z-function z-3 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">nixpkgs</span> +</span></code></pre> +<p>is the same as:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-function z-4 z-nix">inputs</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">inputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixpkgs</span> +</span></code></pre> +<p>In both cases, we’re accessing the <code>nixpkgs</code> property of the <code>inputs</code> set.</p> +<p>But in the first case, we don’t have to repeat <code>inputs.</code> everywhere. In JS, you would call that <em>destructuring</em>: it is just making inner elements easier to access. If you have troubles understanding the Nix syntax, I personally like <a rel="noopener" target="_blank" href="https://fasterthanli.me/series/building-a-rust-service-with-Nix/part-9">FasterThanLime article</a>.</p> +<p><code>(3)</code>: NixOS configuration have to be placed specifically in the <code>nixosConfigurations</code> set.</p> +<p><code>(4)</code> is the place where we actually define the system. We call the <code>nixosSystem</code> function and pass it some arguments. Yes, the whole system is an <code>output</code> too!</p> +<p><code>(5)</code>: we give the packages instance to our system. In our case, we are passing the default packages, but we might want to modify them before. We also have to specify our architecture (<code>x86_64</code>).</p> +<p>That’s pretty much it. With that <code>flake.Nix</code> in <code>/etc/nixos</code>, <code>nixos-rebuild</code> will work as before. However, if you’re using git, beware that your files all need to be under version control or Nix will not see them.</p> +<h1 id="secrets-with-sops">Secrets with Sops</h1> +<p>In order to set up Tailscale, we will use a pre-auth key. This allows us to connect to our server without interaction. However, we must hide this key, or other people could join our Tailscale network, which could obviously have dangerous consequences.</p> +<p>There are 2 well-known solutions : agenix and sops-nix. I’ve chosen sops for no particular reason. +The first step will be to add it to our flake. See, we already get a use for it!</p> +<h2 id="importing-sops-nix">Importing <code>sops-nix</code></h2> +<p>Let’s change our <code>inputs</code>:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">inputs</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops-nix</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">url</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>github:mic92/sops-nix<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">inputs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">nixpkgs</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">follows</span> <span class="z-keyword z-operator z-bind z-nix">=</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>nixpkgs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<h3 id="follows"><code>Follows</code></h3> +<p>What’s up with this <code>follows</code>? <code>sops-nix</code> already depends on <code>nixpkgs</code>, but it might use a different revision than ours. Making it use our own has several advantages:</p> +<ul> +<li>improve consistency</li> +<li>reduce the number of evaluations required</li> +</ul> +<p>And how do we know if a package has inputs that need to be redirected? That’s the neat thing, we don’t. Either we have to look at the upstream <code>flake.nix</code>, or we can call <code>nix flake info</code> and get a graph like so:</p> +<pre class="z-code"><code><span class="z-text z-plain">Resolved URL: git+file:///etc/nixos +</span><span class="z-text z-plain">Locked URL: git+file:///etc/nixos +</span><span class="z-text z-plain">Path: /Nix/store/4b14z6ki7av3kid69sp5vgf50wzd3a73-source +</span><span class="z-text z-plain">Last modified: 2023-04-17 14:04:13 +</span><span class="z-text z-plain">Inputs: +</span><span class="z-text z-plain">├───impermanence: github:Nix-community/impermanence/6138e +</span><span class="z-text z-plain">├───nixpkgs: github:NixOS/nixpkgs/39fa0 +</span><span class="z-text z-plain">└───sops-Nix: github:mic92/sops-nix/de651 +</span><span class="z-text z-plain"> ├───nixpkgs follows input &#39;nixpkgs&#39; +</span><span class="z-text z-plain"> └───nixpkgs-stable: github:NixOS/nixpkgs/1040c +</span></code></pre> +<p>We can notice <code>sops-nix</code> also has a <code>nixpkgs-stable</code> input, that we might as well redirect.</p> +<h2 id="generating-a-key">Generating a key</h2> +<p><code>sops-nix</code> works by encrypting our secrets with private keys. +We thus need to provide it with the keys we will use. We can generate an <code>age</code> key, or get one from our <code>SSH</code> host key. +Each secrets group can have different allowed keys, so that one user cannot access another’s secrets. +I will use the SSH host key for my server:</p> +<pre class="z-code"><code><span class="z-text z-plain">$ nix-shell -p ssh-to-age --run &#39;cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age&#39; +</span><span class="z-text z-plain">age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh +</span></code></pre> +<p>We now have to write <code>.sops.yaml</code> file in order to configure which keys can access which secrets.</p> +<pre data-lang="yaml" class="language-yaml z-code"><code class="language-yaml" data-lang="yaml"><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">keys</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-meta z-property z-yaml"><span class="z-keyword z-control z-property z-anchor z-yaml"><span class="z-punctuation z-definition z-anchor z-yaml">&amp;</span></span><span class="z-entity z-name z-other z-anchor z-yaml">horus</span></span> <span class="z-string z-unquoted z-plain z-out z-yaml">age1dt24qetqhy2ng53fyj69yq9hg8rdsg4ep0lvvhdg69xw9v4l0asqj6xzkh</span> +</span><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">creation_rules</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">path_regex</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">hosts/horus/secrets.yaml$</span> +</span><span class="z-source z-yaml"> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">key_groups</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">age</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-keyword z-control z-flow z-alias z-yaml"><span class="z-punctuation z-definition z-alias z-yaml">*</span></span><span class="z-variable z-other z-alias z-yaml">horus</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">path_regex</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">hosts/common/secrets.yaml$</span> +</span><span class="z-source z-yaml"> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">key_groups</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">age</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> +</span><span class="z-source z-yaml"> <span class="z-punctuation z-definition z-block z-sequence z-item z-yaml">-</span> <span class="z-keyword z-control z-flow z-alias z-yaml"><span class="z-punctuation z-definition z-alias z-yaml">*</span></span><span class="z-variable z-other z-alias z-yaml">horus</span> +</span></code></pre> +<p>That’s it for decryption. However, we need to write secrets too. For that, we can get the corresponding private key:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nix-shell</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> ssh-to-age<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>run</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key | install -D -m 400 /dev/stdin ~/.config/sops/age/keys.txt<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span></code></pre> +<p>That <code>install</code> bit is here to create the directory if it doesn’t exist and set the right permissions.</p> +<blockquote> +<p>Isn’t this insecure? The key is not password-locked.</p> +</blockquote> +<p>Indeed, if someone has access to our user account, they can read that key and decrypt the secrets. However, we can probably assume our user already has access to the local secrets, so it doesn’t matter much. Our goal is to be able to put these secrets on a public GitHub, not to protect them locally.</p> +<h2 id="configuring-sops-nix">Configuring <code>sops-nix</code></h2> +<p>Our last step is to configure <code>sops</code>. +We’re going to get fancy here, as I’m <del>stealing</del> borrowing a module from Misterio’s config. In the future, this will often happen, as his config happens to be a great resource. Let’s have a look at <code>sops.nix</code>:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">sops-nix</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">lib</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">config</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">isEd25519</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-function z-4 z-nix">k</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">k</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">type</span> <span class="z-keyword z-operator z-nix">==</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>ed25519<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">getKeyPath</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-function z-4 z-nix">k</span><span class="z-punctuation z-definition z-function z-nix">:</span> <span class="z-variable z-parameter z-name z-nix">k</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">path</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">keys</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">filter</span> <span class="z-variable z-parameter z-name z-nix">isEd25519</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">openssh</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">hostKeys</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">in</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">sops-nix</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sops</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">age</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">sshKeyPaths</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">map</span> <span class="z-variable z-parameter z-name z-nix">getKeyPath</span> <span class="z-variable z-parameter z-name z-nix">keys</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>This looks complicated, but it is not. First, we are declaring some functions in the <code>let</code> block.</p> +<ul> +<li><code>isEd25519</code> simply tells if an SSH key uses <code>ed25519</code></li> +<li><code>getKeyPath</code> gets the path of an SSH key</li> +<li><code>keys</code> is the list of <code>ed25519</code> keys, taken from <code>openssh</code></li> +</ul> +<p>Then we import <code>sops</code>. Finally, we give it the keys we collected earlier. This avoids hardcoding keys, which is great!</p> +<p>We can now import this module in our config:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">imports</span> <span class="z-invalid z-illegal">=</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">impermanence</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModule</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">./hardware-configuration.Nix</span> +</span><span class="z-source z-nix"> <span class="z-string z-unquoted z-path z-nix">../../modules/sops.nix</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p><code>sops-nix</code> is now ready to use. Do not forget to rebuild the config.</p> +<h2 id="our-first-secret">Our first secret</h2> +<p>Let’s write a secret:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> hosts/horus</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nix-shell</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> sops<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>run</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>sops hosts/horus/secrets.yaml<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span></code></pre> +<p>An editor should open. We can now write secrets, using yaml. Once we’re done, we can save the file. Example content:</p> +<pre data-lang="yaml" class="language-yaml z-code"><code class="language-yaml" data-lang="yaml"><span class="z-source z-yaml"><span class="z-string z-unquoted z-plain z-out z-yaml"><span class="z-entity z-name z-tag z-yaml">tailscale_key</span></span><span class="z-punctuation z-separator z-key-value z-mapping z-yaml">:</span> <span class="z-string z-unquoted z-plain z-out z-yaml">e2b6595884993e001da58d2995af65df489582a702e3a2f3</span> +</span></code></pre> +<p>We now have to tell <code>sops</code> this secret exists. So we declare it somewhere in our configuration:</p> +<pre class="z-code"><code><span class="z-text z-plain">sops.secrets.tailscale_key = { +</span><span class="z-text z-plain"> sopsFile = ./secrets.yaml; +</span><span class="z-text z-plain">}; +</span></code></pre> +<p>And that’s all! To use it, we simply have to use <code>config.sops.secrets.tailscale_key.path</code> where we need it. Beware that this will not give you the secret, but a path to a file containing the raw secret, for security reasons. Otherwise, the secret would be in the Nix store, and thus accessible to any user on the system.</p> +<h2 id="note-adding-a-new-host">Note: adding a new host</h2> +<p>If you ever need to add a new host, you will need to update your secrets with <code>sops updatekeys your_secret</code>. This command has to be on a system with already authorized keys.</p> +<h1 id="tailscale">Tailscale</h1> +<p>We can finally get to a real feature, setting up Tailscale. +For those of you who haven’t heard of it, Tailscale is a private meshed network, allowing you to connect to your machines privately and securely through Wireguard, a VPN protocol, without exposing them to the world. +This means being able to close port 22, while still being able to SSH into your computer.</p> +<p>Furthermore, Tailscale offers some additional features, such as a fancy file sending tool or hole punching, which allows you to connect to your computer even if it is behind a NAT. I won’t go into details here, but you can read more about it on <a rel="noopener" target="_blank" href="https://tailscale.com/">their website</a>.</p> +<p>I’ve chosen to write a full-fledged NixOS module for Tailscale, as it is a service that needs to be configured and started. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!</p> +<h2 id="boilerplate-for-nixos-modules">Boilerplate for NixOS modules</h2> +<p>We’re going to write a module, so we need to create a directory for it:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> modules/nixos</span> +</span></code></pre> +<p>Inside, we’ll need a <code>default.nix</code> file:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale-autoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">import</span> <span class="z-string z-unquoted z-path z-nix">./tailscale-autoconnect.nix</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>By convention, this file is automatically imported when you import a directory. Then, in our <code>flake.nix</code>, we can import our module:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">outputs</span> <span class="z-invalid z-illegal">=</span> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">nixosModules</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-support z-function z-nix">import</span> <span class="z-string z-unquoted z-path z-nix">./modules/nixos</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>As before, the <code>nixosModules</code> attribute has a special meaning.</p> +<p>Finally, we have to import the module we’re writing in our configuration:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">imports</span> <span class="z-invalid z-illegal">=</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">outputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale-autoconnect</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<h2 id="writing-the-module">Writing the module</h2> +<p>We’re going to write a module to start Tailscale and connect to it automatically. This is a good example of a module that can be reused in other configurations, so it’s worth writing it. Let’s get started!</p> +<p>First, we need to create a <code>tailscale-autoconnect.nix</code> file in our <code>modules/nixos</code> directory. We’ll start with the boilerplate:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">config</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">lib</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-variable z-parameter z-function z-1 z-nix">pkgs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">... </span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-invalid z-illegal z-reserved z-nix">with</span> <span class="z-variable z-parameter z-function z-maybe z-nix">lib</span><span class="z-invalid z-illegal">;</span> <span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">cfg</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-keyword z-other z-nix">in</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">options</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscaleAutoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkEnableOption</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscaleAutoconnect<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">config</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkIf</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">enable</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># ...</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"><span class="z-invalid z-illegal">}</span> +</span></code></pre> +<p>This is the basic structure of a module. We declare an option, and then we use it to conditionally change the configuration. So:</p> +<ul> +<li>What we write in <code>options</code> is the option declaration</li> +<li>What we write in <code>config</code> is the consequence of the option being enabled, the configuration change</li> +</ul> +<p>Let’s declare all the options first.</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">options</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscaleAutoconnect</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkEnableOption</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscaleAutoconnect<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">authkeyFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The authkey to use for authentication with Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">loginServer</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The login server to use for authentication with Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">advertiseExitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">bool</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Whether to advertise this node as an exit node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">str</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>The exit node to use for this node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">mkOption</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">types</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">bool</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">default</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Whether to allow LAN access to this node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This looks like a lot of code, but we’re simply declaring options. We need to give them a type, and we can also give a default value and a description. +Now, the actually useful code:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">config</span> <span class="z-invalid z-illegal">=</span> <span class="z-variable z-parameter z-name z-nix">mkIf</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">enable</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertions</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">authkeyFile</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>authkeyFile must be set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-nix">-&gt;</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>exitNodeAllowLanAccess must be false if exitNode is not set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">assertion</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span> <span class="z-keyword z-operator z-nix">-&gt;</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">==</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span><span class="z-entity z-other z-attribute-name z-multipart z-nix">d</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">message</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>advertiseExitNode must be false if exitNode is set<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">systemd</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale-autoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Automatic connection to Tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># make sure tailscale is running before trying to connect to tailscale</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">after</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>network-pre.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wants</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>network-pre.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wantedBy</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>multi-user.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">serviceConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">Type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>oneshot<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">script</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-keyword z-other z-nix">with</span> <span class="z-variable z-parameter z-name z-nix">pkgs</span>; <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # wait for tailscaled to settle +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> sleep 2 +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # check if we are already authenticated to tailscale +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> status=&quot;$(<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale status -json | <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">jq</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/jq -r .BackendState)&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # if status is not null, then we are already authenticated +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;tailscale status: $status&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> if [ &quot;$status&quot; != &quot;NeedsLogin&quot; ]; then +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> exit 0 +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> fi +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # otherwise authenticate with tailscale +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # timeout after 10 seconds to avoid hanging the boot process +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">coreutils</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/timeout 10 <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale up \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--login-server=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> --authkey=$(cat &quot;<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">authkeyFile</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>&quot;) +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # we have to proceed in two steps because some options are only available +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # after authentication +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">coreutils</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/timeout 10 <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/bin/tailscale up \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--login-server=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">loginServer</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--advertise-exit-node<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span> <span class="z-keyword z-operator z-nix">!=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--exit-node=<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNode</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span><span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> \ +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">lib</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">optionalString</span> <span class="z-punctuation z-definition z-expression z-nix">(</span><span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">exitNodeAllowLanAccess</span><span class="z-punctuation z-definition z-expression z-nix">)</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>--exit-node-allow-lan-access<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">networking</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">firewall</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">trustedInterfaces</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>tailscale0<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">allowedUDPPorts</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">port</span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">useRoutingFeatures</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-keyword z-other z-nix">if</span> <span class="z-variable z-parameter z-name z-nix">cfg</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">advertiseExitNode</span> <span class="z-keyword z-other z-nix">th</span><span class="z-keyword z-other z-nix">en</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>server<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-keyword z-other z-nix">el</span><span class="z-keyword z-other z-nix">se</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>client<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>First, the assertions. They’re here to make sure that the user doesn’t make any mistake when configuring the module. For example, a user cannot both advertise an exit node and set an exit node. +Then, the service. We’re using systemd to run a script that will connect to Tailscale. The <code>after</code>, <code>wants</code> and <code>wantedBy</code> options make the script run after the network is up and after Tailscale daemon is started. The <code>Type</code> option is here to make sure that the script is run only once. The script itself is a bit long, but it’s just a bunch of bash commands. It’s pretty straightforward. First, we wait for the Tailscale daemon to settle. Then, we check if we’re already authenticated. If we are, we exit. Otherwise, we authenticate. Finally, we connect to Tailscale. We have to do it in two steps because some options are only available after authentication.</p> +<p>At the end, we configure the firewall to allow Tailscale traffic, and we enable the Tailscale service.</p> +<p>Now, an example of how to use this module:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-punctuation z-definition z-entity z-function z-2 z-nix">{</span> <span class="z-variable z-parameter z-function z-1 z-nix">outputs</span><span class="z-keyword z-operator z-nix">,</span> <span class="z-keyword z-operator z-nix">...</span><span class="z-punctuation z-definition z-entity z-function z-nix">}</span><span class="z-punctuation z-definition z-function z-nix">:</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">outputs</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">nixosModules</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale-autoconnect</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscaleAutoconnect</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">authkeyFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sops</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">secrets</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">tailscale_key</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">path</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">loginServer</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://login.tailscale.com<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNode</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>some-node-id<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">exitNodeAllowLanAccess</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sops</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">secrets</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">tailscale_key</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">sopsFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-unquoted z-path z-nix">./secrets.yaml</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">environment</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">persistence</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">directories</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/var/lib/tailscale<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span> +</span></code></pre> +<p>The module is imported and configured. We also use the <code>sops</code> secret we created earlier. Finally, we persist the Tailscale state, so that we don’t have to authenticate again after a reboot. This is especially important if the authkey can expire.</p> +<hr /> +<p>That’s all for this post. Thanks for reading! If you have any question, feel free to ask in the comments. The final code can be found <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/tree/2-tailscale">here</a>.</p> +<!-- +# Our first service : a simple file server + +Our first service will be a basic web server. For that, we will use nginx. `nginx` is, obviously, a web server. However, it is often also used as a reverse proxy, forwarding the requests it gets to the internal services. `nginx.Nix`: +```nix +{ + services.nginx = { + enable = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + clientMaxBodySize = "300m"; + }; + networking.firewall.allowedTCPPorts = [ 80 443 ]; +} +``` +`web-server.Nix`: +```nix +{ + services.nginx.virtualHosts."e1.oze.li" = { + addSSL = true; + enableACME = true; + root = "/var/www/files"; + }; + + environment.persistence = { + "/persist".directories = [ "/var/www/files" ]; + }; +} +``` +We are enabling the `nginx` service. For now, it only serves `e1.oze.li`, our web server. You can notice the `addSSL` parameter, together with `enableACME`: thanks to them, we are getting a HTTPS certificate for free, provided by LetsEncrypt. We need to accept its terms. `acme.Nix`: +```nix + # Enable acme for usage with nginx vhosts + security.acme = { + defaults.email = "some@email.com"; + acceptTerms = true; + }; + + environment.persistence = { + "/persist".directories = [ "/var/lib/acme" ]; + }; +} +``` +That's all! That is so simple and straightforward. I couldn't imagine myself using only Docker now. +--> + + + + + NixOS as a server, part 1: Impermanence + 2023-02-20T00:00:00+00:00 + 2023-02-20T00:00:00+00:00 + + + + + Unknown + + + + + + https://guekka.github.io/nixos-server-1/ + + <p>A few months ago, I woke up with the idea of hosting my own services. I went through a lot of tries. LXC, Debian, Alpine, (rootless or not) Docker, podman, portainer…</p> +<p>But no solution felt perfect. Until I decided to have a try at hosting using NixOS.</p> +<p>I’m going to assume you know about NixOS and have some prior experience. However, for a small summary: NixOS is a Linux distribution revolving around the Nix package manager. Its main advantage is having a reproducible environment through a declarative configuration. This means that you can copy an entire computer configuration easily: if it works somewhere, it will work anywhere.</p> +<p>My main focus point is reproducibility, so that’s why we’ll start with configuring <em>impermanence</em>.</p> +<h2 id="what-s-impermanence">What’s impermanence?</h2> +<p>Originally, a philosophic concept. But in our case, impermanence means erasing the <code>/</code> drive at each reboot. You read that right, erasing <em>almost</em> everything at each reboot. This part stands on the shoulders of those who did it before me:</p> +<ul> +<li><a rel="noopener" target="_blank" href="https://grahamc.com/blog/erase-your-darlings">Erase your darlings: immutable infrastructure for mutable systems - Graham Christensen</a></li> +<li><a rel="noopener" target="_blank" href="https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/">NixOS ❄: tmpfs as root</a></li> +<li><a rel="noopener" target="_blank" href="https://mt-caret.github.io/blog/posts/2020-06-29-optin-state.html#fn6">Encypted Btrfs Root with Opt-in State on NixOS</a></li> +<li><a rel="noopener" target="_blank" href="https://xeiaso.net/blog/paranoid-nixos-2021-07-18">Paranoid NixOS Setup - Xe Iaso</a></li> +<li><a rel="noopener" target="_blank" href="https://github.com/nix-community/impermanence">nix-community/impermanence: NixOS module</a></li> +</ul> +<p>The goal is the following: over years, configuration files accumulate. Sometimes editing <code>/etc</code> is required, because of a bug or an obscure configuration. NixOS allows us to avoid this manual file editing, but it does not <em>force</em> us to do so. We can still have a lot of important state, breaking the reproducibility promise.</p> +<p>So what can we do instead? Erase everything, at each reboot. This way, we’ll be sure the only source of truth is our configuration.</p> +<h2 id="installing-the-system">Installing the system</h2> +<p>I’m currently using a <a rel="noopener" target="_blank" href="https://github.com/quickemu-project/quickemu">quickemu</a> VM. This is not a recommenced setup and is only done for testing. Configuration file:</p> +<pre data-lang="conf" class="language-conf z-code"><code class="language-conf" data-lang="conf"><span class="z-source z-genconfig"><span class="z-meta z-comment z-genconfig"><span class="z-comment z-line z-number-sign z-genconfig">#!/usr/bin/quickemu --vm +</span></span></span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">guest_os</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;linux&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">disk_img</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;nixos-22.11-minimal/disk.qcow2&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">iso</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;nixos-22.11-minimal/latest-nixos-minimal-x86_64-linux.iso&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">disk_size</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;50G&quot;</span> +</span><span class="z-source z-genconfig"><span class="z-meta z-param z-genconfig"><span class="z-variable z-parameter z-genconfig">ram</span><span class="z-keyword z-operator z-genconfig">=</span></span><span class="z-string z-quoted z-double z-genconfig">&quot;4G&quot;</span> +</span></code></pre> +<p>Let’s first format it:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">DISK</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell">/dev/vda</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mklabel gpt</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart ESP fat32 1MiB 1GiB</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> set 1 boot on</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkfs.vfat</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>1</span> +</span></code></pre> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart Swap linux-swap 1GiB 9GiB</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkswap</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>L</span> Swap <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>2</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">swapon</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>2</span> +</span></code></pre> +<blockquote> +<p>Using swap in 2023!?</p> +</blockquote> +<p><a rel="noopener" target="_blank" href="https://chrisdown.name/2018/01/02/in-defence-of-swap.html">Yes</a>.</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">parted</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span><span class="z-keyword z-operator z-end-of-options z-shell"> --</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkpart primary 9GiB 100<span class="z-meta z-group z-expansion z-job z-shell"><span class="z-punctuation z-definition z-variable z-job z-shell">%</span></span></span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkfs.btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>L</span> Butter <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3</span> +</span></code></pre> +<p>While the <code>impermanence</code> module recommends using <code>tmpfs</code> for <code>/</code>, I chose to use <code>btrfs</code>: I do not have RAM to waste. Furthermore, this will allow us to use a nice script we’ll see later on.</p> +<p>Let’s create <code>btrfs</code> subvolumes:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/root</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/home</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/nix</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/persist</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume create /mnt/log</span> +</span></code></pre> +<p>And now, the crucial part:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">btrfs</span></span><span class="z-meta z-function-call z-arguments z-shell"> subvolume snapshot<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>r</span> /mnt/root /mnt/root-blank</span> +</span></code></pre> +<p>We just took a snapshot of that empty volume. We will restore it at each reboot. +We can now mount the subvolumes and let <code>nixos-generate-config</code> do its job</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=root,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/home</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=home,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/home</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/nix</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=nix,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/nix</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/persist</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=persist,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/persist</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>p</span> /mnt/var/log</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=log,compress=zstd,noatime <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>3 /mnt/var/log</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mkdir</span></span><span class="z-meta z-function-call z-arguments z-shell"> /mnt/boot</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">mount</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">DISK</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span>1 /mnt/boot</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">nixos-generate-config</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>root</span> /mnt</span> +</span></code></pre> +<p>Lastly, we only have to edit the generated configuration files at <code>/mnt/etc/nixos</code>.</p> +<p>My final configuration is available <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/tree/1-impermanence">here</a>. You can follow all the steps by looking at the <a rel="noopener" target="_blank" href="https://github.com/Guekka/nixos-server/commits/1-impermanence">commits</a>.</p> +<h2 id="configuring-the-system">Configuring the system</h2> +<ul> +<li>Checking that we have the correct mount options in <code>/mnt/etc/nixos/hardware-configuration.nix</code>.</li> +</ul> +<p>I’ve added <code>&quot;compress=zstd&quot; &quot;noatime&quot;</code> to all filesystems. We also need to add <code>neededForBoot</code> to <code>/var/log</code> and <code>/persist</code>.</p> +<ul> +<li>Replacing default values in <code>configuration.nix</code></li> +</ul> +<p>I’ve enabled <code>networkmanager</code>, removed most suggested options and enabled <code>system.copySystemConfiguration</code>.</p> +<p>This last option copies the current configuration to <code>/run/current_system/configuration.nix</code>. You should not rely on it: keep your configuration in a git repository. But it can serve as some kind of last chance.</p> +<ul> +<li>Declaring a user, including ssh</li> +</ul> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">mutableUsers</span> <span class="z-invalid z-illegal">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">users</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">user</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">isNormalUser</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">extraGroups</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>wheel<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">openssh</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">authorizedKeys</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">keys</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICWVNch9BcjkMqS/Xwep+GN4HwqyRIjr3Cuw7mHpqsKr nixos<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># passwordFile needs to be in a volume marked with `neededForBoot = true`</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">passwordFile</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist/passwords/user<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>Here we have completely disabled imperative user modification. This does not matter much, as imperative changes would be erased anyway at start. +We thus need to provide a password. We’re using <code>passwordFile</code> for that: a path to a file containing the hashed password.</p> +<p>Here’s how to generate that file: <code>sudo mkpasswd -m sha-512 &quot;hunter2&quot; &gt; /mnt/persist/passwords/user</code>.</p> +<p>The SSH key was generated using `ssh-keygen -t ed25519 -C “nixos”.</p> +<ul> +<li>Enabling openSSH +We’re going to use Xe’s configuration:</li> +</ul> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">services</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">openssh</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">passwordAuthentication</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">allowSFTP</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> <span class="z-comment z-line z-number-sign z-nix"># Don&#39;t set this if you need sftp</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">challengeResponseAuthentication</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">false</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">extraConfig</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowTcpForwarding yes +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> X11Forwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowAgentForwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AllowStreamLocalForwarding no +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> AuthenticationMethods publickey +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>This reduces attack surface, for example by disabling stream-local forwarding and disabling password authentification.</p> +<hr /> +<p>This will be enough for now. Let’s install the system before going to the next step: <code>sudo nixos-install --root /mnt &amp;&amp; sudo reboot</code>. You should be able to connect by SSH using the previously defined key, or login using the password you defined in <code>/persist/passwords/user</code>.</p> +<h2 id="configuring-impermanence">Configuring impermanence</h2> +<p>We’ve created our volumes, we’ve configured the system… But I promised we would reset our system at each reboot. Let’s do that now! +We’re going to use the following script, credit of mt-caret. Do not forget to replace <code>vda3</code> with your data partition.</p> +<p><strong>16/07/23 update</strong>: it was brought to my attention that <a rel="noopener" target="_blank" href="https://discourse.nixos.org/t/what-does-impermanence-add-over-built-in-functionality/27939/16">postDeviceCommands can cause data loss</a>. +While I did not experience any issue, I have updated the script to use a safer alternative.</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">boot</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">initrd</span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">enable</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">true</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">supportedFilesystems</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>btrfs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">systemd</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">services</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">restore-root</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">description</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>Rollback btrfs rootfs<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">wantedBy</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>initrd.target<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">requires</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>dev-vda3<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">after</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>dev-vda3<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># for luks</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>systemd-cryptsetup@<span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">config</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">networking</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">hostName</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>.service<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">before</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>sysroot.mount<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">unitConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">DefaultDependencies</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>no<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">serviceConfig</span>.<span class="z-entity z-other z-attribute-name z-multipart z-nix">Type</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>oneshot<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">script</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> mkdir -p /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # We first mount the btrfs root to /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # so we can manipulate btrfs subvolumes. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> mount -o subvol=/ /dev/vda3 /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # While we&#39;re tempted to just delete /root and create +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # a new snapshot from /root-blank, /root is already +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # populated at this point with a number of subvolumes, +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # which makes `btrfs subvolume delete` fail. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # So, we remove them first. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # /root contains subvolumes: +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # - /root/var/lib/portables +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # - /root/var/lib/machines +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # I suspect these are related to systemd-nspawn, but +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # since I don&#39;t use it I&#39;m not 100% sure. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # Anyhow, deleting these subvolumes hasn&#39;t resulted +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # in any issues so far, except for fairly +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # benign-looking errors from systemd-tmpfiles. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume list -o /mnt/root | +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> cut -f9 -d&#39; &#39; | +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> while read subvolume; do +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;deleting /$subvolume subvolume...&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume delete &quot;/mnt/$subvolume&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> done &amp;&amp; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;deleting /root subvolume...&quot; &amp;&amp; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume delete /mnt/root +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> echo &quot;restoring blank /root subvolume...&quot; +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> btrfs subvolume snapshot /mnt/root-blank /mnt/root +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # Once we&#39;re done rolling back to a blank snapshot, +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # we can unmount /mnt and continue on the boot process. +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> umount /mnt +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-attrset z-nix">}</span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>We can then specify the files we want to keep.</p> +<p>But which files do we want to keep? Let’s find out. Thanks to another useful script of mt-caret, we can list the differences between our current <code>/</code> and the blank state:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell">!/usr/bin/env bash</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> fs-diff.sh</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-support z-function z-set z-shell">set</span></span><span class="z-meta z-function-call z-arguments z-shell"> -euo pipefail</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">OLD_TRANSID</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-meta z-group z-expansion z-command z-parens z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> btrfs subvolume find-new /mnt/root-blank 9999999</span><span class="z-punctuation z-section z-parens z-end z-shell">)</span></span></span> +</span><span class="z-source z-shell z-bash"><span class="z-variable z-other z-readwrite z-assignment z-shell">OLD_TRANSID</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-expansion z-parameter z-begin z-shell">{</span></span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-variable z-other z-readwrite z-shell">OLD_TRANSID<span class="z-keyword z-operator z-expansion z-shell">#</span></span></span><span class="z-meta z-group z-expansion z-parameter z-shell">transid marker was </span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-section z-expansion z-parameter z-end z-shell">}</span></span></span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> btrfs subvolume find-new <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>/mnt/root<span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">OLD_TRANSID</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sed</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&#39;</span>$d<span class="z-punctuation z-definition z-string z-end z-shell">&#39;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">cut</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>f17-</span><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>d</span><span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&#39;</span> <span class="z-punctuation z-definition z-string z-end z-shell">&#39;</span></span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sort</span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">uniq</span></span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> +</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-loop z-while z-shell">while</span> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-read z-shell">read</span></span><span class="z-meta z-function-call z-arguments z-shell"> path</span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-loop z-do z-shell">do</span> +</span><span class="z-source z-shell z-bash"> <span class="z-variable z-other z-readwrite z-assignment z-shell">path</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span>/<span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-if z-shell">if</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell">-</span>L</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-conditional z-then z-shell">then</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-colon z-shell">:</span></span> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> The path is a symbolic link, so is probably handled by NixOS already</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-elseif z-shell">elif</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell">-</span>d</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-conditional z-then z-shell">then</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-colon z-shell">:</span></span> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> The path is a directory, ignore</span><span class="z-comment z-line z-number-sign z-shell"> +</span></span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-else z-shell">else</span> +</span><span class="z-source z-shell z-bash"> <span class="z-meta z-function-call z-shell"><span class="z-support z-function z-echo z-shell">echo</span></span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">&quot;</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">path</span></span><span class="z-punctuation z-definition z-string z-end z-shell">&quot;</span></span></span> +</span><span class="z-source z-shell z-bash"> <span class="z-keyword z-control z-conditional z-end z-shell">fi</span> +</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-loop z-end z-shell">done</span> +</span></code></pre> +<p>Used like this:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /mnt</span> <span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mount<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>o</span> subvol=/ /dev/vda3 /mnt</span> <span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">./fs-diff.sh</span></span> +</span></code></pre> +<p>Here’s the result of mine:</p> +<pre class="z-code"><code><span class="z-text z-plain">/etc/.clean +</span><span class="z-text z-plain">/etc/group +</span><span class="z-text z-plain">/etc/machine-id +</span><span class="z-text z-plain">/etc/nixos/configuration.nix +</span><span class="z-text z-plain">/etc/nixos/hardware-configuration.nix +</span><span class="z-text z-plain">/etc/passwd +</span><span class="z-text z-plain">/etc/resolv.conf +</span><span class="z-text z-plain">/etc/shadow +</span><span class="z-text z-plain">/etc/ssh/authorized_keys.d/user +</span><span class="z-text z-plain">/etc/ssh/ssh_host_ed25519_key +</span><span class="z-text z-plain">/etc/ssh/ssh_host_ed25519_key.pub +</span><span class="z-text z-plain">/etc/ssh/ssh_host_rsa_key +</span><span class="z-text z-plain">/etc/ssh/ssh_host_rsa_key.pub +</span><span class="z-text z-plain">/etc/subgid +</span><span class="z-text z-plain">/etc/subuid +</span><span class="z-text z-plain">/etc/sudoers +</span><span class="z-text z-plain">/etc/.updated +</span><span class="z-text z-plain">/root/.nix-channels +</span><span class="z-text z-plain">/root/.nix-defexpr/channels +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s8.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/NetworkManager-intern.conf +</span><span class="z-text z-plain">/var/lib/NetworkManager/secret_key +</span><span class="z-text z-plain">/var/lib/NetworkManager/timestamps +</span><span class="z-text z-plain">/var/lib/nixos/auto-subuid-map +</span><span class="z-text z-plain">/var/lib/nixos/declarative-groups +</span><span class="z-text z-plain">/var/lib/nixos/declarative-users +</span><span class="z-text z-plain">/var/lib/nixos/gid-map +</span><span class="z-text z-plain">/var/lib/nixos/uid-map +</span><span class="z-text z-plain">/var/lib/systemd/catalog/database +</span><span class="z-text z-plain">/var/lib/systemd/random-seed +</span><span class="z-text z-plain">/var/.updated +</span></code></pre> +<p>That’s not too bad!</p> +<p>Out of these, there’s almost nothing I want to preserve.</p> +<p>Let’s make use of the <code>impermanence</code> module. We need to download it:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"><span class="z-keyword z-other z-nix">let</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">impermanence</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-constant z-language z-nix">builtins</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">fetchTarball</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>https://github.com/nix-community/impermanence/archive/master.tar.gz<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"><span class="z-keyword z-other z-nix">in</span> +</span><span class="z-source z-nix"><span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"><span class="z-entity z-other z-attribute-name z-multipart z-nix">imports</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span><span class="z-markup z-italic"><span class="z-punctuation z-section z-embedded z-begin z-nix">${</span><span class="z-variable z-parameter z-name z-nix">impermanence</span><span class="z-punctuation z-section z-embedded z-end z-nix">}</span></span>/nixos.nix<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-string z-unquoted z-path z-nix">./hardware-configuration.nix</span> <span class="z-punctuation z-definition z-list z-nix">]</span> +</span><span class="z-source z-nix"><span class="z-keyword z-operator z-nix">//</span> <span class="z-variable z-parameter z-name z-nix">the</span> <span class="z-variable z-parameter z-name z-nix">whole</span> <span class="z-variable z-parameter z-name z-nix">configuration</span> +</span><span class="z-source z-nix"><span class="z-invalid z-illegal">}</span> +</span></code></pre> +<p>And now, we can just tell it the files and directories that we want:</p> +<pre data-lang="nix" class="language-nix z-code"><code class="language-nix" data-lang="nix"><span class="z-source z-nix"> <span class="z-comment z-line z-number-sign z-nix"># configure impermanence</span> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">environment</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">persistence</span><span class="z-keyword z-operator z-nix">.</span><span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/persist<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> <span class="z-invalid z-illegal">=</span> <span class="z-punctuation z-definition z-attrset-or-function z-nix">{</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">directories</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/nixos<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-punctuation z-definition z-list z-nix">]</span><span class="z-punctuation z-terminator z-bind z-nix">;</span> +</span><span class="z-source z-nix"> <span class="z-entity z-other z-attribute-name z-multipart z-nix">files</span> <span class="z-keyword z-operator z-bind z-nix">=</span> <span class="z-punctuation z-definition z-list z-nix">[</span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/machine-id<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_ed25519_key<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_ed25519_key.pub<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_rsa_key<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-string z-quoted z-double z-nix"><span class="z-punctuation z-definition z-string z-double z-start z-nix">&quot;</span>/etc/ssh/ssh_host_rsa_key.pub<span class="z-punctuation z-definition z-string z-double z-end z-nix">&quot;</span></span> +</span><span class="z-source z-nix"> <span class="z-invalid z-illegal">}</span><span class="z-invalid z-illegal">;</span> +</span><span class="z-source z-nix"> +</span><span class="z-source z-nix"> <span class="z-variable z-parameter z-name z-nix">security</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">sudo</span><span class="z-keyword z-operator z-nix">.</span><span class="z-variable z-parameter z-name z-nix">extraConfig</span> <span class="z-invalid z-illegal">=</span> <span class="z-string z-quoted z-other z-nix"><span class="z-punctuation z-definition z-string z-other z-start z-nix">&#39;&#39;</span> +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> # rollback results in sudo lectures after each reboot +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> Defaults lecture = never +</span></span><span class="z-source z-nix"><span class="z-string z-quoted z-other z-nix"> <span class="z-punctuation z-definition z-string z-other z-end z-nix">&#39;&#39;</span></span><span class="z-invalid z-illegal">;</span> +</span></code></pre> +<p>What an ergonomic interface.</p> +<blockquote> +<p>Wait, did you just say Nix was ergonomic?</p> +</blockquote> +<p>Well, yes. Sometimes.</p> +<hr /> +<p>I have not saved my network manager configuration, but you may need to.</p> +<p>When new files are set to be preserved, <strong>it is necessary to copy them manually to <code>/persist</code></strong>:</p> +<pre data-lang="sh" class="language-sh z-code"><code class="language-sh" data-lang="sh"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> nixos-rebuild boot</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /persist/etc</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>r</span> <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/nixos</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/machine-id</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mkdir /persist/etc/ssh</span> +</span><span class="z-source z-shell z-bash"> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_ed25519_key</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_ed25519_key.pub</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_rsa_key</span> +</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> cp <span class="z-meta z-group z-expansion z-brace z-shell"><span class="z-punctuation z-section z-expansion z-brace z-begin z-shell">{</span><span class="z-punctuation z-separator z-shell">,</span>/persist<span class="z-punctuation z-section z-expansion z-brace z-end z-shell">}</span></span>/etc/ssh/ssh_host_rsa_key.pub</span> +</span></code></pre> +<p>Now, if we reboot and list files again:</p> +<pre class="z-code"><code><span class="z-text z-plain">/etc/.clean +</span><span class="z-text z-plain">/etc/group +</span><span class="z-text z-plain">/etc/passwd +</span><span class="z-text z-plain">/etc/resolv.conf +</span><span class="z-text z-plain">/etc/shadow +</span><span class="z-text z-plain">/etc/ssh/authorized_keys.d/user +</span><span class="z-text z-plain">/etc/subgid +</span><span class="z-text z-plain">/etc/subuid +</span><span class="z-text z-plain">/etc/sudoers +</span><span class="z-text z-plain">/etc/.updated +</span><span class="z-text z-plain">/root/.nix-channels +</span><span class="z-text z-plain">/var/lib/NetworkManager/internal-84e273c2-b91a-3a96-b341-8234a339bdc7-enp0s9.lease +</span><span class="z-text z-plain">/var/lib/NetworkManager/NetworkManager-intern.conf +</span><span class="z-text z-plain">/var/lib/NetworkManager/secret_key +</span><span class="z-text z-plain">/var/lib/NetworkManager/timestamps +</span><span class="z-text z-plain">/var/lib/nixos/auto-subuid-map +</span><span class="z-text z-plain">/var/lib/nixos/declarative-groups +</span><span class="z-text z-plain">/var/lib/nixos/declarative-users +</span><span class="z-text z-plain">/var/lib/nixos/gid-map +</span><span class="z-text z-plain">/var/lib/nixos/uid-map +</span><span class="z-text z-plain">/var/lib/systemd/catalog/database +</span><span class="z-text z-plain">/var/lib/systemd/random-seed +</span><span class="z-text z-plain">/var/.updated +</span></code></pre> +<p>Success! The files we persisted are no longer showing up.</p> +<h3 id="what-about-our-home-directory">What about our home directory?</h3> +<p>It is possible to setup the impermanence module for our home directory. However, I did not want to go through <code>home-manager</code> installation. Furthermore, a home directory is meant to be stateful.</p> +<p>In our case, we are creating a server, so it would still make sense to configure it. If you are interested, have a look at <a rel="noopener" target="_blank" href="https://elis.nu/blog/2020/06/nixos-tmpfs-as-home/">tmpfs at home</a>.</p> +<h2 id="next-steps">Next steps</h2> +<p>In the next part, we will make our server more secure by making it only available through Tailscale. We will also setup our first service.</p> +<hr /> +<p>I hope you’ve enjoyed this article! Thanks for reading to the end!</p> + + + + diff --git a/tags/self-hosting/index.html b/tags/self-hosting/index.html new file mode 100644 index 0000000..73b25aa --- /dev/null +++ b/tags/self-hosting/index.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + self-hosting tag | Guekka's blog + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    self-hosting

    +

    2023

    +

    NixOS as a server, part 2: Flake, tailscale -

    +

    NixOS as a server, part 1: Impermanence -

    +
    +
    + + +