From b89212309a9fafdae93065f99ca20d9ddcaefdf1 Mon Sep 17 00:00:00 2001 From: javiergarea Date: Mon, 7 Oct 2024 11:20:47 +0000 Subject: [PATCH] deploy: a7989c3d7db2630b3504fb998f743aeefaf1e370 --- .build | 10 +- 404.html | 12 +- api-reference.html | 30 ++- contributing.html | 12 +- dist/html-BHYOTRCH.js | 56 ----- dist/html-YIPIRHGU.js | 56 +++++ dist/html-erlang-EBZIIHAS.css | 6 - dist/html-erlang-YKQ677RH.css | 6 + dist/search_data-1514AF50.js | 1 + dist/search_data-3FC7F05E.js | 1 - dist/sidebar_items-28F82D22.js | 1 + dist/sidebar_items-CD0FFEC6.js | 1 - erf.html | 110 ++++----- erf_conf.html | 52 ++-- erf_http_server.html | 421 ++++++++++++++++++++++++++++++++ erf_http_server_elli.html | 294 ++++++++++++++++++++++ erf_parser.html | 38 ++- erf_parser_oas_3_0.html | 24 +- erf_postprocess_middleware.html | 14 +- erf_preprocess_middleware.html | 14 +- erf_router.html | 69 ++++-- erf_static.html | 14 +- erf_util.html | 16 +- index.html | 2 +- license.html | 12 +- readme.html | 174 +++++++------ search.html | 14 +- 27 files changed, 1099 insertions(+), 361 deletions(-) delete mode 100644 dist/html-BHYOTRCH.js create mode 100644 dist/html-YIPIRHGU.js delete mode 100644 dist/html-erlang-EBZIIHAS.css create mode 100644 dist/html-erlang-YKQ677RH.css create mode 100644 dist/search_data-1514AF50.js delete mode 100644 dist/search_data-3FC7F05E.js create mode 100644 dist/sidebar_items-28F82D22.js delete mode 100644 dist/sidebar_items-CD0FFEC6.js create mode 100644 erf_http_server.html create mode 100644 erf_http_server_elli.html diff --git a/.build b/.build index 66f400e..e8942c7 100644 --- a/.build +++ b/.build @@ -3,8 +3,8 @@ api-reference.html contributing.html dist/handlebars.runtime-NWIB6V2M.js dist/handlebars.templates-K7URE6B4.js -dist/html-BHYOTRCH.js -dist/html-erlang-EBZIIHAS.css +dist/html-YIPIRHGU.js +dist/html-erlang-YKQ677RH.css dist/inconsolata-latin-400-normal-RGKDDNDD.woff2 dist/inconsolata-latin-700-normal-DTS2D7TO.woff2 dist/inconsolata-latin-ext-400-normal-K7HVGTP7.woff2 @@ -18,10 +18,12 @@ dist/lato-latin-ext-300-normal-VPGGJKJL.woff2 dist/lato-latin-ext-400-normal-N27NCBWW.woff2 dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2 dist/remixicon-NKANDIL5.woff2 -dist/search_data-3FC7F05E.js -dist/sidebar_items-CD0FFEC6.js +dist/search_data-1514AF50.js +dist/sidebar_items-28F82D22.js erf.html erf_conf.html +erf_http_server.html +erf_http_server_elli.html erf_parser.html erf_parser_oas_3_0.html erf_postprocess_middleware.html diff --git a/404.html b/404.html index 7f0b691..0161f24 100644 --- a/404.html +++ b/404.html @@ -4,22 +4,21 @@ - + 404 — erf v0.1.2 - + - + - - + @@ -142,7 +141,7 @@

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -153,6 +152,5 @@

- diff --git a/api-reference.html b/api-reference.html index 91a8fda..134fbb1 100644 --- a/api-reference.html +++ b/api-reference.html @@ -4,20 +4,19 @@ - + API Reference — erf v0.1.2 - + - + - - + @@ -149,6 +148,24 @@

erf's configuration manager module.
+ +
+ + +
erf's interface to interact with its underlying HTTP server.
+ +
+
+ + +
An elli implementation for erf_http_server.
+
@@ -253,7 +270,7 @@

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -264,6 +281,5 @@

- diff --git a/contributing.html b/contributing.html index 6ff5c57..55f93af 100644 --- a/contributing.html +++ b/contributing.html @@ -4,20 +4,19 @@ - + Contributing — erf v0.1.2 - + - + - - + @@ -209,7 +208,7 @@

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -220,6 +219,5 @@

- diff --git a/dist/html-BHYOTRCH.js b/dist/html-BHYOTRCH.js deleted file mode 100644 index 5880235..0000000 --- a/dist/html-BHYOTRCH.js +++ /dev/null @@ -1,56 +0,0 @@ -(()=>{var Zn=Object.create;var ut=Object.defineProperty;var ei=Object.getOwnPropertyDescriptor;var ti=Object.getOwnPropertyNames;var ni=Object.getPrototypeOf,ii=Object.prototype.hasOwnProperty;var dt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var ri=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ti(t))!ii.call(e,r)&&r!==n&&ut(e,r,{get:()=>t[r],enumerable:!(i=ei(t,r))||i.enumerable});return e};var ft=(e,t,n)=>(n=e!=null?Zn(ni(e)):{},ri(t||!e||!e.__esModule?ut(n,"default",{value:e,enumerable:!0}):n,e));var kt=dt((ro,wt)=>{var Tt="Expected a function",Et=NaN,mi="[object Symbol]",gi=/^\s+|\s+$/g,yi=/^[-+]0x[0-9a-f]+$/i,vi=/^0b[01]+$/i,bi=/^0o[0-7]+$/i,Si=parseInt,xi=typeof global=="object"&&global&&global.Object===Object&&global,Ei=typeof self=="object"&&self&&self.Object===Object&&self,Li=xi||Ei||Function("return this")(),Ti=Object.prototype,wi=Ti.toString,ki=Math.max,_i=Math.min,Fe=function(){return Li.Date.now()};function Oi(e,t,n){var i,r,s,o,a,l,u=0,f=!1,y=!1,g=!0;if(typeof e!="function")throw new TypeError(Tt);t=Lt(t)||0,ve(n)&&(f=!!n.leading,y="maxWait"in n,s=y?ki(Lt(n.maxWait)||0,t):s,g="trailing"in n?!!n.trailing:g);function L(S){var C=i,D=r;return i=r=void 0,u=S,o=e.apply(D,C),o}function b(S){return u=S,a=setTimeout(h,t),f?L(S):o}function T(S){var C=S-l,D=S-u,V=t-C;return y?_i(V,s-D):V}function m(S){var C=S-l,D=S-u;return l===void 0||C>=t||C<0||y&&D>=s}function h(){var S=Fe();if(m(S))return _(S);a=setTimeout(h,T(S))}function _(S){return a=void 0,g&&i?L(S):(i=r=void 0,o)}function w(){a!==void 0&&clearTimeout(a),u=0,i=l=r=a=void 0}function N(){return a===void 0?o:_(Fe())}function F(){var S=Fe(),C=m(S);if(i=arguments,r=this,l=S,C){if(a===void 0)return b(l);if(y)return a=setTimeout(h,t),L(l)}return a===void 0&&(a=setTimeout(h,t)),o}return F.cancel=w,F.flush=N,F}function Ii(e,t,n){var i=!0,r=!0;if(typeof e!="function")throw new TypeError(Tt);return ve(n)&&(i="leading"in n?!!n.leading:i,r="trailing"in n?!!n.trailing:r),Oi(e,t,{leading:i,maxWait:t,trailing:r})}function ve(e){var t=typeof e;return!!e&&(t=="object"||t=="function")}function Ci(e){return!!e&&typeof e=="object"}function Ai(e){return typeof e=="symbol"||Ci(e)&&wi.call(e)==mi}function Lt(e){if(typeof e=="number")return e;if(Ai(e))return Et;if(ve(e)){var t=typeof e.valueOf=="function"?e.valueOf():e;e=ve(t)?t+"":t}if(typeof e!="string")return e===0?e:+e;e=e.replace(gi,"");var n=vi.test(e);return n||bi.test(e)?Si(e.slice(2),n?2:8):yi.test(e)?Et:+e}wt.exports=Ii});var ln=dt((an,cn)=>{(function(){var e=function(t){var n=new e.Builder;return n.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),n.searchPipeline.add(e.stemmer),t.call(n,n),n.build()};e.version="2.3.9";e.utils={},e.utils.warn=function(t){return function(n){t.console&&console.warn&&console.warn(n)}}(this),e.utils.asString=function(t){return t==null?"":t.toString()},e.utils.clone=function(t){if(t==null)return t;for(var n=Object.create(null),i=Object.keys(t),r=0;r0){var f=e.utils.clone(n)||{};f.position=[a,u],f.index=s.length,s.push(new e.Token(i.slice(a,o),f))}a=o+1}}return s},e.tokenizer.separator=/[\s\-]+/;e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions=Object.create(null),e.Pipeline.registerFunction=function(t,n){n in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+n),t.label=n,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var n=t.label&&t.label in this.registeredFunctions;n||e.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,t)},e.Pipeline.load=function(t){var n=new e.Pipeline;return t.forEach(function(i){var r=e.Pipeline.registeredFunctions[i];if(r)n.add(r);else throw new Error("Cannot load unregistered function: "+i)}),n},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(n){e.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},e.Pipeline.prototype.after=function(t,n){e.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");i=i+1,this._stack.splice(i,0,n)},e.Pipeline.prototype.before=function(t,n){e.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},e.Pipeline.prototype.remove=function(t){var n=this._stack.indexOf(t);n!=-1&&this._stack.splice(n,1)},e.Pipeline.prototype.run=function(t){for(var n=this._stack.length,i=0;i1&&(ot&&(i=s),o!=t);)r=i-n,s=n+Math.floor(r/2),o=this.elements[s*2];if(o==t||o>t)return s*2;if(ol?f+=2:a==l&&(n+=i[u+1]*r[f+1],u+=2,f+=2);return n},e.Vector.prototype.similarity=function(t){return this.dot(t)/this.magnitude()||0},e.Vector.prototype.toArray=function(){for(var t=new Array(this.elements.length/2),n=1,i=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new e.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),r.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new e.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),r.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&r.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new e.TokenSet;s.node.edges["*"]=u}s.str.length==1&&(u.final=!0),r.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var f=s.str.charAt(0),y=s.str.charAt(1),g;y in s.node.edges?g=s.node.edges[y]:(g=new e.TokenSet,s.node.edges[y]=g),s.str.length==1&&(g.final=!0),r.push({node:g,editsRemaining:s.editsRemaining-1,str:f+s.str.slice(2)})}}}return i},e.TokenSet.fromString=function(t){for(var n=new e.TokenSet,i=n,r=0,s=t.length;r=t;n--){var i=this.uncheckedNodes[n],r=i.child.toString();r in this.minimizedNodes?i.parent.edges[i.char]=this.minimizedNodes[r]:(i.child._str=r,this.minimizedNodes[r]=i.child),this.uncheckedNodes.pop()}};e.Index=function(t){this.invertedIndex=t.invertedIndex,this.fieldVectors=t.fieldVectors,this.tokenSet=t.tokenSet,this.fields=t.fields,this.pipeline=t.pipeline},e.Index.prototype.search=function(t){return this.query(function(n){var i=new e.QueryParser(t,n);i.parse()})},e.Index.prototype.query=function(t){for(var n=new e.Query(this.fields),i=Object.create(null),r=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l1?this._b=1:this._b=t},e.Builder.prototype.k1=function(t){this._k1=t},e.Builder.prototype.add=function(t,n){var i=t[this._ref],r=Object.keys(this._fields);this._documents[i]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){var t,n;do t=this.next(),n=t.charCodeAt(0);while(n>47&&n<58);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos1&&(t.backup(),t.emit(e.QueryLexer.TERM)),t.ignore(),t.more())return e.QueryLexer.lexText},e.QueryLexer.lexEditDistance=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.EDIT_DISTANCE),e.QueryLexer.lexText},e.QueryLexer.lexBoost=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.BOOST),e.QueryLexer.lexText},e.QueryLexer.lexEOS=function(t){t.width()>0&&t.emit(e.QueryLexer.TERM)},e.QueryLexer.termSeparator=e.tokenizer.separator,e.QueryLexer.lexText=function(t){for(;;){var n=t.next();if(n==e.QueryLexer.EOS)return e.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){t.escapeCharacter();continue}if(n==":")return e.QueryLexer.lexField;if(n=="~")return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexEditDistance;if(n=="^")return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexBoost;if(n=="+"&&t.width()===1||n=="-"&&t.width()===1)return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if(n.match(e.QueryLexer.termSeparator))return e.QueryLexer.lexTerm}},e.QueryParser=function(t,n){this.lexer=new e.QueryLexer(t),this.query=n,this.currentClause={},this.lexemeIdx=0},e.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var t=e.QueryParser.parseClause;t;)t=t(this);return this.query},e.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},e.QueryParser.prototype.consumeLexeme=function(){var t=this.peekLexeme();return this.lexemeIdx+=1,t},e.QueryParser.prototype.nextClause=function(){var t=this.currentClause;this.query.clause(t),this.currentClause={}},e.QueryParser.parseClause=function(t){var n=t.peekLexeme();if(n!=null)switch(n.type){case e.QueryLexer.PRESENCE:return e.QueryParser.parsePresence;case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(i+=" with value '"+n.str+"'"),new e.QueryParseError(i,n.start,n.end)}},e.QueryParser.parsePresence=function(t){var n=t.consumeLexeme();if(n!=null){switch(n.str){case"-":t.currentClause.presence=e.Query.presence.PROHIBITED;break;case"+":t.currentClause.presence=e.Query.presence.REQUIRED;break;default:var i="unrecognised presence operator'"+n.str+"'";throw new e.QueryParseError(i,n.start,n.end)}var r=t.peekLexeme();if(r==null){var i="expecting term or field, found nothing";throw new e.QueryParseError(i,n.start,n.end)}switch(r.type){case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expecting term or field, found '"+r.type+"'";throw new e.QueryParseError(i,r.start,r.end)}}},e.QueryParser.parseField=function(t){var n=t.consumeLexeme();if(n!=null){if(t.query.allFields.indexOf(n.str)==-1){var i=t.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),r="unrecognised field '"+n.str+"', possible fields: "+i;throw new e.QueryParseError(r,n.start,n.end)}t.currentClause.fields=[n.str];var s=t.peekLexeme();if(s==null){var r="expecting term, found nothing";throw new e.QueryParseError(r,n.start,n.end)}switch(s.type){case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var r="expecting term, found '"+s.type+"'";throw new e.QueryParseError(r,s.start,s.end)}}},e.QueryParser.parseTerm=function(t){var n=t.consumeLexeme();if(n!=null){t.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(t.currentClause.usePipeline=!1);var i=t.peekLexeme();if(i==null){t.nextClause();return}switch(i.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+i.type+"'";throw new e.QueryParseError(r,i.start,i.end)}}},e.QueryParser.parseEditDistance=function(t){var n=t.consumeLexeme();if(n!=null){var i=parseInt(n.str,10);if(isNaN(i)){var r="edit distance must be numeric";throw new e.QueryParseError(r,n.start,n.end)}t.currentClause.editDistance=i;var s=t.peekLexeme();if(s==null){t.nextClause();return}switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(r,s.start,s.end)}}},e.QueryParser.parseBoost=function(t){var n=t.consumeLexeme();if(n!=null){var i=parseInt(n.str,10);if(isNaN(i)){var r="boost must be numeric";throw new e.QueryParseError(r,n.start,n.end)}t.currentClause.boost=i;var s=t.peekLexeme();if(s==null){t.nextClause();return}switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(r,s.start,s.end)}}},function(t,n){typeof define=="function"&&define.amd?define(n):typeof an=="object"?cn.exports=n():t.lunr=n()}(this,function(){return e})})()});Handlebars.registerHelper("groupChanged",function(e,t,n){let i=t||"";if(e.group!==i)return delete e.nestedContext,e.group=i,n.fn(this)});Handlebars.registerHelper("nestingChanged",function(e,t,n){if(t.nested_context&&t.nested_context!==e.nestedContext){if(e.nestedContext=t.nested_context,e.lastModuleSeenInGroup!==t.nested_context)return n.fn(this)}else e.lastModuleSeenInGroup=t.title});Handlebars.registerHelper("showSections",function(e,t){if(e.sections.length>0)return t.fn(this)});Handlebars.registerHelper("showSummary",function(e,t){if(e.nodeGroups)return t.fn(this)});Handlebars.registerHelper("isArray",function(e,t){return Array.isArray(e)?t.fn(this):t.inverse(this)});Handlebars.registerHelper("isNonEmptyArray",function(e,t){return Array.isArray(e)&&e.length>0?t.fn(this):t.inverse(this)});Handlebars.registerHelper("isEmptyArray",function(e,t){return Array.isArray(e)&&e.length===0?t.fn(this):t.inverse(this)});Handlebars.registerHelper("isLocal",function(e,t){let n=window.location.pathname.split("/").pop();return e+".html"===n?t.fn(this):t.inverse(this)});var c=document.querySelector.bind(document),k=document.querySelectorAll.bind(document);function pt(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function he(e){return String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""")}function $(){return document.body.dataset.type}function ht(e,t){if(e){for(let n of e){let i=n.nodeGroups&&n.nodeGroups.find(r=>r.nodes.some(s=>s.anchor===t));if(i)return i.key}return null}}function me(e,t=!1){if(!e)return t?document.getElementById("top-content"):null;let n=document.getElementById(e);return n?n.matches(".detail")?n:["h1","h2","h3","h4","h5","h6"].includes(n.tagName.toLowerCase())?si(n):null:null}function si(e){let t=[e],n=e.nextElementSibling,i=e.tagName.toLowerCase();for(;n;){let s=n.tagName.toLowerCase();["h1","h2","h3","h4","h5","h6"].includes(s)&&s<=i?n=null:(t.push(n),n=n.nextElementSibling)}let r=document.createElement("div");return r.append(...t),r}function ee(){return window.location.hash.replace(/^#/,"")}function mt(e){return new URLSearchParams(window.location.search).get(e)}function gt(e){return fetch(e).then(t=>t.ok).catch(()=>!1)}function yt(e){document.readyState!=="loading"?e():document.addEventListener("DOMContentLoaded",e)}function te(e){return!e||e.trim()===""}function vt(e,t){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>{n=null,e(...r)},t)}}function ge(){return document.head.querySelector("meta[name=project][content]").content}function ye(){return/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)}var bt="ex_doc:settings",oi={tooltips:!0,theme:null,livebookUrl:null},He=class{constructor(){this._subscribers=[],this._settings=oi,this._loadSettings()}get(){return this._settings}update(t){let n=this._settings;this._settings={...this._settings,...t},this._subscribers.forEach(i=>i(this._settings,n)),this._storeSettings()}getAndSubscribe(t){this._subscribers.push(t),t(this._settings)}_loadSettings(){try{let t=localStorage.getItem(bt);if(t){let n=JSON.parse(t);this._settings={...this._settings,...n}}this._loadSettingsLegacy()}catch(t){console.error(`Failed to load settings: ${t}`)}}_storeSettings(){try{this._storeSettingsLegacy(),localStorage.setItem(bt,JSON.stringify(this._settings))}catch(t){console.error(`Failed to persist settings: ${t}`)}}_loadSettingsLegacy(){localStorage.getItem("tooltipsDisabled")!==null&&(this._settings={...this._settings,tooltips:!1}),localStorage.getItem("night-mode")==="true"&&(this._settings={...this._settings,nightMode:!0}),this._settings.nightMode===!0&&(this._settings={...this._settings,theme:"dark"})}_storeSettingsLegacy(){this._settings.tooltips?localStorage.removeItem("tooltipsDisabled"):localStorage.setItem("tooltipsDisabled","true"),this._settings.nightMode!==null?localStorage.setItem("night-mode",this._settings.nightMode===!0?"true":"false"):localStorage.removeItem("night-mode"),this._settings.theme!==null?(localStorage.setItem("night-mode",this._settings.theme==="dark"?"true":"false"),this._settings.nightMode=this._settings.theme==="dark"):(delete this._settings.nightMode,localStorage.removeItem("night-mode"))}},O=new He;var ai=".content",St=".content-inner",ci=".livebook-badge";function xt(e){e||di(),fi(),li(),ui()}function li(){c(ai).querySelectorAll("a").forEach(e=>{e.querySelector("code, img")&&e.classList.add("no-underline")})}function ui(){["warning","info","error","neutral","tip"].forEach(t=>{k(`blockquote h3.${t}, blockquote h4.${t}`).forEach(n=>{n.closest("blockquote").classList.add(t)})})}function di(){c(St).setAttribute("tabindex",-1),c(St).focus()}function fi(){let t=window.location.pathname.replace(/(\.html)?$/,".livemd"),n=new URL(t,window.location.href).toString();O.getAndSubscribe(i=>{let r=i.livebookUrl?hi(i.livebookUrl,n):pi(n);for(let s of k(ci))s.href=r})}function pi(e){return`https://livebook.dev/run?url=${encodeURIComponent(e)}`}function hi(e,t){return`${e}/import?url=${encodeURIComponent(t)}`}var Ot=ft(kt());var Pi=768,De=300,ne=".sidebar-toggle",Ri=".content",M={CLOSED:"closed",OPEN:"open",NO_PREF:"no_pref"},Q={opened:"sidebar-opened",openingStart:"sidebar-opening-start",opening:"sidebar-opening",closed:"sidebar-closed",closingStart:"sidebar-closing-start",closing:"sidebar-closing"},Ni=Object.values(Q),A={togglingTimeout:null,lastWindowWidth:window.innerWidth,sidebarPreference:M.NO_PREF};function It(){Ct(),Qi(),Hi()}function Qi(){let e=sessionStorage.getItem("sidebar_width");e&&_t(e),new ResizeObserver(n=>{for(let i of n)_t(i.contentRect.width)}).observe(document.getElementById("sidebar"))}function _t(e){sessionStorage.setItem("sidebar_width",e),document.body.style.setProperty("--sidebarWidth",`${e}px`)}function Ct(){sessionStorage.getItem("sidebar_state")==="closed"||At()?(q(Q.closed),c(ne).setAttribute("aria-expanded","false")):(q(Q.opened),c(ne).setAttribute("aria-expanded","true")),setTimeout(()=>c(ne).classList.add("sidebar-toggle--animated"),De)}function At(){return window.matchMedia(`screen and (max-width: ${Pi}px)`).matches}function q(...e){document.body.classList.remove(...Ni),document.body.classList.add(...e)}function Hi(){c(ne).addEventListener("click",e=>{Me(),Bi()}),c(Ri).addEventListener("click",e=>{Mi()}),window.addEventListener("resize",(0,Ot.default)(e=>{Di()},100))}function Me(){return Be()?Pt():Fi()}function Be(){return document.body.classList.contains(Q.opened)||document.body.classList.contains(Q.opening)}function Fi(){Rt(),sessionStorage.setItem("sidebar_state","opened"),c(ne).setAttribute("aria-expanded","true"),requestAnimationFrame(()=>{q(Q.openingStart),requestAnimationFrame(()=>(q(Q.opening),new Promise((e,t)=>{A.togglingTimeout=setTimeout(()=>{q(Q.opened),e()},De)})))})}function Pt(){Rt(),sessionStorage.setItem("sidebar_state","closed"),c(ne).setAttribute("aria-expanded","false"),requestAnimationFrame(()=>{q(Q.closingStart),requestAnimationFrame(()=>(q(Q.closing),new Promise((e,t)=>{A.togglingTimeout=setTimeout(()=>{q(Q.closed),e()},De)})))})}function Rt(){A.togglingTimeout&&(clearTimeout(A.togglingTimeout),A.togglingTimeout=null)}function Di(){A.lastWindowWidth!==window.innerWidth&&(A.lastWindowWidth=window.innerWidth,(A.sidebarPreference===M.OPEN||A.sidebarPreference===M.NO_PREF)&&Ct())}function Mi(){At()&&Be()&&Pt()}function Bi(){switch(A.sidebarPreference){case M.OPEN:A.sidebarPreference=M.CLOSED;break;case M.CLOSED:A.sidebarPreference=M.OPEN;break;case M.NO_PREF:Be()?A.sidebarPreference=M.OPEN:A.sidebarPreference=M.CLOSED}}function ce(){return window.sidebarNodes||{}}function Nt(){return window.versionNodes||[]}var ze={search:"search",extras:"extras",modules:"modules",tasks:"tasks"},$e=[ze.extras,ze.modules,ze.tasks],Se=e=>`#${e}-full-list`;function Qt(){$e.forEach(e=>{zi(ce(),e)}),be($()),Ft(),Ht(),Gi()}function zi(e,t){let n=e[t]||[],i=c(Se(t));if(!i)return;let r=Handlebars.templates["sidebar-items"]({nodes:n,group:""});i.innerHTML=r,i.querySelectorAll("ul").forEach(s=>{if(s.innerHTML.trim()===""){let o=s.previousElementSibling;o.classList.contains("expand")&&o.classList.remove("expand"),s.remove()}}),i.querySelectorAll("li a + button").forEach(s=>{s.addEventListener("click",o=>{let l=o.target.closest("li");qi(l)})}),i.querySelectorAll("li a").forEach(s=>{s.addEventListener("click",o=>{let l=o.target.closest("li"),u=i.querySelector(".current-section");u&&ji(u),s.matches(".expand")&&s.pathname===window.location.pathname&&qe(l)})})}function qe(e){e.classList.add("open"),e.querySelector("button[aria-controls]").setAttribute("aria-expanded","true")}function $i(e){e.classList.remove("open"),e.querySelector("button[aria-controls]").setAttribute("aria-expanded","false")}function qi(e){e.classList.contains("open")?$i(e):qe(e)}function Vi(e){e.classList.add("current-section"),e.querySelector("a").setAttribute("aria-current","true")}function ji(e){e.classList.remove("current-section"),e.querySelector("a").setAttribute("aria-current","false")}function Ui(e){e.classList.add("current-hash"),e.querySelector("a").setAttribute("aria-current","true")}function Wi(e){e.classList.remove("current-hash"),e.querySelector("a").setAttribute("aria-current","false")}function be(e){$e.forEach(t=>{let n=c(`#${t}-list-tab-button`);if(n){let i=c(`#${n.getAttribute("aria-controls")}`);t===e?(n.parentElement.classList.add("selected"),n.setAttribute("aria-selected","true"),n.setAttribute("tabindex","0"),i.removeAttribute("hidden")):(n.parentElement.classList.remove("selected"),n.setAttribute("aria-selected","false"),n.setAttribute("tabindex","-1"),i.setAttribute("hidden","hidden"))}})}function Ht(){let e=c(Se($()));if(!e)return;let t=e.querySelector("li.current-page");t&&(t.scrollIntoView(),e.scrollTop-=40)}function Ft(){let e=ee()||"content",n=ce()[$()]||[],i=ht(n,e),r=c(Se($()));if(!r)return;let s=r.querySelector(`li.current-page a.expand[href$="#${i}"]`);s&&qe(s.closest("li"));let o=r.querySelector(`li.current-page a[href$="#${e}"]`);if(o){let a=o.closest("ul");a.classList.contains("deflist")&&Vi(a.closest("li")),Ui(o.closest("li"))}}function Gi(){$e.forEach(t=>{let n=c(`#${t}-list-tab-button`);n&&n.addEventListener("click",i=>{be(t),Ht()})});let e=c("#sidebar-listNav");e.addEventListener("keydown",t=>{if(t.key!=="ArrowRight"&&t.key!=="ArrowLeft")return;let n=Array.from(e.querySelectorAll('[role="tab"]')).map(r=>r.dataset.type),i=e.querySelector('[role="tab"][aria-selected="true"]').dataset.type;if(t.key==="ArrowRight"){let r=n.indexOf(i)+1;r>=n.length&&(r=0);let s=n[r];be(s),c(`#${s}-list-tab-button`).focus()}else if(t.key==="ArrowLeft"){let r=n.indexOf(i)-1;r<0&&(r=n.length-1);let s=n[r];be(s),c(`#${s}-list-tab-button`).focus()}}),window.addEventListener("hashchange",t=>{let n=c(Se($()));if(!n)return;let i=n.querySelector("li.current-page li.current-hash");i&&Wi(i),Ft()})}var B={module:"module",moduleChild:"module-child",mixTask:"mix-task",extra:"extra",section:"section"};function Mt(e,t=8){if(te(e))return[];let n=ce(),i=[...Ve(n.modules,e,B.module,"module"),...Ki(n.modules,e,B.moduleChild),...Ve(n.tasks,e,B.mixTask,"mix task"),...Ve(n.extras,e,B.extra,"page"),...je(n.modules,e,B.section,"module"),...je(n.tasks,e,B.section,"mix task"),...je(n.extras,e,B.section,"page")].filter(r=>r!==null);return nr(i).slice(0,t)}function Ve(e,t,n,i){return e.map(r=>Ji(r,t,n,i))}function Ki(e,t,n){return e.filter(i=>i.nodeGroups).flatMap(i=>i.nodeGroups.flatMap(({key:r,nodes:s})=>{let o=tr(r);return s.map(a=>Xi(a,i.id,t,n,o)||er(a,i.id,t,n,o))}))}function je(e,t,n,i){return e.flatMap(r=>Yi(r).map(s=>Zi(r,s,t,n,i)))}function Yi(e){return(e.sections||[]).concat(e.headers||[])}function Ji(e,t,n,i){return Ee(e.title,t)?{link:`${e.id}.html`,title:we(e.title,t),description:null,matchQuality:Le(e.title,t),deprecated:e.deprecated,labels:[i],category:n}:null}function Xi(e,t,n,i,r){return Ee(e.id,n)?{link:`${t}.html#${e.anchor}`,title:we(e.id,n),labels:[r],description:t,matchQuality:Le(e.id,n),deprecated:e.deprecated,category:i}:null}function Zi(e,t,n,i,r){return Bt(t.id,n)?{link:`${e.id}.html#${t.anchor}`,title:we(t.id,n),description:e.title,matchQuality:Le(t.id,n),labels:[r,"section"],category:i}:null}function er(e,t,n,i,r){let s=`${t}.${e.id}`,o=`${t}:${e.id}`,a,l;if(Ee(s,n))a=s,l=/\./g;else if(Ee(o,n))a=o,l=/:/g;else return null;let u=n.replace(l," ");return Bt(e.id,u)?{link:`${t}.html#${e.anchor}`,title:we(e.id,u),label:r,description:t,matchQuality:Le(a,n),deprecated:e.deprecated,category:i}:null}function tr(e){switch(e){case"callbacks":return"callback";case"types":return"type";default:return"function"}}function nr(e){return e.slice().sort((t,n)=>t.matchQuality!==n.matchQuality?n.matchQuality-t.matchQuality:Dt(t.category)-Dt(n.category))}function Dt(e){switch(e){case B.module:return 1;case B.moduleChild:return 2;case B.mixTask:return 3;default:return 4}}function Bt(e,t){return Te(t).some(i=>zt(e,i))}function Ee(e,t){return Te(t).every(i=>zt(e,i))}function zt(e,t){return e.toLowerCase().includes(t.toLowerCase())}function Le(e,t){let n=Te(t),r=n.map(o=>o.length).reduce((o,a)=>o+a,0)/e.length,s=ir(e,n[0])?1:0;return r+s}function ir(e,t){return e.toLowerCase().startsWith(t.toLowerCase())}function Te(e){return e.trim().split(/\s+/)}function we(e,t){let n=Te(t).sort((i,r)=>r.length-i.length);return xe(e,n)}function xe(e,t){if(t.length===0)return e;let[n,...i]=t,r=e.match(new RegExp(`(.*)(${pt(n)})(.*)`,"i"));if(r){let[,s,o,a]=r;return xe(s,t)+""+he(o)+""+xe(a,t)}else return xe(e,i)}var ke=null,G=null;function $t(){G=document.getElementById("toast"),G.addEventListener("click",e=>{clearTimeout(ke),e.target.classList.remove("show")})}function Ue(e){G&&(clearTimeout(ke),G.innerText=e,G.classList.add("show"),ke=setTimeout(()=>{G.classList.remove("show"),ke=setTimeout(function(){G.innerText=""},1e3)},5e3))}var qt="dark",We=["system","dark","light"];function Vt(e){O.getAndSubscribe(t=>{document.body.classList.toggle(qt,Ut(e||t.theme))}),sr()}function jt(){let e=We[We.indexOf(Ge())+1]||We[0];O.update({theme:e}),Ue(`Set theme to "${e}"`)}function Ge(){return O.get().theme||"system"}function Ut(e){return e==="dark"||rr()&&(e==null||e==="system")}function rr(){return window.matchMedia("(prefers-color-scheme: dark)").matches}function sr(){window.matchMedia("(prefers-color-scheme: dark)").addListener(e=>{let t=O.get().theme,n=Ut(t);(t==null||t==="system")&&(document.body.classList.toggle(qt,n),Ue(`Browser changed theme to "${n?"dark":"light"}"`))})}var ie=".autocomplete",Oe=".autocomplete-suggestions",_e=".autocomplete-suggestion",I={autocompleteSuggestions:[],previewOpen:!1,selectedIdx:-1};function or(){c(ie).classList.add("shown")}function Ke(){c(ie).classList.remove("shown")}function Wt(){return c(ie).classList.contains("shown")}function Ye(e){I.autocompleteSuggestions=Mt(e),I.selectedIdx=-1,te(e)?Ke():(ar({term:e,suggestions:I.autocompleteSuggestions}),Ie(0),or())}function ar({term:e,suggestions:t}){let n=Handlebars.templates["autocomplete-suggestions"]({suggestions:t,term:e}),i=c(ie);i.innerHTML=n}function Gt(){return I.selectedIdx===-1?null:I.autocompleteSuggestions[I.selectedIdx]}function Ie(e){Yt(cr(e))}function Kt(e){if(e.data.type==="preview"){let{contentHeight:t}=e.data,n=c(".autocomplete-preview");n&&(n.style.height=`${t+32}px`,n.classList.remove("loading"))}}function Yt(e){I.selectedIdx=e;let t=c(Oe),n=c(`${_e}.selected`),i=c(`${_e}[data-index="${I.selectedIdx}"]`);if(n&&n.classList.remove("selected"),i){if(I.previewOpen){Xt(),window.addEventListener("message",Kt),t.classList.add("previewing");let r=document.createElement("div");r.classList.add("autocomplete-preview"),r.classList.add("loading");let s=i.href.replace(".html",`.html?preview=true&theme=${Ge()}`),o=document.createElement("iframe");o.setAttribute("src",s),r.appendChild(document.createElement("div")),r.appendChild(document.createElement("span")),r.appendChild(o),i.parentNode.insertBefore(r,i.nextSibling)}i.classList.add("selected"),i.scrollIntoView({block:"nearest"})}else t&&(t.scrollTop=0)}function Jt(){I.previewOpen?Ce():Je()}function Ce(){I.previewOpen=!1;let e=c(Oe);e&&e.classList.remove("previewing"),Xt()}function Je(e){I.previewOpen=!0,e?e=e.closest(_e):e=c(`${_e}[data-index="${I.selectedIdx}"]`),e&&Yt(parseInt(e.dataset.index))}function Xt(){let e=c(".autocomplete-preview");e&&(e.remove(),window.removeEventListener("message",Kt))}function cr(e){let t=I.autocompleteSuggestions.length+1;return(I.selectedIdx+e+1+t)%t-1}var le="form.search-bar input",lr="form.search-bar .search-close-button";function nn(){ur(),window.onTogglePreviewClick=function(e,t){e.preventDefault(),e.stopImmediatePropagation(),Xe(),t?Je(e.target):Ce()}}function rn(e){let t=c(le);t.value=e}function Xe(){let e=c(le);document.body.classList.add("search-focused"),e.focus()}function ur(){let e=c(le);if(document.querySelector('meta[name="exdoc:autocomplete"][content="off"]'))return e.addEventListener("keydown",t=>{t.key==="Enter"&&Zt(t)}),!0;e.addEventListener("keydown",t=>{let n=ye();t.key==="Escape"?(Ae(),e.blur()):t.key==="Enter"?Zt(t):t.key==="ArrowUp"||n&&t.ctrlKey&&t.key==="p"?(Ie(-1),t.preventDefault()):t.key==="ArrowDown"||n&&t.ctrlKey&&t.key==="n"?(Ie(1),t.preventDefault()):t.key==="Tab"&&(Jt(),t.preventDefault())}),e.addEventListener("input",t=>{Ye(t.target.value)}),e.addEventListener("focus",t=>{document.body.classList.contains("search-focused")||(document.body.classList.add("search-focused"),Ye(t.target.value))}),e.addEventListener("blur",t=>{let n=t.relatedTarget,i=c(Oe);if(n&&i&&i.contains(n))return setTimeout(()=>{Wt()&&e.focus()},1e3),null;Pe()}),c(ie).addEventListener("click",t=>{t.shiftKey||t.ctrlKey?e.focus():(Ae(),Pe())}),c(lr).addEventListener("click",t=>{Ae(),Pe()})}function Zt(e){let t=c(le),n=e.shiftKey||e.ctrlKey,i=Gt();e.preventDefault();let r=n?"_blank":"_self",s=document.createElement("a");if(s.setAttribute("target",r),i)s.setAttribute("href",i.link);else{let o=document.querySelector('meta[name="exdoc:full-text-search-url"]'),a=o?o.getAttribute("content"):"search.html?q=";s.setAttribute("href",`${a}${encodeURIComponent(t.value)}`)}s.click(),n||(Ae(),Pe())}function Ae(){let e=c(le);e.value=""}function Pe(){Ce(),document.body.classList.remove("search-focused"),Ke()}var en=window.scrollY,tn=70;window.addEventListener("scroll",function(){let e=window.scrollY;e>tn*2&&document.body.classList.add("scroll-sticky"),e===0&&document.body.classList.remove("scroll-sticky"),e>en&&e>tn?document.body.classList.remove("scroll-sticky"):document.body.classList.add("scroll-sticky"),en=e<=0?0:e},!1);var sn=".sidebar-projectVersion",dr=".sidebar-projectVersionsDropdown";function on(){let e=Nt();if(e.length>0){let n=c(sn).textContent.trim(),i=pr(e,n);fr({nodes:i})}}function fr({nodes:e}){let t=c(sn),n=Handlebars.templates["versions-dropdown"]({nodes:e});t.innerHTML=n,c(dr).addEventListener("change",mr)}function pr(e,t){return hr(e,t).map(i=>({...i,isCurrentVersion:i.version===t}))}function hr(e,t){return e.some(i=>i.version===t)?e:[{version:t,url:"#"},...e]}function mr(e){let t=e.target.value,n=window.location.pathname.split("/").pop()+window.location.hash,i=`${t}/${n}`;gt(i).then(r=>{r?window.location.href=i:window.location.href=t})}var H=ft(ln());var Re=80,gr="#search";function dn(){if(window.location.pathname.endsWith("/search.html")){let e=mt("q");yr(e)}}async function yr(e){if(te(e))Ze({value:e});else{rn(e);let t=await vr();try{let n=e.replaceAll(/(\B|\\):/g,"\\:"),i=Or(t.search(n));Ze({value:e,results:i})}catch(n){Ze({value:e,errorMessage:n.message})}}}function Ze({value:e,results:t,errorMessage:n}){let i=c(gr),r=Handlebars.templates["search-results"]({value:e,results:t,errorMessage:n});i.innerHTML=r}async function vr(){H.default.tokenizer.separator=/\s+/,H.default.QueryLexer.termSeparator=/\s+/,H.default.Pipeline.registerFunction(pn,"docTokenSplitter"),H.default.Pipeline.registerFunction(hn,"docTrimmer");let e=await br();if(e)return e;let t=wr();return Sr(t),t}async function br(){try{let e=sessionStorage.getItem(fn());if(e){let t=await Er(e);return H.default.Index.load(t)}else return null}catch(e){return console.error("Failed to load index: ",e),null}}async function Sr(e){try{let t=await xr(e);sessionStorage.setItem(fn(),t)}catch(t){console.error("Failed to save index: ",t)}}async function xr(e){let t=new Blob([JSON.stringify(e)],{type:"application/json"}).stream().pipeThrough(new window.CompressionStream("gzip")),i=await(await new Response(t).blob()).arrayBuffer();return Lr(i)}async function Er(e){let t=new Blob([Tr(e)],{type:"application/json"}).stream().pipeThrough(new window.DecompressionStream("gzip")),n=await new Response(t).text();return JSON.parse(n)}function Lr(e){let t="",n=new Uint8Array(e),i=n.byteLength;for(let r=0;r{this.add(e)})})}function kr(e){e.pipeline.before(H.default.stemmer,pn)}function pn(e){let t=e.toString().split(/\:|\.|\/|_|-/).map(n=>e.clone().update(()=>n));return t.length>1?[...t,e]:t}function _r(e){e.pipeline.before(H.default.stemmer,hn)}function hn(e){return e.update(function(t){return t.replace(/^[^@:\w]+/,"").replace(/[^\?\!\w]+$/,"")})}function Or(e){return e.filter(t=>un(t.ref)).map(t=>{let n=un(t.ref),i=t.matchData.metadata;return{...n,metadata:i,excerpts:Ir(n,i)}})}function un(e){return searchData.items.find(t=>t.ref===e)||null}function Ir(e,t){let{doc:n}=e,r=Object.keys(t).filter(s=>"doc"in t[s]).map(s=>t[s].doc.position.map(([o,a])=>Cr(n,o,a))).reduce((s,o)=>s.concat(o),[]);return r.length===0?[n.slice(0,Re*2)+(Re*20?"...":"",e.slice(i,t),""+he(e.slice(t,t+n))+"",e.slice(t+n,r),r{let n=t.getAttribute("data-group-id");t.addEventListener("mouseenter",i=>{mn(n,!0)}),t.addEventListener("mouseleave",i=>{mn(n,!1)})})}function mn(e,t){k(`[data-group-id="${e}"]`).forEach(i=>{i.classList.toggle(Ar,t)})}var K=".modal",Rr=".modal .modal-close",Nr=".modal .modal-title",Qr=".modal .modal-body",yn='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])',z={prevFocus:null,lastFocus:null,ignoreFocusChanges:!1};function vn(){Hr()}function Hr(){let e=Handlebars.templates["modal-layout"]();document.body.insertAdjacentHTML("beforeend",e),c(K).addEventListener("keydown",t=>{t.key==="Escape"&&re()}),c(Rr).addEventListener("click",t=>{re()}),c(K).addEventListener("click",t=>{t.target.classList.contains("modal")&&re()})}function bn(e){if(z.ignoreFocusChanges)return;let t=c(K);if(t.contains(e.target))z.lastFocus=e.target;else{z.ignoreFocusChanges=!0;let n=Fr(t);z.lastFocus===n?Dr(t).focus():n.focus(),z.ignoreFocusChanges=!1,z.lastFocus=document.activeElement}}function Fr(e){return e.querySelector(yn)}function Dr(e){let t=e.querySelectorAll(yn);return t[t.length-1]}function Ne({title:e,body:t}){z.prevFocus=document.activeElement,document.addEventListener("focus",bn,!0),c(Nr).innerHTML=e,c(Qr).innerHTML=t,c(K).classList.add("shown"),c(K).focus()}function re(){c(K).classList.remove("shown"),document.addEventListener("focus",bn,!0),z.prevFocus&&z.prevFocus.focus(),z.prevFocus=null}function Sn(){return c(K).classList.contains("shown")}var Mr="https://hexdocs.pm/%%",Br="https://hex.pm/api/packages?search=name:%%*",zr=".display-quick-switch",et="#quick-switch-input",En="#quick-switch-results",$r=".quick-switch-result",qr=300,Vr=9,jr=["elixir","eex","ex_unit","hex","iex","logger","mix"].map(e=>({name:e})),Ln=2,P={autocompleteResults:[],selectedIdx:null};function Tn(){Ur()}function Ur(){k(zr).forEach(e=>{e.addEventListener("click",t=>{nt()})})}function Wr(e){if(e.key==="Enter"){let t=e.target.value;Kr(t),e.preventDefault()}else e.key==="ArrowUp"?(xn(-1),e.preventDefault()):e.key==="ArrowDown"&&(xn(1),e.preventDefault())}function Gr(e){let t=e.target.value;if(t.lengthn.json()).then(n=>{Array.isArray(n)&&(P.autocompleteResults=Zr(e,n),P.selectedIdx=null,c(et).value.length>=Ln&&Xr({results:P.autocompleteResults}))})}function Xr({results:e}){let t=c(En),n=Handlebars.templates["quick-switch-results"]({results:e});t.innerHTML=n,k($r).forEach(i=>{i.addEventListener("click",r=>{let s=i.getAttribute("data-index"),o=P.autocompleteResults[s];tt(o.name)})})}function Zr(e,t){return jr.concat(t).filter(n=>n.name.toLowerCase().includes(e.toLowerCase())).filter(n=>n.releases===void 0||n.releases[0].has_docs===!0).slice(0,Vr)}function xn(e){P.selectedIdx=es(e);let t=c(".quick-switch-result.selected"),n=c(`.quick-switch-result[data-index="${P.selectedIdx}"]`);t&&t.classList.remove("selected"),n&&n.classList.add("selected")}function es(e){let t=P.autocompleteResults.length;if(P.selectedIdx===null){if(e>=0)return 0;if(e<0)return t-1}return(P.selectedIdx+e+t)%t}var ts=".display-settings",ns="#settings-modal-content",it="#modal-settings-tab",rt="#modal-keyboard-shortcuts-tab",kn="#settings-content",_n="#keyboard-shortcuts-content",is=[{title:"Settings",id:"modal-settings-tab"},{title:"Keyboard shortcuts",id:"modal-keyboard-shortcuts-tab"}];function On(){rs()}function rs(){k(ts).forEach(e=>{e.addEventListener("click",t=>{st()})})}function wn(){c(rt).classList.remove("active"),c(it).classList.add("active"),c(kn).classList.remove("hidden"),c(_n).classList.add("hidden")}function ss(){c(rt).classList.add("active"),c(it).classList.remove("active"),c(_n).classList.remove("hidden"),c(kn).classList.add("hidden")}function st(){Ne({title:is.map(({id:s,title:o})=>``).join(""),body:Handlebars.templates["settings-modal-body"]({shortcuts:ot})});let e=c(ns),t=e.querySelector('[name="theme"]'),n=e.querySelector('[name="tooltips"]'),i=e.querySelector('[name="direct_livebook_url"]'),r=e.querySelector('[name="livebook_url"]');O.getAndSubscribe(s=>{t.value=s.theme||"system",n.checked=s.tooltips,s.livebookUrl===null?(i.checked=!1,r.classList.add("hidden"),r.tabIndex=-1):(i.checked=!0,r.classList.remove("hidden"),r.tabIndex=0,r.value=s.livebookUrl)}),t.addEventListener("change",s=>{O.update({theme:s.target.value})}),n.addEventListener("change",s=>{O.update({tooltips:s.target.checked})}),i.addEventListener("change",s=>{let o=s.target.checked?r.value:null;O.update({livebookUrl:o})}),r.addEventListener("input",s=>{O.update({livebookUrl:s.target.value})}),c(it).addEventListener("click",s=>{wn()}),c(rt).addEventListener("click",s=>{ss()}),wn()}var os="#settings-modal-content",ot=[{key:"c",description:"Toggle sidebar",action:Me},{key:"n",description:"Cycle themes",action:jt},{key:"s",description:"Focus search bar",displayAs:"/ or s",action:at},{key:"/",action:at},{key:"k",hasModifier:!0,action:at},{key:"g",description:"Search HexDocs package",displayAs:"g",action:nt},{key:"?",displayAs:"?",description:"Bring up this modal",action:us}],ct={shortcutBeingPressed:null};function In(){as()}function as(){document.addEventListener("keydown",cs),document.addEventListener("keyup",ls)}function cs(e){if(ct.shortcutBeingPressed||e.target.matches("input, textarea"))return;let t=ot.find(n=>n.hasModifier?ye()&&e.metaKey||e.ctrlKey?n.key===e.key:!1:e.ctrlKey||e.metaKey||e.altKey?!1:n.key===e.key);t&&(ct.shortcutBeingPressed=t,e.preventDefault(),t.action(e))}function ls(e){ct.shortcutBeingPressed=null}function at(e){re(),Xe()}function us(){ds()?re():st()}function ds(){return Sn()&&c(os)}var Y={plain:"plain",function:"function",module:"module"},fs=[{href:"typespecs.html#basic-types",hint:{kind:Y.plain,description:"Basic type"}},{href:"typespecs.html#literals",hint:{kind:Y.plain,description:"Literal"}},{href:"typespecs.html#built-in-types",hint:{kind:Y.plain,description:"Built-in type"}}],Qe={cancelHintFetching:null};function Cn(e){if(Pn(e))return!0;let t=/#.*\//;return e.includes("#")&&!t.test(e)?!1:e.includes(".html")}function An(e){let t=Pn(e);return t?Promise.resolve(t):ps(e)}function Pn(e){let t=fs.find(n=>e.includes(n.href));return t?t.hint:null}function ps(e){let t=e.replace(".html",".html?hint=true");return new Promise((n,i)=>{let r=document.createElement("iframe");r.setAttribute("src",t),r.style.display="none";function s(a){let{href:l,hint:u}=a.data;t===l&&(o(),n(u))}Qe.cancelHintFetching=()=>{o(),i(new Error("cancelled"))};function o(){r.remove(),window.removeEventListener("message",s),Qe.cancelHintFetching=null}window.addEventListener("message",s),document.body.appendChild(r)})}function Rn(){Qe.cancelHintFetching&&Qe.cancelHintFetching()}function Nn(e){let n=e.querySelector("h1").textContent,i=e.querySelector(".docstring > p"),r=i?i.innerHTML:"";return{kind:Y.function,title:n.trim(),description:r.trim()}}function Qn(e){let n=e.querySelector("h1 > span").textContent,i=e.querySelector("#moduledoc p"),r=i?i.innerHTML:"";return{kind:Y.module,title:n.trim(),description:r.trim()}}var hs=".content a",lt=".tooltip",ms=".tooltip .tooltip-body",Fn="body .content-inner",gs="#content",Dn="tooltip-shown",ue=10,ys=ue*4,Hn={height:450,width:768},vs=100,se={currentLinkElement:null,hoverDelayTimeout:null};function Mn(){bs(),Ss()}function bs(){let e=Handlebars.templates["tooltip-layout"]();c(Fn).insertAdjacentHTML("beforeend",e)}function Ss(){k(hs).forEach(e=>{xs(e)&&(e.addEventListener("mouseenter",t=>{Ls(e)}),e.addEventListener("mouseleave",t=>{_s(e)}))})}function xs(e){return!(e.getAttribute("data-no-tooltip")!==null||Es(e.href)||!Cn(e.href))}function Es(e){let t=e.replace(gs,"");return window.location.href.split("#")[0]===t}function Ls(e){Ts()&&(se.currentLinkElement=e,se.hoverDelayTimeout=setTimeout(()=>{An(e.href).then(t=>{ws(t),ks()}).catch(()=>{})},vs))}function Ts(){let e=window.innerWidthe.firstElementChild&&e.firstElementChild.tagName==="CODE").forEach(e=>e.insertAdjacentHTML("beforeend",Hs)),Array.from(k(".copy-button")).forEach(e=>{let t;e.addEventListener("click",()=>{let n=e.querySelector("[aria-live]");t&&clearTimeout(t);let i=Array.from(e.parentElement.querySelector("code").childNodes).filter(r=>!(r.tagName==="SPAN"&&r.classList.contains("unselectable"))).map(r=>r.textContent).join("");navigator.clipboard.writeText(i),e.classList.add("clicked"),n.innerHTML="Copied! ✓",t=setTimeout(()=>{e.classList.remove("clicked"),n.innerHTML=""},3e3)})})}function Vn(){let t=/(Macintosh|iPhone|iPad|iPod)/.test(window.navigator.userAgent)?"apple-os":"non-apple-os";document.documentElement.classList.add(t)}var Ds="content",Ms="tabs-open",Bs="tabs-close",zs="H3",$s="tabset";function Un(){qs().map(Vs).forEach(n=>Ws(n))}function qs(){let e=document.createNodeIterator(document.getElementById(Ds),NodeFilter.SHOW_COMMENT,{acceptNode(i){return i.nodeValue.trim()===Ms?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}}),t=[],n;for(;n=e.nextNode();)t.push(n);return t}function Vs(e,t,n){let i=[],r=[],s={label:"",content:[]};for(;e=e.nextSibling;){if(js(e)){jn(s,r,t);break}i.push(e),e.nodeName===zs?(jn(s,r,t),s.label=e.innerText,s.content=[]):s.content.push(e.outerHTML)}let o=document.createElement("div");return o.className=$s,Us(i,o),o.innerHTML=Handlebars.templates.tabset({tabs:r}),o}function js(e){return e.nodeName==="#comment"&&e.nodeValue.trim()===Bs}function jn(e,t,n){if(e.label===""&&!e.content.length)return!1;let i=e.label,r=e.content;t.push({label:i,content:r,setIndex:n})}function Us(e,t){if(!e||!e.length)return!1;e[0].parentNode.insertBefore(t,e[0]),e.forEach(n=>t.appendChild(n))}function Ws(e){let t={tabs:e.querySelectorAll(':scope [role="tab"]'),panels:e.querySelectorAll(':scope [role="tabpanel"]'),activeIndex:0};t.tabs.forEach((n,i)=>{n.addEventListener("click",r=>{J(i,t)}),n.addEventListener("keydown",r=>{let s=t.tabs.length-1;r.code==="ArrowLeft"?(r.preventDefault(),t.activeIndex===0?J(s,t):J(t.activeIndex-1,t)):r.code==="ArrowRight"?(r.preventDefault(),t.activeIndex===s?J(0,t):J(t.activeIndex+1,t)):r.code==="Home"?(r.preventDefault(),J(0,t)):r.code==="End"&&(r.preventDefault(),J(s,t))})})}function J(e,t){t.tabs[t.activeIndex].setAttribute("aria-selected","false"),t.tabs[t.activeIndex].tabIndex=-1,t.tabs[e].setAttribute("aria-selected","true"),t.tabs[e].tabIndex=0,t.tabs[e].focus(),t.panels[t.activeIndex].setAttribute("hidden",""),t.panels[t.activeIndex].tabIndex=-1,t.panels[e].removeAttribute("hidden"),t.panels[e].tabIndex=0,t.activeIndex=e}function Gn(){let e=me(ee(),!0);e&&Gs(e)}function Gs(e){Js(e),Ks(),Ys(),Wn(),window.addEventListener("resize",t=>{Wn()})}function Wn(){let e=document.body.scrollHeight,t=document.getElementById("content").parentElement.offsetHeight,n={type:"preview",maxHeight:e,contentHeight:t};window.parent.postMessage(n,"*")}function Ks(){let e=document.getElementsByTagName("a");for(let t of e)t.getAttribute("target")!=="_blank"&&t.setAttribute("target","_parent")}function Ys(){window.scrollTo(0,0)}function Js(e){document.body.classList.add("preview");let t=document.getElementById("content");t.innerHTML=e.innerHTML}yt(()=>{let e=new URLSearchParams(window.location.search),t=e.has("preview");Vt(e.get("theme")),xt(t),gn(),Mn(),$n(),qn(),Vn(),Un(),t?Gn():(on(),It(),Qt(),nn(),vn(),In(),Tn(),$t(),dn(),On())});})(); -/*! Bundled license information: - -lunr/lunr.js: - (** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - *) - (*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - *) - (*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - *) -*/ diff --git a/dist/html-YIPIRHGU.js b/dist/html-YIPIRHGU.js new file mode 100644 index 0000000..c080222 --- /dev/null +++ b/dist/html-YIPIRHGU.js @@ -0,0 +1,56 @@ +(()=>{var ii=Object.create;var pt=Object.defineProperty;var ri=Object.getOwnPropertyDescriptor;var si=Object.getOwnPropertyNames;var oi=Object.getPrototypeOf,ai=Object.prototype.hasOwnProperty;var ht=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var ci=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of si(t))!ai.call(e,r)&&r!==n&&pt(e,r,{get:()=>t[r],enumerable:!(i=ri(t,r))||i.enumerable});return e};var mt=(e,t,n)=>(n=e!=null?ii(oi(e)):{},ci(t||!e||!e.__esModule?pt(n,"default",{value:e,enumerable:!0}):n,e));var It=ht((co,_t)=>{var Ot="Expected a function",wt=NaN,bi="[object Symbol]",Si=/^\s+|\s+$/g,xi=/^[-+]0x[0-9a-f]+$/i,Ei=/^0b[01]+$/i,Li=/^0o[0-7]+$/i,Ti=parseInt,wi=typeof global=="object"&&global&&global.Object===Object&&global,ki=typeof self=="object"&&self&&self.Object===Object&&self,Oi=wi||ki||Function("return this")(),_i=Object.prototype,Ii=_i.toString,Ci=Math.max,Ai=Math.min,Fe=function(){return Oi.Date.now()};function Pi(e,t,n){var i,r,s,o,a,l,u=0,f=!1,y=!1,g=!0;if(typeof e!="function")throw new TypeError(Ot);t=kt(t)||0,ve(n)&&(f=!!n.leading,y="maxWait"in n,s=y?Ci(kt(n.maxWait)||0,t):s,g="trailing"in n?!!n.trailing:g);function L(S){var C=i,D=r;return i=r=void 0,u=S,o=e.apply(D,C),o}function b(S){return u=S,a=setTimeout(h,t),f?L(S):o}function T(S){var C=S-l,D=S-u,V=t-C;return y?Ai(V,s-D):V}function m(S){var C=S-l,D=S-u;return l===void 0||C>=t||C<0||y&&D>=s}function h(){var S=Fe();if(m(S))return O(S);a=setTimeout(h,T(S))}function O(S){return a=void 0,g&&i?L(S):(i=r=void 0,o)}function w(){a!==void 0&&clearTimeout(a),u=0,i=l=r=a=void 0}function Q(){return a===void 0?o:O(Fe())}function F(){var S=Fe(),C=m(S);if(i=arguments,r=this,l=S,C){if(a===void 0)return b(l);if(y)return a=setTimeout(h,t),L(l)}return a===void 0&&(a=setTimeout(h,t)),o}return F.cancel=w,F.flush=Q,F}function Ri(e,t,n){var i=!0,r=!0;if(typeof e!="function")throw new TypeError(Ot);return ve(n)&&(i="leading"in n?!!n.leading:i,r="trailing"in n?!!n.trailing:r),Pi(e,t,{leading:i,maxWait:t,trailing:r})}function ve(e){var t=typeof e;return!!e&&(t=="object"||t=="function")}function Ni(e){return!!e&&typeof e=="object"}function Qi(e){return typeof e=="symbol"||Ni(e)&&Ii.call(e)==bi}function kt(e){if(typeof e=="number")return e;if(Qi(e))return wt;if(ve(e)){var t=typeof e.valueOf=="function"?e.valueOf():e;e=ve(t)?t+"":t}if(typeof e!="string")return e===0?e:+e;e=e.replace(Si,"");var n=Ei.test(e);return n||Li.test(e)?Ti(e.slice(2),n?2:8):xi.test(e)?wt:+e}_t.exports=Ri});var pn=ht((dn,fn)=>{(function(){var e=function(t){var n=new e.Builder;return n.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),n.searchPipeline.add(e.stemmer),t.call(n,n),n.build()};e.version="2.3.9";e.utils={},e.utils.warn=function(t){return function(n){t.console&&console.warn&&console.warn(n)}}(this),e.utils.asString=function(t){return t==null?"":t.toString()},e.utils.clone=function(t){if(t==null)return t;for(var n=Object.create(null),i=Object.keys(t),r=0;r0){var f=e.utils.clone(n)||{};f.position=[a,u],f.index=s.length,s.push(new e.Token(i.slice(a,o),f))}a=o+1}}return s},e.tokenizer.separator=/[\s\-]+/;e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions=Object.create(null),e.Pipeline.registerFunction=function(t,n){n in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+n),t.label=n,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var n=t.label&&t.label in this.registeredFunctions;n||e.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,t)},e.Pipeline.load=function(t){var n=new e.Pipeline;return t.forEach(function(i){var r=e.Pipeline.registeredFunctions[i];if(r)n.add(r);else throw new Error("Cannot load unregistered function: "+i)}),n},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(n){e.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},e.Pipeline.prototype.after=function(t,n){e.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");i=i+1,this._stack.splice(i,0,n)},e.Pipeline.prototype.before=function(t,n){e.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},e.Pipeline.prototype.remove=function(t){var n=this._stack.indexOf(t);n!=-1&&this._stack.splice(n,1)},e.Pipeline.prototype.run=function(t){for(var n=this._stack.length,i=0;i1&&(ot&&(i=s),o!=t);)r=i-n,s=n+Math.floor(r/2),o=this.elements[s*2];if(o==t||o>t)return s*2;if(ol?f+=2:a==l&&(n+=i[u+1]*r[f+1],u+=2,f+=2);return n},e.Vector.prototype.similarity=function(t){return this.dot(t)/this.magnitude()||0},e.Vector.prototype.toArray=function(){for(var t=new Array(this.elements.length/2),n=1,i=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new e.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),r.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new e.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),r.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&r.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new e.TokenSet;s.node.edges["*"]=u}s.str.length==1&&(u.final=!0),r.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var f=s.str.charAt(0),y=s.str.charAt(1),g;y in s.node.edges?g=s.node.edges[y]:(g=new e.TokenSet,s.node.edges[y]=g),s.str.length==1&&(g.final=!0),r.push({node:g,editsRemaining:s.editsRemaining-1,str:f+s.str.slice(2)})}}}return i},e.TokenSet.fromString=function(t){for(var n=new e.TokenSet,i=n,r=0,s=t.length;r=t;n--){var i=this.uncheckedNodes[n],r=i.child.toString();r in this.minimizedNodes?i.parent.edges[i.char]=this.minimizedNodes[r]:(i.child._str=r,this.minimizedNodes[r]=i.child),this.uncheckedNodes.pop()}};e.Index=function(t){this.invertedIndex=t.invertedIndex,this.fieldVectors=t.fieldVectors,this.tokenSet=t.tokenSet,this.fields=t.fields,this.pipeline=t.pipeline},e.Index.prototype.search=function(t){return this.query(function(n){var i=new e.QueryParser(t,n);i.parse()})},e.Index.prototype.query=function(t){for(var n=new e.Query(this.fields),i=Object.create(null),r=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l1?this._b=1:this._b=t},e.Builder.prototype.k1=function(t){this._k1=t},e.Builder.prototype.add=function(t,n){var i=t[this._ref],r=Object.keys(this._fields);this._documents[i]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){var t,n;do t=this.next(),n=t.charCodeAt(0);while(n>47&&n<58);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos1&&(t.backup(),t.emit(e.QueryLexer.TERM)),t.ignore(),t.more())return e.QueryLexer.lexText},e.QueryLexer.lexEditDistance=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.EDIT_DISTANCE),e.QueryLexer.lexText},e.QueryLexer.lexBoost=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.BOOST),e.QueryLexer.lexText},e.QueryLexer.lexEOS=function(t){t.width()>0&&t.emit(e.QueryLexer.TERM)},e.QueryLexer.termSeparator=e.tokenizer.separator,e.QueryLexer.lexText=function(t){for(;;){var n=t.next();if(n==e.QueryLexer.EOS)return e.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){t.escapeCharacter();continue}if(n==":")return e.QueryLexer.lexField;if(n=="~")return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexEditDistance;if(n=="^")return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexBoost;if(n=="+"&&t.width()===1||n=="-"&&t.width()===1)return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if(n.match(e.QueryLexer.termSeparator))return e.QueryLexer.lexTerm}},e.QueryParser=function(t,n){this.lexer=new e.QueryLexer(t),this.query=n,this.currentClause={},this.lexemeIdx=0},e.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var t=e.QueryParser.parseClause;t;)t=t(this);return this.query},e.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},e.QueryParser.prototype.consumeLexeme=function(){var t=this.peekLexeme();return this.lexemeIdx+=1,t},e.QueryParser.prototype.nextClause=function(){var t=this.currentClause;this.query.clause(t),this.currentClause={}},e.QueryParser.parseClause=function(t){var n=t.peekLexeme();if(n!=null)switch(n.type){case e.QueryLexer.PRESENCE:return e.QueryParser.parsePresence;case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(i+=" with value '"+n.str+"'"),new e.QueryParseError(i,n.start,n.end)}},e.QueryParser.parsePresence=function(t){var n=t.consumeLexeme();if(n!=null){switch(n.str){case"-":t.currentClause.presence=e.Query.presence.PROHIBITED;break;case"+":t.currentClause.presence=e.Query.presence.REQUIRED;break;default:var i="unrecognised presence operator'"+n.str+"'";throw new e.QueryParseError(i,n.start,n.end)}var r=t.peekLexeme();if(r==null){var i="expecting term or field, found nothing";throw new e.QueryParseError(i,n.start,n.end)}switch(r.type){case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expecting term or field, found '"+r.type+"'";throw new e.QueryParseError(i,r.start,r.end)}}},e.QueryParser.parseField=function(t){var n=t.consumeLexeme();if(n!=null){if(t.query.allFields.indexOf(n.str)==-1){var i=t.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),r="unrecognised field '"+n.str+"', possible fields: "+i;throw new e.QueryParseError(r,n.start,n.end)}t.currentClause.fields=[n.str];var s=t.peekLexeme();if(s==null){var r="expecting term, found nothing";throw new e.QueryParseError(r,n.start,n.end)}switch(s.type){case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var r="expecting term, found '"+s.type+"'";throw new e.QueryParseError(r,s.start,s.end)}}},e.QueryParser.parseTerm=function(t){var n=t.consumeLexeme();if(n!=null){t.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(t.currentClause.usePipeline=!1);var i=t.peekLexeme();if(i==null){t.nextClause();return}switch(i.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+i.type+"'";throw new e.QueryParseError(r,i.start,i.end)}}},e.QueryParser.parseEditDistance=function(t){var n=t.consumeLexeme();if(n!=null){var i=parseInt(n.str,10);if(isNaN(i)){var r="edit distance must be numeric";throw new e.QueryParseError(r,n.start,n.end)}t.currentClause.editDistance=i;var s=t.peekLexeme();if(s==null){t.nextClause();return}switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(r,s.start,s.end)}}},e.QueryParser.parseBoost=function(t){var n=t.consumeLexeme();if(n!=null){var i=parseInt(n.str,10);if(isNaN(i)){var r="boost must be numeric";throw new e.QueryParseError(r,n.start,n.end)}t.currentClause.boost=i;var s=t.peekLexeme();if(s==null){t.nextClause();return}switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(r,s.start,s.end)}}},function(t,n){typeof define=="function"&&define.amd?define(n):typeof dn=="object"?fn.exports=n():t.lunr=n()}(this,function(){return e})})()});Handlebars.registerHelper("groupChanged",function(e,t,n){let i=t||"";if(e.group!==i)return delete e.nestedContext,e.group=i,n.fn(this)});Handlebars.registerHelper("nestingChanged",function(e,t,n){if(t.nested_context&&t.nested_context!==e.nestedContext){if(e.nestedContext=t.nested_context,e.lastModuleSeenInGroup!==t.nested_context)return n.fn(this)}else e.lastModuleSeenInGroup=t.title});Handlebars.registerHelper("showSections",function(e,t){if(e.sections.length>0)return t.fn(this)});Handlebars.registerHelper("showSummary",function(e,t){if(e.nodeGroups)return t.fn(this)});Handlebars.registerHelper("isArray",function(e,t){return Array.isArray(e)?t.fn(this):t.inverse(this)});Handlebars.registerHelper("isNonEmptyArray",function(e,t){return Array.isArray(e)&&e.length>0?t.fn(this):t.inverse(this)});Handlebars.registerHelper("isEmptyArray",function(e,t){return Array.isArray(e)&&e.length===0?t.fn(this):t.inverse(this)});Handlebars.registerHelper("isLocal",function(e,t){let n=window.location.pathname.split("/").pop();return n===e+".html"||n===e?t.fn(this):t.inverse(this)});var c=document.querySelector.bind(document),k=document.querySelectorAll.bind(document);function gt(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function me(e){return String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""")}function $(){return document.body.dataset.type}function yt(e,t){if(e){for(let n of e){let i=n.nodeGroups&&n.nodeGroups.find(r=>r.nodes.some(s=>s.anchor===t));if(i)return i.key}return null}}function ge(e,t=!1){if(!e)return t?document.getElementById("top-content"):null;let n=document.getElementById(e);return n?n.matches(".detail")?n:["h1","h2","h3","h4","h5","h6"].includes(n.tagName.toLowerCase())?li(n):null:null}function li(e){let t=[e],n=e.nextElementSibling,i=e.tagName.toLowerCase();for(;n;){let s=n.tagName.toLowerCase();["h1","h2","h3","h4","h5","h6"].includes(s)&&s<=i?n=null:(t.push(n),n=n.nextElementSibling)}let r=document.createElement("div");return r.append(...t),r}function te(){return window.location.hash.replace(/^#/,"")}function vt(e){return new URLSearchParams(window.location.search).get(e)}function bt(e){return fetch(e).then(t=>t.ok).catch(()=>!1)}function St(e){document.readyState!=="loading"?e():document.addEventListener("DOMContentLoaded",e)}function ne(e){return!e||e.trim()===""}function xt(e,t){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>{n=null,e(...r)},t)}}function ye(){return document.head.querySelector("meta[name=project][content]").content}function ie(){return/(Macintosh|iPhone|iPad|iPod)/.test(window.navigator.userAgent)}var Et="ex_doc:settings",ui={tooltips:!0,theme:null,livebookUrl:null},He=class{constructor(){this._subscribers=[],this._settings=ui,this._loadSettings()}get(){return this._settings}update(t){let n=this._settings;this._settings={...this._settings,...t},this._subscribers.forEach(i=>i(this._settings,n)),this._storeSettings()}getAndSubscribe(t){this._subscribers.push(t),t(this._settings)}_loadSettings(){try{let t=localStorage.getItem(Et);if(t){let n=JSON.parse(t);this._settings={...this._settings,...n}}this._loadSettingsLegacy()}catch(t){console.error(`Failed to load settings: ${t}`)}}_storeSettings(){try{this._storeSettingsLegacy(),localStorage.setItem(Et,JSON.stringify(this._settings))}catch(t){console.error(`Failed to persist settings: ${t}`)}}_loadSettingsLegacy(){localStorage.getItem("tooltipsDisabled")!==null&&(this._settings={...this._settings,tooltips:!1}),localStorage.getItem("night-mode")==="true"&&(this._settings={...this._settings,nightMode:!0}),this._settings.nightMode===!0&&(this._settings={...this._settings,theme:"dark"})}_storeSettingsLegacy(){this._settings.tooltips?localStorage.removeItem("tooltipsDisabled"):localStorage.setItem("tooltipsDisabled","true"),this._settings.nightMode!==null?localStorage.setItem("night-mode",this._settings.nightMode===!0?"true":"false"):localStorage.removeItem("night-mode"),this._settings.theme!==null?(localStorage.setItem("night-mode",this._settings.theme==="dark"?"true":"false"),this._settings.nightMode=this._settings.theme==="dark"):(delete this._settings.nightMode,localStorage.removeItem("night-mode"))}},_=new He;var di=".content",Lt=".content-inner",fi=".livebook-badge";function Tt(e){e||mi(),gi(),pi(),hi()}function pi(){c(di).querySelectorAll("a").forEach(e=>{e.querySelector("code, img")&&e.classList.add("no-underline")})}function hi(){["warning","info","error","neutral","tip"].forEach(t=>{k(`blockquote h3.${t}, blockquote h4.${t}`).forEach(n=>{n.closest("blockquote").classList.add(t)})})}function mi(){c(Lt).setAttribute("tabindex",-1),c(Lt).focus()}function gi(){let t=window.location.pathname.replace(/(\.html)?$/,".livemd"),n=new URL(t,window.location.href).toString();_.getAndSubscribe(i=>{let r=i.livebookUrl?vi(i.livebookUrl,n):yi(n);for(let s of k(fi))s.href=r})}function yi(e){return`https://livebook.dev/run?url=${encodeURIComponent(e)}`}function vi(e,t){return`${e}/import?url=${encodeURIComponent(t)}`}var At=mt(It());var Hi=768,De=300,re=".sidebar-toggle",Fi=".content",M={CLOSED:"closed",OPEN:"open",NO_PREF:"no_pref"},N={opened:"sidebar-opened",openingStart:"sidebar-opening-start",opening:"sidebar-opening",closed:"sidebar-closed",closingStart:"sidebar-closing-start",closing:"sidebar-closing"},Di=Object.values(N),A={togglingTimeout:null,lastWindowWidth:window.innerWidth,sidebarPreference:M.NO_PREF};function Pt(){Rt(),Mi(),Bi()}function Mi(){let e=sessionStorage.getItem("sidebar_width");e&&Ct(e),new ResizeObserver(n=>{for(let i of n)Ct(i.contentRect.width)}).observe(document.getElementById("sidebar"))}function Ct(e){sessionStorage.setItem("sidebar_width",e),document.body.style.setProperty("--sidebarWidth",`${e}px`)}function Rt(){sessionStorage.getItem("sidebar_state")==="closed"||Nt()?(q(N.closed),c(re).setAttribute("aria-expanded","false")):(q(N.opened),c(re).setAttribute("aria-expanded","true")),setTimeout(()=>c(re).classList.add("sidebar-toggle--animated"),De)}function Nt(){return window.matchMedia(`screen and (max-width: ${Hi}px)`).matches}function q(...e){document.body.classList.remove(...Di),document.body.classList.add(...e)}function Bi(){c(re).addEventListener("click",e=>{Me(),qi()}),c(Fi).addEventListener("click",e=>{$i()}),window.addEventListener("resize",(0,At.default)(e=>{zi()},100))}function Me(){return Be()?Ht():ze()}function Be(){return document.body.classList.contains(N.opened)||document.body.classList.contains(N.opening)}function Qt(){return document.body.classList.contains(N.opened)}function ze(){return Ft(),sessionStorage.setItem("sidebar_state","opened"),c(re).setAttribute("aria-expanded","true"),new Promise((e,t)=>{requestAnimationFrame(()=>{q(N.openingStart),requestAnimationFrame(()=>{q(N.opening),A.togglingTimeout=setTimeout(()=>{q(N.opened),e()},De)})})})}function Ht(){return Ft(),sessionStorage.setItem("sidebar_state","closed"),c(re).setAttribute("aria-expanded","false"),new Promise((e,t)=>{requestAnimationFrame(()=>{q(N.closingStart),requestAnimationFrame(()=>{q(N.closing),A.togglingTimeout=setTimeout(()=>{q(N.closed),e()},De)})})})}function Ft(){A.togglingTimeout&&(clearTimeout(A.togglingTimeout),A.togglingTimeout=null)}function zi(){A.lastWindowWidth!==window.innerWidth&&(A.lastWindowWidth=window.innerWidth,(A.sidebarPreference===M.OPEN||A.sidebarPreference===M.NO_PREF)&&Rt())}function $i(){Nt()&&Be()&&Ht()}function qi(){switch(A.sidebarPreference){case M.OPEN:A.sidebarPreference=M.CLOSED;break;case M.CLOSED:A.sidebarPreference=M.OPEN;break;case M.NO_PREF:Be()?A.sidebarPreference=M.OPEN:A.sidebarPreference=M.CLOSED}}function le(){return window.sidebarNodes||{}}function Dt(){return window.versionNodes||[]}var $e={search:"search",extras:"extras",modules:"modules",tasks:"tasks"},qe=[$e.extras,$e.modules,$e.tasks],Se=e=>`#${e}-full-list`;function Mt(){qe.forEach(e=>{Vi(le(),e)}),be($()),zt(),Bt(),Ji()}function Vi(e,t){let n=e[t]||[],i=c(Se(t));if(!i)return;let r=Handlebars.templates["sidebar-items"]({nodes:n,group:""});i.innerHTML=r,i.querySelectorAll("ul").forEach(s=>{if(s.innerHTML.trim()===""){let o=s.previousElementSibling;o.classList.contains("expand")&&o.classList.remove("expand"),s.remove()}}),i.querySelectorAll("li a + button").forEach(s=>{s.addEventListener("click",o=>{let l=o.target.closest("li");Ui(l)})}),i.querySelectorAll("li a").forEach(s=>{s.addEventListener("click",o=>{let l=o.target.closest("li"),u=i.querySelector(".current-section");u&&Gi(u),s.matches(".expand")&&(s.pathname===window.location.pathname||s.pathname===window.location.pathname+".html")&&Ve(l)})})}function Ve(e){e.classList.add("open"),e.querySelector("button[aria-controls]").setAttribute("aria-expanded","true")}function ji(e){e.classList.remove("open"),e.querySelector("button[aria-controls]").setAttribute("aria-expanded","false")}function Ui(e){e.classList.contains("open")?ji(e):Ve(e)}function Wi(e){e.classList.add("current-section"),e.querySelector("a").setAttribute("aria-current","true")}function Gi(e){e.classList.remove("current-section"),e.querySelector("a").setAttribute("aria-current","false")}function Ki(e){e.classList.add("current-hash"),e.querySelector("a").setAttribute("aria-current","true")}function Yi(e){e.classList.remove("current-hash"),e.querySelector("a").setAttribute("aria-current","false")}function be(e){qe.forEach(t=>{let n=c(`#${t}-list-tab-button`);if(n){let i=c(`#${n.getAttribute("aria-controls")}`);t===e?(n.parentElement.classList.add("selected"),n.setAttribute("aria-selected","true"),n.setAttribute("tabindex","0"),i.removeAttribute("hidden")):(n.parentElement.classList.remove("selected"),n.setAttribute("aria-selected","false"),n.setAttribute("tabindex","-1"),i.setAttribute("hidden","hidden"))}})}function Bt(){let e=c(Se($()));if(!e)return;let t=e.querySelector("li.current-page");t&&(t.scrollIntoView(),e.scrollTop-=40)}function zt(){let e=te()||"content",n=le()[$()]||[],i=yt(n,e),r=c(Se($()));if(!r)return;let s=r.querySelector(`li.current-page a.expand[href$="#${i}"]`);s&&Ve(s.closest("li"));let o=r.querySelector(`li.current-page a[href$="#${e}"]`);if(o){let a=o.closest("ul");a.classList.contains("deflist")&&Wi(a.closest("li")),Ki(o.closest("li"))}}function Ji(){qe.forEach(t=>{let n=c(`#${t}-list-tab-button`);n&&n.addEventListener("click",i=>{be(t),Bt()})});let e=c("#sidebar-listNav");e.addEventListener("keydown",t=>{if(t.key!=="ArrowRight"&&t.key!=="ArrowLeft")return;let n=Array.from(e.querySelectorAll('[role="tab"]')).map(r=>r.dataset.type),i=e.querySelector('[role="tab"][aria-selected="true"]').dataset.type;if(t.key==="ArrowRight"){let r=n.indexOf(i)+1;r>=n.length&&(r=0);let s=n[r];be(s),c(`#${s}-list-tab-button`).focus()}else if(t.key==="ArrowLeft"){let r=n.indexOf(i)-1;r<0&&(r=n.length-1);let s=n[r];be(s),c(`#${s}-list-tab-button`).focus()}}),window.addEventListener("hashchange",t=>{let n=c(Se($()));if(!n)return;let i=n.querySelector("li.current-page li.current-hash");i&&Yi(i),zt()})}var B={module:"module",moduleChild:"module-child",mixTask:"mix-task",extra:"extra",section:"section"};function qt(e,t=8){if(ne(e))return[];let n=le(),i=[...je(n.modules,e,B.module,"module"),...Xi(n.modules,e,B.moduleChild),...je(n.tasks,e,B.mixTask,"mix task"),...je(n.extras,e,B.extra,"page"),...Ue(n.modules,e,B.section,"module"),...Ue(n.tasks,e,B.section,"mix task"),...Ue(n.extras,e,B.section,"page")].filter(r=>r!==null);return sr(i).slice(0,t)}function je(e,t,n,i){return e.map(r=>er(r,t,n,i))}function Xi(e,t,n){return e.filter(i=>i.nodeGroups).flatMap(i=>i.nodeGroups.flatMap(({key:r,nodes:s})=>{let o=rr(r);return s.map(a=>tr(a,i.id,t,n,o)||ir(a,i.id,t,n,o))}))}function Ue(e,t,n,i){return e.flatMap(r=>Zi(r).map(s=>nr(r,s,t,n,i)))}function Zi(e){return(e.sections||[]).concat(e.headers||[])}function er(e,t,n,i){return Ee(e.title,t)?{link:`${e.id}.html`,title:we(e.title,t),description:null,matchQuality:Le(e.title,t),deprecated:e.deprecated,labels:[i],category:n}:null}function tr(e,t,n,i,r){return Ee(e.id,n)?{link:`${t}.html#${e.anchor}`,title:we(e.id,n),labels:[r],description:t,matchQuality:Le(e.id,n),deprecated:e.deprecated,category:i}:null}function nr(e,t,n,i,r){return Vt(t.id,n)?{link:`${e.id}.html#${t.anchor}`,title:we(t.id,n),description:e.title,matchQuality:Le(t.id,n),labels:[r,"section"],category:i}:null}function ir(e,t,n,i,r){let s=`${t}.${e.id}`,o=`${t}:${e.id}`,a,l;if(Ee(s,n))a=s,l=/\./g;else if(Ee(o,n))a=o,l=/:/g;else return null;let u=n.replace(l," ");return Vt(e.id,u)?{link:`${t}.html#${e.anchor}`,title:we(e.id,u),label:r,description:t,matchQuality:Le(a,n),deprecated:e.deprecated,category:i}:null}function rr(e){switch(e){case"callbacks":return"callback";case"types":return"type";default:return"function"}}function sr(e){return e.slice().sort((t,n)=>t.matchQuality!==n.matchQuality?n.matchQuality-t.matchQuality:$t(t.category)-$t(n.category))}function $t(e){switch(e){case B.module:return 1;case B.moduleChild:return 2;case B.mixTask:return 3;default:return 4}}function Vt(e,t){return Te(t).some(i=>jt(e,i))}function Ee(e,t){return Te(t).every(i=>jt(e,i))}function jt(e,t){return e.toLowerCase().includes(t.toLowerCase())}function Le(e,t){let n=Te(t),r=n.map(o=>o.length).reduce((o,a)=>o+a,0)/e.length,s=or(e,n[0])?1:0;return r+s}function or(e,t){return e.toLowerCase().startsWith(t.toLowerCase())}function Te(e){return e.trim().split(/\s+/)}function we(e,t){let n=Te(t).sort((i,r)=>r.length-i.length);return xe(e,n)}function xe(e,t){if(t.length===0)return e;let[n,...i]=t,r=e.match(new RegExp(`(.*)(${gt(n)})(.*)`,"i"));if(r){let[,s,o,a]=r;return xe(s,t)+""+me(o)+""+xe(a,t)}else return xe(e,i)}var ke=null,G=null;function Ut(){G=document.getElementById("toast"),G.addEventListener("click",e=>{clearTimeout(ke),e.target.classList.remove("show")})}function We(e){G&&(clearTimeout(ke),G.innerText=e,G.classList.add("show"),ke=setTimeout(()=>{G.classList.remove("show"),ke=setTimeout(function(){G.innerText=""},1e3)},5e3))}var Wt="dark",Ge=["system","dark","light"];function Gt(e){_.getAndSubscribe(t=>{document.body.classList.toggle(Wt,Yt(e||t.theme))}),cr()}function Kt(){let e=Ge[Ge.indexOf(Ke())+1]||Ge[0];_.update({theme:e}),We(`Set theme to "${e}"`)}function Ke(){return _.get().theme||"system"}function Yt(e){return e==="dark"||ar()&&(e==null||e==="system")}function ar(){return window.matchMedia("(prefers-color-scheme: dark)").matches}function cr(){window.matchMedia("(prefers-color-scheme: dark)").addListener(e=>{let t=_.get().theme,n=Yt(t);(t==null||t==="system")&&(document.body.classList.toggle(Wt,n),We(`Browser changed theme to "${n?"dark":"light"}"`))})}var se=".autocomplete",_e=".autocomplete-suggestions",Oe=".autocomplete-suggestion",I={autocompleteSuggestions:[],previewOpen:!1,selectedIdx:-1};function lr(){c(se).classList.add("shown")}function Ye(){c(se).classList.remove("shown")}function Jt(){return c(se).classList.contains("shown")}function Je(e){I.autocompleteSuggestions=qt(e),I.selectedIdx=-1,ne(e)?Ye():(ur({term:e,suggestions:I.autocompleteSuggestions}),Ie(0),lr())}function ur({term:e,suggestions:t}){let n=Handlebars.templates["autocomplete-suggestions"]({suggestions:t,term:e}),i=c(se);i.innerHTML=n}function Xt(){return I.selectedIdx===-1?null:I.autocompleteSuggestions[I.selectedIdx]}function Ie(e){en(dr(e))}function Zt(e){if(e.data.type==="preview"){let{contentHeight:t}=e.data,n=c(".autocomplete-preview");n&&(n.style.height=`${t+32}px`,n.classList.remove("loading"))}}function en(e){I.selectedIdx=e;let t=c(_e),n=c(`${Oe}.selected`),i=c(`${Oe}[data-index="${I.selectedIdx}"]`);if(n&&n.classList.remove("selected"),i){if(I.previewOpen){nn(),window.addEventListener("message",Zt),t.classList.add("previewing");let r=document.createElement("div");r.classList.add("autocomplete-preview"),r.classList.add("loading");let s=i.href.replace(".html",`.html?preview=true&theme=${Ke()}`),o=document.createElement("iframe");o.setAttribute("src",s),r.appendChild(document.createElement("div")),r.appendChild(document.createElement("span")),r.appendChild(o),i.parentNode.insertBefore(r,i.nextSibling)}i.classList.add("selected"),i.scrollIntoView({block:"nearest"})}else t&&(t.scrollTop=0)}function tn(){I.previewOpen?Ce():Xe()}function Ce(){I.previewOpen=!1;let e=c(_e);e&&e.classList.remove("previewing"),nn()}function Xe(e){I.previewOpen=!0,e?e=e.closest(Oe):e=c(`${Oe}[data-index="${I.selectedIdx}"]`),e&&en(parseInt(e.dataset.index))}function nn(){let e=c(".autocomplete-preview");e&&(e.remove(),window.removeEventListener("message",Zt))}function dr(e){let t=I.autocompleteSuggestions.length+1;return(I.selectedIdx+e+1+t)%t-1}var ue="form.search-bar input",fr="form.search-bar .search-close-button";function on(){pr(),window.onTogglePreviewClick=function(e,t){e.preventDefault(),e.stopImmediatePropagation(),et(),t?Xe(e.target):Ce()}}function an(e){let t=c(ue);t.value=e}function et(){let e=c(ue);document.body.classList.add("search-focused"),e.focus()}function pr(){let e=c(ue);if(document.querySelector('meta[name="exdoc:autocomplete"][content="off"]'))return e.addEventListener("keydown",t=>{t.key==="Enter"&&rn(t)}),!0;e.addEventListener("keydown",t=>{let n=ie();t.key==="Escape"?(Ae(),e.blur()):t.key==="Enter"?rn(t):t.key==="ArrowUp"||n&&t.ctrlKey&&t.key==="p"?(Ie(-1),t.preventDefault()):t.key==="ArrowDown"||n&&t.ctrlKey&&t.key==="n"?(Ie(1),t.preventDefault()):t.key==="Tab"&&(tn(),t.preventDefault())}),e.addEventListener("input",t=>{Je(t.target.value)}),e.addEventListener("focus",t=>{document.body.classList.contains("search-focused")||(document.body.classList.add("search-focused"),Je(t.target.value))}),e.addEventListener("blur",t=>{let n=t.relatedTarget,i=c(_e);if(n&&i&&i.contains(n))return setTimeout(()=>{Jt()&&e.focus()},1e3),null;Pe()}),c(se).addEventListener("click",t=>{t.shiftKey||t.ctrlKey?e.focus():(Ae(),Pe())}),c(fr).addEventListener("click",t=>{Ae(),Pe()})}function rn(e){let t=c(ue),n=e.shiftKey||e.ctrlKey,i=Xt();e.preventDefault();let r=n?"_blank":"_self",s=document.createElement("a");if(s.setAttribute("target",r),i)s.setAttribute("href",i.link);else{let o=document.querySelector('meta[name="exdoc:full-text-search-url"]'),a=o?o.getAttribute("content"):"search.html?q=";s.setAttribute("href",`${a}${encodeURIComponent(t.value)}`)}s.click(),n||(Ae(),Pe())}function Ae(){let e=c(ue);e.value=""}function Pe(){Ce(),document.body.classList.remove("search-focused"),Ye()}var Ze=window.scrollY,hr=70,sn=-2;window.addEventListener("scroll",function(){let e=window.scrollY;e===0||Ze-ehr?document.body.classList.remove("scroll-sticky"):Ze-e>Math.abs(sn)&&document.body.classList.add("scroll-sticky"),Ze=e<=0?0:e},!1);var cn=".sidebar-projectVersion",ln=".sidebar-projectVersionsDropdown";function un(){let e=Dt();if(e.length>0){let n=c(cn).textContent.trim(),i=gr(e,n);mr({nodes:i})}}function mr({nodes:e}){let t=c(cn),n=Handlebars.templates["versions-dropdown"]({nodes:e});t.innerHTML=n,c(ln).addEventListener("change",vr)}function gr(e,t){return yr(e,t).map(i=>({...i,isCurrentVersion:i.version===t}))}function yr(e,t){return e.some(i=>i.version===t)?e:[{version:t,url:"#"},...e]}function vr(e){let t=e.target.value,n=window.location.pathname.split("/").pop()+window.location.hash,i=`${t}/${n}`;bt(i).then(r=>{r?window.location.href=i:window.location.href=t})}function tt(){let e=c(ln);e&&(e.focus(),e.addEventListener("keydown",t=>{(t.key==="Escape"||t.key==="v")&&(t.preventDefault(),e.blur())}),navigator.userActivation.isActive&&"showPicker"in HTMLSelectElement.prototype&&e.showPicker())}var H=mt(pn());var Re=80,br="#search";function mn(){let e=window.location.pathname;if(e.endsWith("/search.html")||e.endsWith("/search")){let t=vt("q");Sr(t)}}async function Sr(e){if(ne(e))nt({value:e});else{an(e);let t=await xr();try{let n=e.replaceAll(/(\B|\\):/g,"\\:"),i=Ar(t.search(n));nt({value:e,results:i})}catch(n){nt({value:e,errorMessage:n.message})}}}function nt({value:e,results:t,errorMessage:n}){let i=c(br),r=Handlebars.templates["search-results"]({value:e,results:t,errorMessage:n});i.innerHTML=r}async function xr(){H.default.tokenizer.separator=/\s+/,H.default.QueryLexer.termSeparator=/\s+/,H.default.Pipeline.registerFunction(yn,"docTokenSplitter"),H.default.Pipeline.registerFunction(vn,"docTrimmer");let e=await Er();if(e)return e;let t=_r();return Lr(t),t}async function Er(){try{let e=sessionStorage.getItem(gn());if(e){let t=await wr(e);return H.default.Index.load(t)}else return null}catch(e){return console.error("Failed to load index: ",e),null}}async function Lr(e){try{let t=await Tr(e);sessionStorage.setItem(gn(),t)}catch(t){console.error("Failed to save index: ",t)}}async function Tr(e){let t=new Blob([JSON.stringify(e)],{type:"application/json"}).stream().pipeThrough(new window.CompressionStream("gzip")),i=await(await new Response(t).blob()).arrayBuffer();return kr(i)}async function wr(e){let t=new Blob([Or(e)],{type:"application/json"}).stream().pipeThrough(new window.DecompressionStream("gzip")),n=await new Response(t).text();return JSON.parse(n)}function kr(e){let t="",n=new Uint8Array(e),i=n.byteLength;for(let r=0;r{this.add(e)})})}function Ir(e){e.pipeline.before(H.default.stemmer,yn)}function yn(e){let t=[e],n=/\/\d+$/,i=/\:|\./,r=e.toString();if(n.test(r)){let o=e.toString().replace(n,"");t.push(e.clone().update(()=>o));let a=o.split(i);if(a.length>1){for(let u of a)t.push(e.clone().update(()=>u));let l=e.toString().split(i);t.push(e.clone().update(()=>l[l.length-1]))}r=a[a.length-1]}else r.startsWith("@")&&(r=r.substring(1),t.push(e.clone().update(()=>r)));let s=r.split(/\_|\-/);if(s.length>1)for(let o of s)t.push(e.clone().update(()=>o));return t}function Cr(e){e.pipeline.before(H.default.stemmer,vn)}function vn(e){return e.update(function(t){return t.replace(/^[^@:\w]+/,"").replace(/[^\?\!\w]+$/,"")})}function Ar(e){return e.filter(t=>hn(t.ref)).map(t=>{let n=hn(t.ref),i=t.matchData.metadata;return{...n,metadata:i,excerpts:Pr(n,i)}})}function hn(e){return searchData.items.find(t=>t.ref===e)||null}function Pr(e,t){let{doc:n}=e,r=Object.keys(t).filter(s=>"doc"in t[s]).map(s=>t[s].doc.position.map(([o,a])=>Rr(n,o,a))).reduce((s,o)=>s.concat(o),[]);return r.length===0?[n.slice(0,Re*2)+(Re*20?"...":"",e.slice(i,t),""+me(e.slice(t,t+n))+"",e.slice(t+n,r),r{let n=t.getAttribute("data-group-id");t.addEventListener("mouseenter",i=>{bn(n,!0)}),t.addEventListener("mouseleave",i=>{bn(n,!1)})})}function bn(e,t){k(`[data-group-id="${e}"]`).forEach(i=>{i.classList.toggle(Nr,t)})}var Y=".modal",Hr=".modal .modal-close",Fr=".modal .modal-title",Dr=".modal .modal-body",xn='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])',z={prevFocus:null,lastFocus:null,ignoreFocusChanges:!1};function En(){Mr()}function Mr(){let e=Handlebars.templates["modal-layout"]();document.body.insertAdjacentHTML("beforeend",e),c(Y).addEventListener("keydown",t=>{t.key==="Escape"&&K()}),c(Hr).addEventListener("click",t=>{K()}),c(Y).addEventListener("click",t=>{t.target.classList.contains("modal")&&K()})}function Ln(e){if(z.ignoreFocusChanges)return;let t=c(Y);if(t.contains(e.target))z.lastFocus=e.target;else{z.ignoreFocusChanges=!0;let n=Br(t);z.lastFocus===n?zr(t).focus():n.focus(),z.ignoreFocusChanges=!1,z.lastFocus=document.activeElement}}function Br(e){return e.querySelector(xn)}function zr(e){let t=e.querySelectorAll(xn);return t[t.length-1]}function Ne({title:e,body:t}){z.prevFocus=document.activeElement,document.addEventListener("focus",Ln,!0),c(Fr).innerHTML=e,c(Dr).innerHTML=t,c(Y).classList.add("shown"),c(Y).focus()}function K(){c(Y).classList.remove("shown"),document.addEventListener("focus",Ln,!0),z.prevFocus&&z.prevFocus.focus(),z.prevFocus=null}function Tn(){return c(Y).classList.contains("shown")}var $r="https://hexdocs.pm/%%",qr="https://hex.pm/api/packages?search=name:%%*",Vr=".display-quick-switch",it="#quick-switch-input",kn="#quick-switch-results",jr=".quick-switch-result",Ur=300,Wr=9,Gr=["elixir","eex","ex_unit","hex","iex","logger","mix"].map(e=>({name:e})),On=2,P={autocompleteResults:[],selectedIdx:null};function _n(){Kr()}function Kr(){k(Vr).forEach(e=>{e.addEventListener("click",t=>{st()})})}function Yr(e){if(e.key==="Enter"){let t=e.target.value;Xr(t),e.preventDefault()}else e.key==="ArrowUp"?(wn(-1),e.preventDefault()):e.key==="ArrowDown"&&(wn(1),e.preventDefault())}function Jr(e){let t=e.target.value;if(t.lengthn.json()).then(n=>{Array.isArray(n)&&(P.autocompleteResults=ns(e,n),P.selectedIdx=null,c(it).value.length>=On&&ts({results:P.autocompleteResults}))})}function ts({results:e}){let t=c(kn),n=Handlebars.templates["quick-switch-results"]({results:e});t.innerHTML=n,k(jr).forEach(i=>{i.addEventListener("click",r=>{let s=i.getAttribute("data-index"),o=P.autocompleteResults[s];rt(o.name)})})}function ns(e,t){return Gr.concat(t).filter(n=>n.name.toLowerCase().includes(e.toLowerCase())).filter(n=>n.releases===void 0||n.releases[0].has_docs===!0).slice(0,Wr)}function wn(e){P.selectedIdx=is(e);let t=c(".quick-switch-result.selected"),n=c(`.quick-switch-result[data-index="${P.selectedIdx}"]`);t&&t.classList.remove("selected"),n&&n.classList.add("selected")}function is(e){let t=P.autocompleteResults.length;if(P.selectedIdx===null){if(e>=0)return 0;if(e<0)return t-1}return(P.selectedIdx+e+t)%t}var rs=".display-settings",ss="#settings-modal-content",ot="#modal-settings-tab",at="#modal-keyboard-shortcuts-tab",Cn="#settings-content",An="#keyboard-shortcuts-content",os=[{title:"Settings",id:"modal-settings-tab"},{title:"Keyboard shortcuts",id:"modal-keyboard-shortcuts-tab"}];function Pn(){as()}function as(){k(rs).forEach(e=>{e.addEventListener("click",t=>{ct()})})}function In(){c(at).classList.remove("active"),c(ot).classList.add("active"),c(Cn).classList.remove("hidden"),c(An).classList.add("hidden")}function cs(){c(at).classList.add("active"),c(ot).classList.remove("active"),c(An).classList.remove("hidden"),c(Cn).classList.add("hidden")}function ct(){Ne({title:os.map(({id:s,title:o})=>``).join(""),body:Handlebars.templates["settings-modal-body"]({shortcuts:lt})});let e=c(ss),t=e.querySelector('[name="theme"]'),n=e.querySelector('[name="tooltips"]'),i=e.querySelector('[name="direct_livebook_url"]'),r=e.querySelector('[name="livebook_url"]');_.getAndSubscribe(s=>{t.value=s.theme||"system",n.checked=s.tooltips,s.livebookUrl===null?(i.checked=!1,r.classList.add("hidden"),r.tabIndex=-1):(i.checked=!0,r.classList.remove("hidden"),r.tabIndex=0,r.value=s.livebookUrl)}),t.addEventListener("change",s=>{_.update({theme:s.target.value})}),n.addEventListener("change",s=>{_.update({tooltips:s.target.checked})}),i.addEventListener("change",s=>{let o=s.target.checked?r.value:null;_.update({livebookUrl:o})}),r.addEventListener("input",s=>{_.update({livebookUrl:s.target.value})}),c(ot).addEventListener("click",s=>{In()}),c(at).addEventListener("click",s=>{cs()}),In()}var ls="#settings-modal-content",lt=[{key:"c",description:"Toggle sidebar",action:Me},{key:"n",description:"Cycle themes",action:Kt},{key:"s",description:"Focus search bar",displayAs:"/ or s",action:ut},{key:"/",action:ut},{key:"k",hasModifier:!0,action:ut},{key:"v",description:"Open/focus version select",action:ps},{key:"g",description:"Search HexDocs package",displayAs:"g",action:st},{key:"?",displayAs:"?",description:"Bring up this modal",action:hs}],dt={shortcutBeingPressed:null};function Rn(){us()}function us(){document.addEventListener("keydown",ds),document.addEventListener("keyup",fs)}function ds(e){if(dt.shortcutBeingPressed||e.target.matches("input, select, textarea"))return;let t=lt.find(n=>n.hasModifier?ie()&&e.metaKey||e.ctrlKey?n.key===e.key:!1:e.ctrlKey||e.metaKey||e.altKey?!1:n.key===e.key);t&&(dt.shortcutBeingPressed=t,e.preventDefault(),t.action(e))}function fs(e){dt.shortcutBeingPressed=null}function ut(e){K(),et()}function ps(){K(),Qt()?tt():ze().then(tt)}function hs(){ms()?K():ct()}function ms(){return Tn()&&c(ls)}var J={plain:"plain",function:"function",module:"module"},gs=[{href:"typespecs.html#basic-types",hint:{kind:J.plain,description:"Basic type"}},{href:"typespecs.html#literals",hint:{kind:J.plain,description:"Literal"}},{href:"typespecs.html#built-in-types",hint:{kind:J.plain,description:"Built-in type"}}],Qe={cancelHintFetching:null};function Nn(e){if(Hn(e))return!0;let t=/#.*\//;return e.includes("#")&&!t.test(e)?!1:e.includes(".html")}function Qn(e){let t=Hn(e);return t?Promise.resolve(t):ys(e)}function Hn(e){let t=gs.find(n=>e.includes(n.href));return t?t.hint:null}function ys(e){let t=e.replace(".html",".html?hint=true");return new Promise((n,i)=>{let r=document.createElement("iframe");r.setAttribute("src",t),r.style.display="none";function s(a){let{href:l,hint:u}=a.data;t===l&&(o(),n(u))}Qe.cancelHintFetching=()=>{o(),i(new Error("cancelled"))};function o(){r.remove(),window.removeEventListener("message",s),Qe.cancelHintFetching=null}window.addEventListener("message",s),document.body.appendChild(r)})}function Fn(){Qe.cancelHintFetching&&Qe.cancelHintFetching()}function Dn(e){let n=e.querySelector("h1").textContent,i=e.querySelector(".docstring > p"),r=i?i.innerHTML:"";return{kind:J.function,title:n.trim(),description:r.trim()}}function Mn(e){let n=e.querySelector("h1 > span").textContent,i=e.querySelector("#moduledoc p"),r=i?i.innerHTML:"";return{kind:J.module,title:n.trim(),description:r.trim()}}var vs=".content a",ft=".tooltip",bs=".tooltip .tooltip-body",zn="body .content-inner",Ss="#content",$n="tooltip-shown",de=10,xs=de*4,Bn={height:450,width:768},Es=100,oe={currentLinkElement:null,hoverDelayTimeout:null};function qn(){Ls(),Ts()}function Ls(){let e=Handlebars.templates["tooltip-layout"]();c(zn).insertAdjacentHTML("beforeend",e)}function Ts(){k(vs).forEach(e=>{ws(e)&&(e.addEventListener("mouseenter",t=>{Os(e)}),e.addEventListener("mouseleave",t=>{As(e)}))})}function ws(e){return!(e.getAttribute("data-no-tooltip")!==null||ks(e.href)||!Nn(e.href))}function ks(e){let t=e.replace(Ss,"");return window.location.href.split("#")[0]===t}function Os(e){_s()&&(oe.currentLinkElement=e,oe.hoverDelayTimeout=setTimeout(()=>{Qn(e.href).then(t=>{Is(t),Cs()}).catch(()=>{})},Es))}function _s(){let e=window.innerWidthe.firstElementChild&&e.firstElementChild.tagName==="CODE").forEach(e=>e.insertAdjacentHTML("beforeend",Bs)),Array.from(k(".copy-button")).forEach(e=>{let t;e.addEventListener("click",()=>{let n=e.querySelector("[aria-live]");t&&clearTimeout(t);let i=Array.from(e.parentElement.querySelector("code").childNodes).filter(r=>!(r.tagName==="SPAN"&&r.classList.contains("unselectable"))).map(r=>r.textContent).join("");navigator.clipboard.writeText(i),e.classList.add("clicked"),n.innerHTML="Copied! ✓",t=setTimeout(()=>{e.classList.remove("clicked"),n.innerHTML=""},3e3)})})}function Gn(){let e=ie()?"apple-os":"non-apple-os";document.documentElement.classList.add(e)}var $s="content",qs="tabs-open",Vs="tabs-close",js="H3",Us="tabset";function Yn(){Ws().map(Gs).forEach(n=>Js(n))}function Ws(){let e=document.createNodeIterator(document.getElementById($s),NodeFilter.SHOW_COMMENT,{acceptNode(i){return i.nodeValue.trim()===qs?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}}),t=[],n;for(;n=e.nextNode();)t.push(n);return t}function Gs(e,t,n){let i=[],r=[],s={label:"",content:[]};for(;e=e.nextSibling;){if(Ks(e)){Kn(s,r,t);break}i.push(e),e.nodeName===js?(Kn(s,r,t),s.label=e.innerText,s.content=[]):s.content.push(e.outerHTML)}let o=document.createElement("div");return o.className=Us,Ys(i,o),o.innerHTML=Handlebars.templates.tabset({tabs:r}),o}function Ks(e){return e.nodeName==="#comment"&&e.nodeValue.trim()===Vs}function Kn(e,t,n){if(e.label===""&&!e.content.length)return!1;let i=e.label,r=e.content;t.push({label:i,content:r,setIndex:n})}function Ys(e,t){if(!e||!e.length)return!1;e[0].parentNode.insertBefore(t,e[0]),e.forEach(n=>t.appendChild(n))}function Js(e){let t={tabs:e.querySelectorAll(':scope [role="tab"]'),panels:e.querySelectorAll(':scope [role="tabpanel"]'),activeIndex:0};t.tabs.forEach((n,i)=>{n.addEventListener("click",r=>{X(i,t)}),n.addEventListener("keydown",r=>{let s=t.tabs.length-1;r.code==="ArrowLeft"?(r.preventDefault(),t.activeIndex===0?X(s,t):X(t.activeIndex-1,t)):r.code==="ArrowRight"?(r.preventDefault(),t.activeIndex===s?X(0,t):X(t.activeIndex+1,t)):r.code==="Home"?(r.preventDefault(),X(0,t)):r.code==="End"&&(r.preventDefault(),X(s,t))})})}function X(e,t){t.tabs[t.activeIndex].setAttribute("aria-selected","false"),t.tabs[t.activeIndex].tabIndex=-1,t.tabs[e].setAttribute("aria-selected","true"),t.tabs[e].tabIndex=0,t.tabs[e].focus(),t.panels[t.activeIndex].setAttribute("hidden",""),t.panels[t.activeIndex].tabIndex=-1,t.panels[e].removeAttribute("hidden"),t.panels[e].tabIndex=0,t.activeIndex=e}function Xn(){let e=ge(te(),!0);e&&Xs(e)}function Xs(e){to(e),Zs(),eo(),Jn(),window.addEventListener("resize",t=>{Jn()})}function Jn(){let e=document.body.scrollHeight,t=document.getElementById("content").parentElement.offsetHeight,n={type:"preview",maxHeight:e,contentHeight:t};window.parent.postMessage(n,"*")}function Zs(){let e=document.getElementsByTagName("a");for(let t of e)t.getAttribute("target")!=="_blank"&&t.setAttribute("target","_parent")}function eo(){window.scrollTo(0,0)}function to(e){document.body.classList.add("preview");let t=document.getElementById("content");t.innerHTML=e.innerHTML}St(()=>{let e=new URLSearchParams(window.location.search),t=e.has("preview");Gt(e.get("theme")),Tt(t),Sn(),qn(),Un(),Wn(),Gn(),Yn(),t?Xn():(un(),Pt(),Mt(),on(),En(),Rn(),_n(),Ut(),mn(),Pn())});})(); +/*! Bundled license information: + +lunr/lunr.js: + (** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + *) + (*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + *) + (*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + *) +*/ diff --git a/dist/html-erlang-EBZIIHAS.css b/dist/html-erlang-EBZIIHAS.css deleted file mode 100644 index e51da55..0000000 --- a/dist/html-erlang-EBZIIHAS.css +++ /dev/null @@ -1,6 +0,0 @@ -:root{--main: hsl(0, 100%, 44%);--mainDark: hsl(0, 100%, 34%);--mainDarkest: hsl(0, 100%, 24%);--mainLight: hsl(0, 100%, 64%);--mainLightest: hsl(0, 100%, 74%);--searchBarFocusColor: hsl(0, 100%, 50%);--searchBarBorderColor: rgb(255, 71, 71, .1);--linksNoUnderline: #0969da;--linksNoUnderlineVisited: #085fc4}body.dark{--linksNoUnderline: #71b7ff;--linksNoUnderlineVisited: #65a4e5}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:300;src:url(./lato-latin-ext-300-normal-VPGGJKJL.woff2) format("woff2"),url(./lato-all-300-normal-GIV56FBX.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:300;src:url(./lato-latin-300-normal-YUMVEFOL.woff2) format("woff2"),url(./lato-all-300-normal-GIV56FBX.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:400;src:url(./lato-latin-ext-400-normal-N27NCBWW.woff2) format("woff2"),url(./lato-all-400-normal-MNITWADU.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:400;src:url(./lato-latin-400-normal-W7754I4D.woff2) format("woff2"),url(./lato-all-400-normal-MNITWADU.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:700;src:url(./lato-latin-ext-700-normal-Q2L5DVMW.woff2) format("woff2"),url(./lato-all-700-normal-XMT5XFBS.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:700;src:url(./lato-latin-700-normal-2XVSBPG4.woff2) format("woff2"),url(./lato-all-700-normal-XMT5XFBS.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:400;src:url(./inconsolata-vietnamese-400-normal-IGQPHHJH.woff2) format("woff2"),url(./inconsolata-all-400-normal-HMVRHNDU.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:400;src:url(./inconsolata-latin-ext-400-normal-K7HVGTP7.woff2) format("woff2"),url(./inconsolata-all-400-normal-HMVRHNDU.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:400;src:url(./inconsolata-latin-400-normal-RGKDDNDD.woff2) format("woff2"),url(./inconsolata-all-400-normal-HMVRHNDU.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:700;src:url(./inconsolata-vietnamese-700-normal-LHEGSN35.woff2) format("woff2"),url(./inconsolata-all-700-normal-WFUKXZPS.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:700;src:url(./inconsolata-latin-ext-700-normal-4MPBLFZC.woff2) format("woff2"),url(./inconsolata-all-700-normal-WFUKXZPS.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:700;src:url(./inconsolata-latin-700-normal-DTS2D7TO.woff2) format("woff2"),url(./inconsolata-all-700-normal-WFUKXZPS.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--content-width: 949px;--content-gutter: 60px;--borderRadius: 4px;--navTabBorderWidth: 4px;--defaultFontFamily: -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";--sansFontFamily: "Lato", sans-serif;--monoFontFamily: "Inconsolata", Menlo, Courier, monospace;--baseFontSize: 18px;--baseLineHeight: 1.5em;--gray25: hsl(207, 43%, 98%);--gray50: hsl(207, 43%, 96%);--gray100: hsl(212, 33%, 91%);--gray200: hsl(210, 29%, 88%);--gray300: hsl(210, 26%, 84%);--gray400: hsl(210, 21%, 64%);--gray450: hsl(210, 21%, 49%);--gray500: hsl(210, 21%, 34%);--gray600: hsl(210, 27%, 26%);--gray700: hsl(212, 35%, 17%);--gray750: hsl(214, 46%, 14%);--gray800: hsl(216, 52%, 11%);--gray800-opacity-0: hsla(216, 52%, 11%, 0%);--gray850: hsl(216, 63%, 8%);--gray900: hsl(218, 73%, 4%);--gray900-opacity-50: hsla(218, 73%, 4%, 50%);--gray900-opacity-0: hsla(218, 73%, 4%, 0%);--coldGrayFaint: hsl(240, 5%, 97%);--coldGrayLight: hsl(240, 5%, 88%);--coldGray-lightened-10: hsl(240, 5%, 56%);--coldGray: hsl(240, 5%, 46%);--coldGray-opacity-10: hsla(240, 5%, 46%, 10%);--coldGrayDark: hsl(240, 5%, 28%);--coldGrayDim: hsl(240, 5%, 18%);--yellowLight: hsl(60, 100%, 81%);--yellowDark: hsl(60, 100%, 43%, 62%);--yellow: hsl(60, 100%, 43%);--green-lightened-10: hsl(90, 100%, 45%);--green: hsl(90, 100%, 35%);--white: hsl(0, 0%, 100%);--white-opacity-50: hsla(0, 0%, 100%, 50%);--white-opacity-10: hsla(0, 0%, 100%, 10%);--white-opacity-0: hsla(0, 0%, 100%, 0%);--black: hsl(0, 0%, 0%);--black-opacity-10: hsla(0, 0%, 0%, 10%);--black-opacity-50: hsla(0, 0%, 0%, 50%)}@media screen and (max-width: 768px){:root{--content-width: 100%;--content-gutter: 20px}}:root{--background: var(--white);--contrast: var(--black);--textBody: var(--gray800);--textHeaders: var(--gray900);--textDetailAccent: var(--mainLight);--textDetailBackground: var(--coldGrayFaint);--textFooter: var(--gray700);--links: var(--black);--linksVisited: var(--black);--linksDecoration: var(--gray450);--iconAction: var(--coldGray);--iconActionHover: var(--gray800);--blockquoteBackground: var(--coldGrayFaint);--blockquoteBorder: var(--coldGrayLight);--tableHeadBorder: var(--gray100);--tableBodyBorder: var(--gray50);--warningBackground: hsl( 33, 100%, 97%);--warningHeadingBackground: hsl( 33, 87%, 64%);--warningHeading: var(--black);--errorBackground: hsl( 7, 81%, 96%);--errorHeadingBackground: hsl( 6, 80%, 60%);--errorHeading: var(--white);--infoBackground: hsl(206, 91%, 96%);--infoHeadingBackground: hsl(213, 92%, 62%);--infoHeading: var(--white);--neutralBackground: hsl(212, 29%, 92%);--neutralHeadingBackground: hsl(220, 43%, 11%);--neutralHeading: var(--white);--tipBackground: hsl(142, 31%, 93%);--tipHeadingBackground: hsl(134, 39%, 36%);--tipHeading: var(--white);--fnSpecAttr: var(--coldGray);--fnDeprecated: var(--yellowLight);--blink: var(--yellowLight);--codeBackground: var(--gray25);--codeBorder: var(--gray100);--codeScrollThumb: var(--gray400);--codeScrollBackground: var(--codeBorder);--admCodeBackground: var(--gray25);--admCodeBorder: var(--gray100);--admCodeColor: var(--black);--admInlineCodeColor: var(--black);--admInlineCodeBackground: var(--gray25);--admInlineCodeBorder: var(--gray100);--tabBackground: var(--white);--tabBorder: var(--gray300);--tabBorderTop: var(--gray100);--tab: var(--gray600);--tabShadow: var(--gray25);--bottomActionsBtnBorder: var(--black-opacity-10);--bottomActionsBtnSubheader: var(--mainDark);--modalBackground: var(--white);--settingsInput: var(--gray500);--settingsInputBackground: var(--white);--settingsInputBorder: var(--gray300);--settingsSectionBorder: var(--gray300);--quickSwitchInput: var(--gray500);--quickSwitchContour: var(--coldGray);--success: var(--green);--sidebarButtonBackground: linear-gradient(180deg, var(--white) 20%, var(--white-opacity-50) 70%, var(--white-opacity-0) 100%);--sidebarAccentMain: var(--gray50);--sidebarBackground: var(--gray800);--sidebarHeader: var(--gray700);--sidebarMuted: var(--gray300);--sidebarHover: var(--white);--sidebarScrollbarThumb: var(--coldGray);--sidebarScrollbarTrack: var(--sidebarBackground);--sidebarSubheadings: var(--gray400);--sidebarItem: var(--gray200);--sidebarInactiveItemMarker: var(--gray600);--sidebarLanguageAccentBar: var(--mainLight);--sidebarActiveItem: var(--mainLightest);--searchBarBorder: var(--gray200);--searchAccentMain: var(--gray-400);--searchLanguageAccentBar: var(--main);--searchSearch: var(--white);--autocompleteBorder: rgba(3, 9, 19, .1);--autocompletePreview: var(--gray25);--autocompleteHover: var(--grey50, #F0F5F9);--autocompleteBackground: var(--white);--suggestionBorder: var(--gray200);--autocompleteResults: var(--gray600);--autocompleteResultsBold: var(--gray800);--autocompleteSrollbarThumb: var(--gray200);--autocompleteSrollbarTrack: var(--gray50);--autocompleteLabelBack: var(--gray100);--autocompleteLabelFont: var(--gray600)}body.dark{--background: var(--gray900);--contrast: var(--white);--textBody: var(--gray200);--textHeaders: var(--gray100);--textDetailAccent: var(--mainLight);--textDetailBackground: var(--gray700);--textFooter: var(--gray300);--links: var(--gray100);--linksVisited: var(--gray100);--linksDecoration: var(--gray450);--iconAction: var(--coldGray-lightened-10);--iconActionHover: var(--white);--blockquoteBackground: var(--coldGray-opacity-10);--blockquoteBorder: var(--coldGrayDim);--tableHeadBorder: var(--gray600);--tableBodyBorder: var(--gray700);--warningBackground: hsla( 33, 30%, 60%, 10%);--warningHeadingBackground: hsla( 33, 66%, 35%, 80%);--warningHeading: var(--white);--errorBackground: hsla( 7, 30%, 60%, 10%);--errorHeadingBackground: hsla( 6, 70%, 40%, 80%);--errorHeading: var(--white);--infoBackground: hsla(206, 30%, 60%, 10%);--infoHeadingBackground: hsla(213, 55%, 35%, 80%);--infoHeading: var(--white);--neutralBackground: hsl(210, 30%, 60%, 10%);--neutralHeadingBackground: var(--gray600);--neutralHeading: var(--white);--tipBackground: hsla(142, 30%, 60%, 10%);--tipHeadingBackground: hsla(134, 45%, 30%, 80%);--tipHeading: var(--white);--fnSpecAttr: var(--gray400);--fnDeprecated: var(--yellowDark);--blink: var(--gray600);--codeBackground: var(--gray750);--codeBorder: var(--gray600);--codeScrollThumb: var(--gray500);--codeScrollBackground: var(--codeBorder);--admCodeBackground: var(--gray750);--admCodeBorder: var(--gray600);--admCodeColor: var(--gray100);--admInlineCodeColor: var(--gray100);--admInlineCodeBackground: var(--gray750);--admInlineCodeBorder: var(--gray600);--tabBackground: var(--gray900);--tabBorder: var(--gray700);--tabBorderTop: var(--gray700);--tab: var(--white);--tabShadow: var(--black);--bottomActionsBtnBorder: var(--white-opacity-10);--bottomActionsBtnSubheader: var(--mainLight);--modalBackground: var(--gray800);--settingsInput: var(--white);--settingsInputBackground: var(--gray700);--settingsInputBorder: var(--gray700);--settingsSectionBorder: var(--gray700);--quickSwitchInput: var(--gray300);--quickSwitchContour: var(--gray500);--success: var(--green-lightened-10);--sidebarButtonBackground: linear-gradient(180deg, var(--gray900) 20%, var(--gray900-opacity-50) 70%, var(--gray900-opacity-0) 100%);--sidebarAccentMain: var(--gray50);--sidebarBackground: var(--gray800);--sidebarHeader: var(--gray700);--sidebarMuted: var(--gray300);--sidebarHover: var(--white);--sidebarScrollbarThumb: var(--coldGray);--sidebarScrollbarTrack: var(--sidebarBackground);--sidebarSubheadings: var(--gray400);--sidebarItem: var(--gray200);--sidebarInactiveItemMarker: var(--gray600);--sidebarLanguageAccentBar: var(--mainLight);--sidebarActiveItem: var(--mainLightest);--searchBarBorder: var(--gray500);--searchAccentMain: var(--gray300);--searchSearch: var(--gray900);--autocompleteBorder: rgba(28,42,60,.75);--autocompletePreview: var(--gray750);--autocompleteHover: var(--gray700);--autocompleteBackground: var(--gray800);--suggestionBorder: var(--gray600);--autocompleteResults: var(--gray200);--autocompleteResultsBold: var(--gray100);--autocompleteSrollbarThumb: var(--gray600);--autocompleteSrollbarTrack: var(--gray850);--autocompleteLabelBack: var(--gray600);--autocompleteLabelFont: rgba(255, 255, 255, .8)}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}@font-face{font-family:remixicon;src:url(./remixicon-NKANDIL5.woff2) format("woff2");font-display:swap}[class^=ri-],[class*=" ri-"],.remix-icon{font-family:remixicon;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:root{--icon-arrow-up-s: "\ea78";--icon-arrow-down-s: "\ea4e";--icon-arrow-right-s: "\ea6e";--icon-add: "\ea13";--icon-subtract: "\f1af";--icon-error-warning: "\eca1";--icon-information: "\ee59";--icon-alert: "\ea21";--icon-double-quotes-l: "\ec51";--icon-link-m: "\eeaf";--icon-close-line: "\eb99";--icon-code-s-slash-line: "\ebad";--icon-menu-line: "\ef3e";--icon-search-2-line: "\f0cd";--icon-settings-3-line: "\f0e6";--icon-printer-line: "\f029"}.ri-lg{font-size:1.3333em;line-height:.75em;vertical-align:-.0667em}.ri-settings-3-line:before{content:var(--icon-settings-3-line)}.ri-add-line:before{content:var(--icon-add)}.ri-subtract-line:before{content:var(--icon-subtract)}.ri-arrow-up-s-line:before{content:var(--icon-arrow-up-s)}.ri-arrow-down-s-line:before{content:var(--icon-arrow-down-s)}.ri-arrow-right-s-line:before{content:var(--icon-arrow-right-s)}.ri-search-2-line:before{content:var(--icon-search-2-line)}.ri-menu-line:before{content:var(--icon-menu-line)}.ri-close-line:before{content:var(--icon-close-line)}.ri-link-m:before{content:var(--icon-link-m)}.ri-code-s-slash-line:before{content:var(--icon-code-s-slash-line)}.ri-error-warning-line:before{content:var(--icon-error-warning)}.ri-information-line:before{content:var(--icon-information)}.ri-alert-line:before{content:var(--icon-alert)}.ri-double-quotes-l:before{content:var(--icon-double-quotes-l)}.ri-printer-line:before{content:var(--icon-printer-line)}html,body{box-sizing:border-box;height:100%;width:100%}body{--sidebarWidth: 300px;--sidebarMinWidth: 300px;--sidebarTransitionDuration: .3s;background-color:var(--background);color:var(--textBody);font-size:16px;font-family:var(--sansFontFamily);line-height:1.6875em}*,*:before,*:after{box-sizing:inherit}.body-wrapper{display:flex;height:100%}.sidebar{display:flex;flex-direction:column;width:var(--sidebarWidth);min-width:var(--sidebarMinWidth);height:100%;position:fixed;top:0;left:0;z-index:100;resize:horizontal}.sidebar-button{padding:26px 12px 18px 19px;position:fixed;z-index:200;top:0;left:0;will-change:transform}.sidebar-toggle--animated.sidebar-button{transition:transform var(--sidebarTransitionDuration) ease-in-out}.content{width:calc(100% - var(--sidebarWidth));left:var(--sidebarWidth);height:100%;position:absolute}.content .content-inner{max-width:var(--content-width);min-height:100%;margin:0 auto;padding:0 var(--content-gutter) 10px}.content-inner:focus{outline:none}body:is(.sidebar-opening,.sidebar-opened) .sidebar-button{transform:translate(calc(var(--sidebarWidth) - 100%))}body.sidebar-opening-start .sidebar{left:calc(-1 * var(--sidebarWidth))}body.sidebar-opening-start .content{width:100%;left:0}body.sidebar-opening .sidebar{left:0;transition:left var(--sidebarTransitionDuration) ease-in-out}body.sidebar-opening .content{width:calc(100% - var(--sidebarWidth));left:var(--sidebarWidth);transition:all var(--sidebarTransitionDuration) ease-in-out}body.sidebar-closing .sidebar-button{transform:translate(0)}body.sidebar-closing .sidebar{left:calc(-1 * var(--sidebarWidth));transition:left var(--sidebarTransitionDuration) ease-in-out}body.sidebar-closing .content{width:100%;left:0;transition:all var(--sidebarTransitionDuration) ease-in-out}body.sidebar-closed .sidebar{left:calc(-1 * var(--sidebarWidth));display:none}body.sidebar-closed .content{width:100%;left:0}@media screen and (max-width: 768px){.content,body.sidebar-opening .content{left:0;width:100%}body.sidebar-closed .sidebar-button{position:absolute}}.sidebar{--sidebarFontSize: 16px;--sidebarLineHeight: 20px;font-family:var(--sansFontFamily);font-size:var(--sidebarFontSize);font-weight:300;line-height:var(--sidebarLineHeight);background-color:var(--sidebarBackground);color:var(--sidebarAccentMain);overflow:hidden;scrollbar-color:var(--sidebarScrollbarThumb) var(--sidebarScrollbarTrack)}.non-apple-os .sidebar{font-weight:400}.sidebar ul{list-style:none}.sidebar ul li{margin:0;padding:0 10px}.sidebar a{color:var(--sidebarAccentMain);text-decoration:none;transition:color .3s ease-in-out}.sidebar a:hover{color:var(--sidebarHover)}.sidebar .sidebar-header{background-color:var(--sidebarHeader);width:100%}.sidebar .sidebar-projectInfo{display:flex;justify-content:start;align-items:center;gap:16px;margin:12px 16px 12px 14px;max-width:235px}.sidebar .sidebar-projectImage{align-self:flex-end}.sidebar .sidebar-projectImage img{display:block;max-width:48px;max-height:48px}.sidebar .sidebar-projectName{font-weight:700;font-size:20px;line-height:24px;color:var(--sidebarAccentMain);margin:0;padding:0;max-width:230px;word-wrap:break-word}.sidebar .sidebar-projectVersion{display:block;position:relative;margin:0;padding:0;font-size:var(--sidebarFontSize);line-height:var(--sidebarLineHeight);color:var(--sidebarMuted)}.sidebar .sidebar-projectVersionsDropdown{cursor:pointer;position:relative;margin:0;padding:0 0 0 12px;border:none;-webkit-appearance:none;appearance:none;background-color:transparent;color:var(--sidebarMuted);z-index:2}.sidebar .sidebar-projectVersionsDropdown option{color:initial}.sidebar .sidebar-projectVersionsDropdownCaret{position:absolute;left:0;top:2px;z-index:1;font-size:8px;color:var(--sidebarMuted)}.sidebar .sidebar-projectVersionsDropdown::-ms-expand{display:none}.sidebar .sidebar-listNav{display:flex;margin:0;padding:4px 4px 0}.sidebar .sidebar-listNav :is(li,li button){text-transform:uppercase;letter-spacing:.02em;font-size:14px;color:var(--sidebarMuted)}.sidebar .sidebar-listNav li{display:inline-block;padding:0}.sidebar .sidebar-listNav li button{background:none;border:0;border-radius:0;-webkit-appearance:none;text-align:inherit;color:inherit;font-weight:inherit;cursor:pointer;display:inline-block;line-height:27px;padding:4px 10px 2px;transition:all .15s}.sidebar .sidebar-listNav li:is(.selected) button{background-color:var(--sidebarBackground);border-top:var(--navTabBorderWidth) solid var(--sidebarLanguageAccentBar)}.sidebar .sidebar-listNav li:not(.selected) button{border-top:var(--navTabBorderWidth) solid var(--sidebarHeader)}.sidebar .sidebar-listNav li:is(:hover):not(.selected) button{background-color:var(--gray600);border-top:var(--navTabBorderWidth) solid var(--gray400);color:var(--sidebarAccentMain);transition:all .15s}.sidebar .sidebar-tabpanel{flex:1 1 .01%;overflow-y:auto;overscroll-behavior:contain;position:relative;-webkit-overflow-scrolling:touch;margin-top:12px}.sidebar .full-list{margin:0;padding:0 0 20px;position:relative}.sidebar .full-list :is(li,a){overflow:hidden;text-overflow:ellipsis}.sidebar .full-list li{padding:0;margin-right:30px;line-height:27px;white-space:nowrap}.sidebar .full-list li.docs{margin-right:0}.sidebar .full-list li.open>ul{display:block;margin-left:10px}.sidebar .full-list li a.expand+button.icon-expand{appearance:none;background-color:transparent;border:0;padding:0;cursor:pointer;color:inherit;margin-right:10px;font-size:calc(1.2 * var(--sidebarFontSize));line-height:var(--sidebarLineHeight);position:absolute;display:flex;right:0;transform:translateY(calc(-100% - 4px))}.sidebar .full-list li a+button.icon-expand:after{font-family:remixicon;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sidebar .full-list li a.expand+button.icon-expand:after{content:var(--icon-arrow-down-s)}.sidebar .full-list li.open>a.expand+button.icon-expand:after{content:var(--icon-arrow-up-s)}.sidebar .full-list li.docs>a+button.icon-expand{margin-right:12px;font-size:var(--sidebarFontSize);line-height:var(--sidebarFontSize);transform:translateY(calc(-100% - 5px))}.sidebar .full-list li.docs>a+button.icon-expand:after{content:var(--icon-add)}.sidebar .full-list li.docs.open>a+button.icon-expand:after{content:var(--icon-subtract)}.sidebar .full-list li.nesting-context{font-weight:700;font-size:.9em;line-height:1.8em;color:var(--sidebarSubheadings);padding-left:15px}.sidebar .full-list li.group{text-transform:uppercase;font-weight:700;font-size:.8em;margin:1.5em 0 0;line-height:1.8em;color:var(--sidebarSubheadings);padding-left:15px}.sidebar .full-list li a{padding:3px 0 3px 15px;color:var(--sidebarItem)}.sidebar .full-list>li>a{display:block;width:100%;height:27px;line-height:var(--sidebarLineHeight)}.sidebar .full-list li .current-section>a{color:var(--sidebarActiveItem)}.sidebar .full-list li .current-section>a+button.icon-expand{color:var(--sidebarActiveItem)}.sidebar .full-list>li>a:hover{border-left:3px solid var(--sidebarLanguageAccentBar);padding-left:12px}.sidebar .full-list>li.current-page>a{color:var(--sidebarActiveItem);border-left:3px solid var(--sidebarLanguageAccentBar);padding-left:12px}.sidebar .full-list>li.current-page>a:after,.sidebar .full-list>li.current-page{color:var(--sidebarActiveItem)}.sidebar .full-list>li:last-child{margin-bottom:30px}.sidebar .full-list>li.group:first-child{margin-top:0}.sidebar .full-list ul{display:none;margin:10px 0 10px 15px;padding:0}.sidebar .full-list ul li{font-weight:300;line-height:var(--sidebarFontSize);padding:0 8px;margin-right:0;color:var(--sidebarAccentMain)}.non-apple-os .sidebar .full-list ul li{font-weight:400}.sidebar .full-list ul li.current-hash{color:var(--sidebarActiveItem)}.sidebar .full-list ul li.current-hash>a{color:var(--sidebarActiveItem)}.sidebar .full-list ul li.current-hash>a:before,.sidebar .full-list>li>ul>li>a:hover:before{content:"\2022";position:absolute;margin-left:-15px;color:var(--sidebarActiveItem)}.sidebar .full-list ul li a{padding-left:15px;display:block;width:100%;height:24px}.sidebar .full-list ul li ul{display:none;margin:9px 0 9px 20px}.sidebar .full-list ul li ul li{margin-right:0;height:20px;color:var(--sidebarAccentMain)}.sidebar .full-list ul li ul li a{border-left:1px solid var(--sidebarInactiveItemMarker);padding:0 10px;height:20px}.sidebar .full-list ul li ul li.current-hash>a:before{content:none}.sidebar .full-list ul li ul li>a:hover{border-color:var(--sidebarLanguageAccentBar)}.sidebar .full-list ul li ul li.current-hash>a{color:var(--sidebarActiveItem);border-color:var(--sidebarLanguageAccentBar)}.sidebar .full-list ul li ul li.current-hash>a{color:var(--sidebarActiveItem);margin-left:0}.sidebar ::-webkit-scrollbar{width:14px}::-webkit-scrollbar-track{background-color:var(--sidebarBackground)}.sidebar ::-webkit-scrollbar-thumb{background-color:var(--sidebarScrollbarThumb);border-radius:10px;border:3px solid var(--sidebarBackground)}.sidebar-button{cursor:pointer;background-color:transparent;border:none;font-size:var(--sidebarFontSize)}.sidebar-button:hover{color:var(--sidebarHover)}.sidebar-button{color:var(--sidebarAccentMain)}.sidebar-closed .sidebar-button{color:var(--contrast)}@media screen and (max-height: 500px){.sidebar{overflow-y:auto}.sidebar .full-list{overflow:visible}}.top-search{background-color:var(--background);top:0;z-index:99;position:relative;width:100%;padding:10px 0}.search-settings{display:flex;column-gap:12px;align-items:center;width:100%;position:relative}.search-bar{border:1px solid var(--searchBarBorder);border-radius:8px;height:48px;position:relative;width:100%}.top-search .search-bar .search-input{background-color:var(--searchSearch);border:none;border-radius:8px;color:var(--searchAccentMain);position:relative;height:46px;padding:8px 35px 8px 43px;width:100%}.top-search .search-bar .search-input::placeholder{color:var(--searchAccentMain);opacity:.5}.top-search .search-bar .search-input:focus{border:1px solid var(--searchBarFocusColor);border-radius:7px;position:relative;box-shadow:0 4px 20px 0 var(--searchBarBorderColor) inset}.top-search .search-bar .search-label{position:relative}.top-search .search-bar .search-button{font-size:14px;color:var(--searchAccentMain);background-color:transparent;border:none;cursor:pointer;left:11px;opacity:.5;padding:5px 1px 5px 5px;position:absolute;top:60%;transform:translateY(-60%);z-index:99}.top-search .search-bar.selected .search-button,.top-search .search-bar .search-button:hover,.top-search .search-bar .search-button:focus{color:var(--top-searchLanguageAccentBar);opacity:1}.top-search .search-bar .search-close-button{font-size:16px;color:var(--searchAccentMain);background-color:transparent;border:none;cursor:pointer;right:11px;margin:0;opacity:.5;padding:5px 1px 5px 0;position:absolute;transform:scaleY(0);top:calc(50% - 13px);transition:.15s transform ease-out;z-index:99}.top-search .search-bar .search-close-button:hover{opacity:.7}.top-search .search-settings button.icon-settings{display:flex;align-items:center;justify-content:flex-end}.top-search .search-settings .icon-settings{font-size:20px;float:right;color:var(--iconAction);text-decoration:none;border:none;transition:color .3s ease-in-out;background-color:transparent;cursor:pointer;padding:0}.top-search .search-settings .icon-settings:hover{color:var(--iconActionHover)}.top-search .search-settings .icon-settings:visited{color:var(--iconAction)}@media screen and (max-width: 768px){.top-search{padding-left:calc(var(--content-gutter) + 36px);padding-right:var(--content-gutter);margin-left:calc(-1 * var(--content-gutter));margin-right:calc(-1 * var(--content-gutter));width:calc(2 * var(--content-gutter) + 100%)}.search-settings{width:100%;box-sizing:border-box}}body.search-focused .search-bar .search-close-button{transform:scaleY(1);transition:transform .15s ease-out .15s}@media screen and (hover: hover){body.search-focused .top-search{position:sticky!important}body.search-focused.sidebar-closed .sidebar-button{position:fixed!important}}@media screen and (hover: none){body.scroll-sticky .top-search{position:sticky!important}body.scroll-sticky.sidebar-closed .sidebar-button{position:fixed!important}}*:focus,button:focus,[type=button]:focus,[type=reset]:focus,[type=submit]:focus{outline:2px solid var(--main);outline-offset:-2px}*:focus:not(:focus-visible),button:focus:not(:focus-visible),[type=button]:focus:not(:focus-visible),[type=reset]:focus:not(:focus-visible),[type=submit]:focus:not(:focus-visible){outline:0}input[type=text],input[type=number],input[type=date],input[type=datetime],input[type=datetime-local],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=time],input[type=url],input[type=week],textarea{outline:0}.content-inner{font-family:var(--defaultFontFamily);font-size:1em;line-height:1.6875em;position:relative;background-color:var(--background);color:var(--textBody)}.content-inner :is(h1,h2,h3,h4,h5,h6){font-family:var(--sansFontFamily);font-weight:700;line-height:1.5em;word-wrap:break-word;color:var(--textHeaders)}.content-inner h1{font-size:2em;margin:.5em 0}.content-inner h1.signature{margin:0}.content-inner h1.section-heading{margin:1.5em 0 .5em}.content-inner h1 small{font-weight:300}.content-inner h1 .icon-action{font-size:1.2rem;font-weight:400}.content-inner h2{font-size:1.6em;margin:1em 0 .5em;font-weight:700}.content-inner h3{font-size:1.375em;margin:1em 0 .5em;font-weight:700}.content-inner li+li{margin-top:.25em}.content-inner :is(a,.a-main){color:var(--links);text-decoration:underline;text-decoration-color:var(--linksDecoration);text-decoration-skip-ink:auto}.content-inner :is(a:visited,.a-main:visited){color:var(--linksVisited)}.content-inner .icon-action{float:right;color:var(--iconAction);text-decoration:none;border:none;transition:color .3s ease-in-out;background-color:transparent;cursor:pointer}.content-inner button.icon-action{margin-top:12px}.content-inner .icon-action:hover{color:var(--iconActionHover)}.content-inner .icon-action:visited{color:var(--iconAction)}.content-inner .livebook-badge-container{display:flex}.content-inner a.livebook-badge{display:inline-flex}.content-inner .note{color:var(--iconAction);margin-right:5px;font-size:14px;font-weight:400}.content-inner blockquote{border-left:3px solid var(--blockquoteBorder);position:relative;margin:1.5625em 0;padding:0 1.2rem;overflow:auto;background-color:var(--blockquoteBackground);border-radius:var(--borderRadius)}.content-inner blockquote p:last-child{padding-bottom:1em;margin-bottom:0}.content-inner table{margin:2em 0;border-collapse:collapse}.content-inner th{text-align:left;font-family:var(--sansFontFamily);text-transform:uppercase;font-weight:700;padding-bottom:.5em}.content-inner thead tr{border-bottom:1px solid var(--tableHeadBorder)}.content-inner tbody tr{border-bottom:1px solid var(--tableBodyBorder)}.content-inner tbody tr:last-child{border-bottom:none}.content-inner tr{vertical-align:bottom;height:2.5em}.content-inner :is(td,th){padding:.25em .25em .25em 1em;line-height:2em;vertical-align:top}.content-inner .section-heading{--icon-size: 16px;--icon-spacing: 5px;display:grid;grid-template:1fr / 1fr}.content-inner .section-heading>:is(.hover-link,.text){grid-row:1;grid-column:1}.content-inner .section-heading .hover-link{text-decoration:none}.content-inner .section-heading i{font-size:var(--icon-size);margin-top:.1em;margin-left:calc(-1 * (var(--icon-size) + var(--icon-spacing)));padding-right:var(--icon-spacing);opacity:0}@media screen and (max-width: 768px){.content-inner .section-heading i{margin-left:calc(-1 * (var(--icon-size)))}}.content-inner blockquote .section-heading i{display:none}.content-inner .section-heading .hover-link:is(:hover,:focus) i{opacity:1}.content-inner .section-heading .text{pointer-events:none}.content-inner .section-heading .text a{pointer-events:all}.content-inner .app-vsn{display:none!important;font-size:.6em;line-height:1.5em}@media screen and (max-width: 768px){.content-inner .app-vsn{display:block!important}}.content-inner img{max-width:100%}.content-inner strong>code{font-weight:700}.content-inner code{font-family:var(--monoFontFamily);font-style:normal;line-height:24px;font-weight:400}@media screen and (max-width: 768px){.content-inner :is(ol,ul){padding-left:calc(1.5 * var(--content-gutter))}}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip){border-radius:10px;border-left:0}.content-inner blockquote.warning{background-color:var(--warningBackground)}.content-inner blockquote.error{background-color:var(--errorBackground)}.content-inner blockquote.info{background-color:var(--infoBackground)}.content-inner blockquote.neutral{background-color:var(--neutralBackground)}.content-inner blockquote.tip{background-color:var(--tipBackground)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip){color:var(--contrast);margin:0 -1.2rem;padding:.7rem 1.2rem .7rem 3.3rem;font-weight:700;font-style:normal}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip):before{color:var(--contrast);position:absolute;left:1rem;font-size:1.8rem;font-family:remixicon;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.content-inner blockquote :is(h3,h4).warning{background-color:var(--warningHeadingBackground);color:var(--warningHeading)}.content-inner blockquote :is(h3,h4).warning:before{content:var(--icon-error-warning);color:var(--warningHeading)}.content-inner blockquote :is(h3,h4).error{background-color:var(--errorHeadingBackground);color:var(--errorHeading)}.content-inner blockquote :is(h3,h4).error:before{content:var(--icon-error-warning);color:var(--errorHeading)}.content-inner blockquote :is(h3,h4).info{background-color:var(--infoHeadingBackground);color:var(--infoHeading)}.content-inner blockquote :is(h3,h4).info:before{content:var(--icon-information);color:var(--infoHeading)}.content-inner blockquote :is(h3,h4).neutral{background-color:var(--neutralHeadingBackground);color:var(--neutralHeading)}.content-inner blockquote :is(h3,h4).neutral:before{content:var(--icon-double-quotes-l);color:var(--neutralHeading)}.content-inner blockquote :is(h3,h4).tip{background-color:var(--tipHeadingBackground);color:var(--tipHeading)}.content-inner blockquote :is(h3,h4).tip:before{content:var(--icon-information);color:var(--tipHeading)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip) code{margin:0 .5ch}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip) code{background-color:var(--admInlineCodeBackground);border:1px solid var(--admInlineCodeBorder);color:var(--admInlineCodeColor)}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip) pre code{background-color:var(--admCodeBackground);border:1px solid var(--admCodeBorder);color:var(--admCodeColor)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip) :is(a,a:visited){color:inherit;text-decoration-color:currentColor}@media screen and (max-width: 768px){.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip){margin-left:calc(-1 * var(--content-gutter));margin-right:calc(-1 * var(--content-gutter));padding-left:var(--content-gutter);padding-right:var(--content-gutter);border-radius:0}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip){margin:0 calc(-1 * var(--content-gutter))}}.content-inner .summary h2{font-weight:700}.content-inner .summary h2 a{text-decoration:none;border:none}.content-inner .summary span.deprecated{color:var(--darkDeprecated);font-weight:400;font-style:italic}.content-inner .summary .summary-row .summary-signature{font-family:var(--monoFontFamily);font-weight:700}.content-inner .summary .summary-row .summary-signature a{text-decoration:none;border:none}.content-inner .summary .summary-row .summary-synopsis{font-family:var(--defaultFontFamily);font-style:italic;padding:0 1.2em;margin:0 0 .5em}.content-inner .summary .summary-row .summary-synopsis p{margin:0;padding:0}.content-inner :is(a.no-underline,pre a){color:var(--linksNoUnderline);text-shadow:none;text-decoration:none;background-image:none}.content-inner :is(a.no-underline,pre a):is(:visited,:active,:focus,:hover){color:var(--linksNoUnderlineVisited)}.content-inner code{background-color:var(--codeBackground);vertical-align:baseline;border-radius:2px;padding:.1em .2em;border:1px solid var(--codeBorder);text-transform:none}.content-inner pre{margin:var(--baseLineHeight) 0}.content-inner pre code{display:block;overflow-x:auto;white-space:inherit;padding:.5em 1em}.content-inner pre code::-webkit-scrollbar{width:.4rem;height:.4rem}.content-inner pre code::-webkit-scrollbar-thumb{border-radius:.25rem;background-color:var(--codeScrollThumb)}.content-inner pre code::-webkit-scrollbar-track{background-color:var(--codeScrollBackground)}.content-inner pre code::-webkit-scrollbar-corner{background-color:var(--codeScrollBackground)}.content-inner pre code.output{margin:0 12px;max-height:400px;overflow:auto}.content-inner pre code.output+.copy-button{margin-right:12px}.content-inner pre code.output:before{content:"Output";display:block;position:absolute;top:-16px;left:12px;padding:2px 4px;font-size:12px;font-family:var(--monoFontFamily);line-height:1;color:var(--textHeaders);background-color:var(--codeBackground);border:1px solid var(--codeBorder);border-bottom:0;border-radius:2px}@media screen and (max-width: 768px){.content-inner>pre,.content-inner section>pre{margin-left:calc(-1 * var(--content-gutter));margin-right:calc(-1 * var(--content-gutter))}.content-inner>pre code,.content-inner section>pre code{padding-left:var(--content-gutter);padding-right:var(--content-gutter);border-radius:0;border-left-width:0;border-right-width:0}}@keyframes blink-background{0%{background-color:var(--textDetailBackground)}to{background-color:var(--blink)}}.content-inner .detail:target .detail-header{animation-duration:.55s;animation-name:blink-background;animation-iteration-count:1;animation-timing-function:ease-in-out}.content-inner .detail-header{margin:2 0 1em;padding:.5em 1em;background-color:var(--textDetailBackground);border-left:3px solid var(--textDetailAccent);font-size:1em;font-family:var(--monoFontFamily);position:relative}.content-inner .detail-header .note{float:right}.content-inner .detail-header .signature{display:inline-block;font-family:var(--monoFontFamily);font-size:1rem;font-weight:700}.content-inner .detail-header:hover a.detail-link,.content-inner .detail-header a.detail-link:focus{opacity:1;text-decoration:none}.content-inner .detail-header a.detail-link{transition:opacity .3s ease-in-out;position:absolute;top:0;left:0;display:block;opacity:0;padding:.6em;line-height:1.5em;margin-left:-2.5em;text-decoration:none;border:none}@media screen and (max-width: 768px){.content-inner .detail-header a.detail-link{margin-left:-30px}}.content-inner .specs pre{font-family:var(--monoFontFamily);font-size:.9em;font-style:normal;line-height:24px;white-space:pre-wrap;margin:0;padding:0}.content-inner .specs .attribute{color:var(--fnSpecAttr)}.content-inner .docstring{margin:1.2em 0 3em 1.2em}@media screen and (max-width: 768px){.content-inner .docstring{margin-left:0}}.content-inner .docstring:is(h2,h3,h4,h5){font-weight:700}.content-inner .docstring h2{font-size:1.1em}.content-inner .docstring h3{font-size:1em}.content-inner .docstring h4{font-size:.95em}.content-inner .docstring h5{font-size:.9em}.content-inner div.deprecated{display:block;padding:9px 15px;background-color:var(--fnDeprecated)}.content-inner .footer{margin:4em auto 1em;text-align:center;font-style:italic;font-size:14px}.content-inner .footer,.content-inner .footer :is(a,.footer-button){color:var(--textFooter)}.content-inner .footer .line{display:inline-block}.content-inner .footer .footer-button{background-color:transparent;border:0;cursor:pointer;font-style:italic;padding:0 4px}.content-inner .footer .footer-hex-package{margin-right:4px}.content-inner .bottom-actions{display:flex;justify-content:space-between;margin-top:4em}.content-inner .bottom-actions .bottom-actions-button{display:flex;text-decoration:none;flex-direction:column;border-radius:var(--borderRadius);border:1px solid var(--bottomActionsBtnBorder);padding:8px 16px;min-width:150px}.content-inner .bottom-actions .bottom-actions-button .subheader{font-size:.8em;color:var(--bottomActionsBtnSubheader);white-space:nowrap}.content-inner .bottom-actions .bottom-actions-button[rel=prev] .subheader{text-align:right}@media screen and (max-width: 768px){.content-inner .bottom-actions{flex-direction:column-reverse}.content-inner .bottom-actions .bottom-actions-item:not(:first-child){margin-bottom:16px}}.page-cheatmd .content-inner{--horizontal-space: 1.5em;--vertical-space: 1em}@media (max-width: 600px){.page-cheatmd .content-inner{--horizontal-space: 1em;--vertical-space: .75em}}.page-cheatmd .content-inner{max-width:1200px}.page-cheatmd .content-inner h1{margin-bottom:var(--vertical-space)}.page-cheatmd .content-inner h2{margin:var(--vertical-space) 0;column-span:all;color:var(--gray700);font-weight:500}.page-cheatmd.dark .content-inner h2{color:var(--gray200)}.page-cheatmd .content-inner h3{color:var(--main);text-decoration-color:var(--main);margin:0 0 1em;font-weight:400}.page-cheatmd .content-inner h3 :is(a,a:visited){color:var(--main);text-decoration-color:var(--main)}.page-cheatmd .content-inner section.h3{min-width:300px;margin:0;padding:0 0 calc(var(--vertical-space) * 2) 0;break-inside:avoid}.page-cheatmd .content-inner h3 .text{overflow:hidden}.page-cheatmd .content-inner h3 .text:after{content:"";margin-left:calc(var(--horizontal-space) / 2);vertical-align:baseline;display:inline-block;width:100%;height:1px;margin-right:-100%;margin-bottom:5px;background-color:var(--codeBorder)}.page-cheatmd .content-inner h4{display:block;margin:0;padding:.25em var(--horizontal-space);font-weight:400;background:var(--gray100);color:#567;border:solid 1px 1px 0 1px var(--gray100)}.page-cheatmd.dark .content-inner h4{background:#192f50;color:var(--textBody);border:1px solid #192f50;border-bottom:0}.page-cheatmd .content-inner .h2 p{margin:0;display:block;background:var(--gray50);padding:var(--vertical-space) var(--horizontal-space)}.page-cheatmd.dark .content-inner .h2 p{background:var(--gray700)}.page-cheatmd .content-inner .h2 p>code{color:#eb5757;border-radius:var(--borderRadius);padding:.2em .4em}.page-cheatmd .content-inner pre code{padding:var(--vertical-space) var(--horizontal-space)}.page-cheatmd .content-inner pre code::-webkit-scrollbar{width:.4rem;height:.6rem}.page-cheatmd .content-inner .h2 pre{margin:0}.page-cheatmd .content-inner .h2 pre+pre{margin-top:-1px}.page-cheatmd .content-inner pre.wrap{white-space:break-spaces}@media screen and (max-width: 768px){.page-cheatmd .content-inner pre code{border-left-width:1px!important;border-right-width:1px!important}}.page-cheatmd .content-inner .h2 table{display:table;box-sizing:border-box;width:100%;border-collapse:collapse;margin:0}.page-cheatmd .content-inner .h2 th{padding:var(--vertical-space) var(--horizontal-space);line-height:inherit;margin-bottom:-1px;vertical-align:middle;border-bottom:1px solid var(--codeBorder)}.page-cheatmd .content-inner .h2 td{padding:var(--vertical-space) var(--horizontal-space);border:0;border-bottom:1px solid var(--codeBorder)}.page-cheatmd .content-inner .h2 tr:first-child{border-top:1px solid var(--codeBorder)}.page-cheatmd .content-inner .h2 td code{color:#eb5757;border-radius:var(--borderRadius);padding:.2em .4em}.page-cheatmd .content-inner .h2 thead{background-color:var(--gray50)}.page-cheatmd.dark .content-inner .h2 thead{background-color:var(--gray700)}.page-cheatmd .content-inner .h2 tbody{background-color:var(--codeBackground)}.page-cheatmd .content-inner .h2 :is(ul,ol){margin:0;padding:0}.page-cheatmd .content-inner .h2 li{list-style-position:inside;padding:.5em var(--horizontal-space);line-height:2em;vertical-align:middle;background-color:var(--codeBackground);border-bottom:1px solid var(--codeBorder);margin-top:0}.page-cheatmd .content-inner .h2 :is(ul,ol)+pre code{border-top:0}.page-cheatmd .content-inner .h2 li>code{color:#eb5757;border-radius:var(--borderRadius);padding:.2em .4em}.page-cheatmd .content-inner section.width-50{display:block;width:50%;margin:0}.page-cheatmd .content-inner section.width-50>section>table{width:100%}.page-cheatmd .content-inner section:is(.col-2,.col-2-left,.col-3){column-gap:40px}.page-cheatmd .content-inner section.col-2{column-count:2;height:auto}.page-cheatmd .content-inner section.col-2-left{display:grid;grid-template-columns:calc(100% / 3) auto}.page-cheatmd .content-inner section.col-2-left>h2{grid-column-end:span 2}.page-cheatmd .content-inner section.col-3{column-count:3;height:auto}.page-cheatmd .content-inner section.list-4>ul{display:flex;flex-wrap:wrap}.page-cheatmd .content-inner section.list-4>ul>li{flex:0 0 25%}.page-cheatmd .content-inner section.list-6>ul{display:flex;flex-wrap:wrap}.page-cheatmd .content-inner section.list-6>ul>li{flex:0 0 calc(100% / 6)}@media screen and (max-width: 1400px){.page-cheatmd .content-inner section.col-3{column-count:2}.page-cheatmd .content-inner section.col-2-left{display:flex;flex-direction:column}}@media screen and (max-width: 1200px){.page-cheatmd .content-inner section:is(.col-2,.col-3){display:flex;flex-direction:column}.page-cheatmd .content-inner section.list-6>ul>li{flex:0 0 25%}}@media screen and (max-width: 1000px){.page-cheatmd .content-inner section:is(.list-4,.list-6)>ul>li{flex:0 0 calc(100% / 3)}}@media screen and (max-width: 600px){.page-cheatmd .content-inner section:is(.list-4,.list-6)>ul>li{flex:0 0 50%}.page-cheatmd .content-inner section.width-50{width:100%}}#search{min-height:200px;position:relative}#search .loading{height:64px;width:64px;position:absolute;top:50%;left:calc(50% - 32px)}#search .loading div{box-sizing:border-box;display:block;position:absolute;width:51px;height:51px;margin:6px;border:6px solid var(--coldGray);border-radius:50%;animation:loading 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:var(--coldGray) transparent transparent transparent}#search .loading div:nth-child(1){animation-delay:-.45s}#search .loading div:nth-child(2){animation-delay:-.3s}#search .loading div:nth-child(3){animation-delay:-.15s}@keyframes loading{0%{transform:rotate(0)}to{transform:rotate(360deg)}}#search .result{margin:2em 0 2.5em}#search .result p{margin:0}#search .result-id{font-size:1.4em;margin:0}#search .result-id a{text-decoration:none;transition:color .1s ease-in-out;color:var(--links)}#search .result-id a:is(:visited,:active,:focus){color:var(--linksVisited)}#search .result-id a:hover{color:var(--main)}#search :is(.result-id,.result-elem) em{font-style:normal;color:var(--main)}#search .result-id small{font-weight:400}@keyframes keyboard-shortcuts-show{0%{opacity:0}to{opacity:1}}.modal{animation-duration:.15s;animation-name:keyboard-shortcuts-show;animation-iteration-count:1;animation-timing-function:ease-in-out;display:none;background-color:#000000bf;position:fixed;inset:0;z-index:300}.modal.shown{display:block}.modal .modal-contents{margin:75px auto 0;max-width:500px;background-color:var(--modalBackground);border-radius:var(--borderRadius);box-shadow:2px 2px 8px #0003;padding:25px 35px 35px}@media screen and (max-width: 768px){.modal .modal-contents{padding:20px}}.modal .modal-header{display:flex;align-items:start}.modal .modal-title{display:inline-block;flex-grow:1;font-size:1.2rem;font-weight:700;margin-bottom:20px}.modal .modal-title button{border:none;background-color:transparent;color:var(--textHeaders);font-weight:700;margin-right:30px;padding-left:0;text-align:left;transition:color .15s}.modal .modal-title button:hover{color:var(--main);cursor:pointer}.modal .modal-title button.active{color:var(--main)}.modal .modal-close{cursor:pointer;display:block;font-size:1.5rem;margin:-8px -8px 0 0;padding:8px;opacity:.7;background-color:transparent;color:var(--textHeaders);border:none;transition:opacity .15s}.modal .modal-close:hover{opacity:1}#keyboard-shortcuts-content dl.shortcut-row{display:flex;align-items:center;justify-content:space-between;margin:0;padding:6px 0 8px;border-bottom:1px solid var(--settingsSectionBorder)}#keyboard-shortcuts-content dl.shortcut-row:last-of-type{border-bottom-style:none}#keyboard-shortcuts-content dl.shortcut-row:first-child{padding-top:0}#keyboard-shortcuts-content :is(.shortcut-keys,.shortcut-description){display:inline-block}#keyboard-shortcuts-content kbd>kbd{background-color:var(--settingsInputBorder);color:var(--contrast);border-radius:var(--borderRadius);font-family:inherit;font-weight:700;display:inline-block;line-height:1;padding:4px 7px 6px;min-width:26px;text-align:center}#keyboard-shortcuts-content :is(.shortcut-keys,.shortcut-description){margin:0}#quick-switch-modal-body{width:100%;position:relative}#quick-switch-modal-body .ri-search-2-line{position:absolute;left:0;top:0;padding:4px 10px;color:var(--quickSwitchContour);font-weight:700}#quick-switch-modal-body #quick-switch-input{width:100%;padding:8px 6px 8px 38px;border:none;color:var(--quickSwitchInput);background-color:transparent;border-bottom:1px solid var(--quickSwitchContour);box-sizing:border-box;transition:all .12s ease-out}#quick-switch-modal-body #quick-switch-results{margin:0}#quick-switch-modal-body .quick-switch-result{padding:2px 5px;border-bottom:1px dotted var(--quickSwitchContour);transition:all .12s ease-out}#quick-switch-modal-body .quick-switch-result:last-child{border-bottom:none}#quick-switch-modal-body .quick-switch-result:hover{cursor:pointer}#quick-switch-modal-body .quick-switch-result:is(:hover,.selected){border-left:4px solid var(--main);background-color:var(--codeBackground)}.autocomplete{display:none;position:absolute;width:calc(100% - 32px);top:55px}.autocomplete .triangle{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-bottom:12px solid var(--autocompleteBackground);position:absolute;top:8px;left:26px;transform:translate(-50%);z-index:100;background-color:transparent}.autocomplete-preview{width:100%;margin:0;height:100%;line-height:20px;background-color:var(--background);font-family:var(--sansFontFamily);border:4px solid var(--autocompleteBorder);padding:12px 16px}.autocomplete-preview div,.autocomplete-preview span{display:none}.autocomplete-preview.loading div{float:left;display:block;border:5px solid var(--autocompleteBorder);border-radius:50%;border-top:5px solid var(--textDetailAccent);width:20px;height:20px;animation:spinner 4s linear infinite}.autocomplete-preview.loading span{color:var(--autocompleteResults);display:inline;margin-left:6px}.autocomplete-preview.loading span:after{color:var(--autocompleteResults);content:"Loading"}@keyframes spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.autocomplete-preview.loading iframe{height:0}.autocomplete-preview iframe{width:100%;height:100%;border:0}.autocomplete-results{list-style:none;margin:0;padding:15px 20px;display:flex;justify-content:space-between;color:var(--autocompleteResults);font-family:var(--sansFontFamily);font-weight:300;font-size:.9rem}.autocomplete-results .bold{color:var(--autocompleteResultsBold);font-weight:400}.autocomplete.shown{display:block}.autocomplete-container{position:absolute;top:15px;width:100%;z-index:200}.autocomplete-suggestions{background-color:var(--autocompleteBackground);border-radius:8px;box-shadow:0 15px 99px 0 var(--autocompleteBorder);overflow-y:auto;max-height:450px;white-space:normal;overflow-x:hidden;overscroll-behavior-y:contain}.autocomplete-suggestions.previewing:has(.selected){max-height:80vh}.autocomplete-suggestions.previewing:has(.selected) .autocomplete-suggestion:not(.selected){display:none}.autocomplete-suggestions.previewing:not(:has(.selected)) .autocomplete-preview{display:none}.autocomplete-suggestions:not(.previewing) .autocomplete-preview{display:none}.autocomplete-suggestion{color:inherit;display:block;padding:12px 20px;text-decoration:none;transition:background-color .3s ease-in-out;border-top:1px solid var(--suggestionBorder);font-size:.9rem}.autocomplete-suggestion:hover,.autocomplete-suggestion.selected{background-color:var(--autocompleteHover)}.autocomplete-suggestion:not(.selected) .autocomplete-preview-indicator{display:none}.autocomplete-preview-indicator{float:right}.autocomplete-preview-indicator button{color:var(--iconAction);display:flex;align-items:center;text-decoration:none;border:1px solid var(--suggestionBorder);border-radius:8px;transition:color .3s ease-in-out;background-color:var(--autocompletePreview);cursor:pointer;padding:4px 8px;font-size:14px}.autocomplete-preview-indicator button:hover{color:var(--iconActionHover);background-color:var(--autocompleteHover)}.autocomplete-preview-indicator button i{margin-right:4px}.autocomplete-suggestions.previewing .autocomplete-preview-indicator-closed{display:none}.autocomplete-suggestions:not(.previewing) .autocomplete-preview-indicator-open{display:none}.autocomplete-suggestion:hover:not(.selected) .autocomplete-preview-indicator-closed{display:block}.autocomplete-suggestion em{font-style:normal;font-weight:700}.autocomplete-suggestion .description{opacity:.6;padding-top:3px}.autocomplete-suggestion .label{background-color:var(--autocompleteLabelBack);opacity:.6;color:var(--autocompleteLabelFont);padding:4px 8px;border-radius:4px;margin-left:5px;text-transform:uppercase;font-family:var(--sansFontFamily);font-size:.7rem}.autocomplete-suggestion .header{margin-right:5px}.autocomplete-suggestion .title,.autocomplete-suggestion .description{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.autocomplete-suggestions a{text-decoration:none!important}.autocomplete-suggestions::-webkit-scrollbar{width:5px;border-radius:7px;flex-shrink:0}.autocomplete-suggestions::-webkit-scrollbar-thumb{background-color:var(--autocompleteSrollbarThumb);border-radius:7px}.autocomplete-suggestions::-webkit-scrollbar-track{background-color:var(--autocompleteSrollbarTrack)}@media screen and (max-width: 1023px){.autocomplete-results .press-return{display:none}}.tooltip{box-shadow:0 0 10px var(--black-opacity-10);max-height:300px;max-width:500px;padding:0;position:absolute;pointer-events:none;margin:0;z-index:99;top:0;left:0;visibility:hidden;transform:translateY(20px);opacity:0;transition:.2s visibility ease-out,.2s transform ease-out,.2s opacity ease-out}.tooltip.tooltip-shown{visibility:visible;transform:translateY(0);opacity:1}.tooltip .tooltip-body{border:1px solid var(--codeBorder)}.tooltip .tooltip-body .signature{min-width:320px;width:100%}.tooltip .tooltip-body .detail-header{border-left:0;margin-bottom:0;margin-top:0}.tooltip .tooltip-body .docstring{background-color:var(--background);padding:1.2em;margin:0;width:498px}.tooltip .tooltip-body .docstring-plain{max-width:498px;width:auto}.tooltip .tooltip-body .version-info{float:right;line-height:1.6rem;font-family:var(--monoFontFamily);font-size:.9rem;font-weight:400;margin-bottom:-6px;opacity:.3;padding-left:.3em}pre{position:relative}pre:hover .copy-button,pre .copy-button:focus{opacity:1}.copy-button{display:flex;opacity:0;position:absolute;top:5px;right:5px;padding:4px;background-color:var(--codeBackground);border:none;cursor:pointer;transition:all .15s;font-family:var(--defaultFontFamily);font-size:14px;line-height:24px;color:currentColor}.copy-button svg{opacity:.5;transition:all .15s}pre .copy-button:hover svg,pre .copy-button:focus-visible svg{opacity:1}.copy-button svg{width:20px}.copy-button.clicked{opacity:1;color:var(--success)}.copy-button.clicked svg{display:none;color:currentColor}#settings-modal-content{margin-top:10px}#settings-modal-content .hidden{display:none}#settings-modal-content .input{box-sizing:border-box;width:80%;padding:8px;font-size:14px;background-color:var(--settingsInputBackground);color:var(--settingsInput);border:1px solid var(--settingsInputBorder);border-radius:8px;transition:border-color .15s}#settings-modal-content .input:focus{border-color:var(--main)}#settings-modal-content .input::placeholder{color:var(--gray400)}#settings-modal-content .switch-button-container{display:flex;align-items:center;justify-content:space-between;border-top:1px solid var(--settingsSectionBorder);padding:10px 0}#settings-modal-content .switch-button-container:first-of-type{border-top-style:none;padding-top:0}#settings-modal-content .switch-button-container>div>span{font-size:18px}#settings-modal-content .switch-button-container>div>p{font-size:14px;font-weight:300;line-height:1.4;margin:0;padding-bottom:6px;padding-right:10px}#settings-modal-content .switch-button{position:relative;display:inline-block;flex-shrink:0;width:40px;height:20px;user-select:none;transition:all .15s}#settings-modal-content .switch-button__checkbox{appearance:none;position:absolute;display:block;width:20px;height:20px;border-radius:1000px;background-color:#91a4b7;border:3px solid #e5edf5;cursor:pointer;transition:all .3s}#settings-modal-content .switch-button__bg{display:block;width:100%;height:100%;border-radius:1000px;background-color:#e5edf5;cursor:pointer;transition:all .3s}#settings-modal-content .switch-button__checkbox:checked{background-color:#fff;border-color:var(--main);transform:translate(100%)}#settings-modal-content .switch-button__checkbox:checked+.switch-button__bg{background-color:var(--main)}#settings-modal-content .switch-button__checkbox:focus{outline:0}#settings-modal-content .switch-button__checkbox:focus+.switch-button__bg{outline:2px solid var(--main);outline-offset:2px}#settings-modal-content .switch-button__checkbox:focus:not(:focus-visible)+.switch-button__bg{outline:0}#settings-modal-content .settings-select{cursor:pointer;position:relative;border:none;background-color:transparent;color:var(--textBody)}#settings-modal-content .settings-select option{color:initial}#toast{opacity:0;position:fixed;z-index:1;left:50%;bottom:1rem;min-width:3rem;margin:0 -1.2rem;padding:.7rem 1.2rem;text-align:center;font-weight:700;border-radius:10px;border:1px solid var(--codeBorder);background-color:var(--codeBackground);color:var(--textBody);transition:opacity .4s ease-in-out,transform .3s ease-out;cursor:default}#toast.show{opacity:1;transform:translateY(-.75rem)}@media (prefers-reduced-motion: reduce){#toast{transition:none}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0;user-select:none}@media print{.body-wrapper{display:block}.sidebar,.sidebar-button,.top-search{display:none}.content{padding-left:0;overflow:visible;left:0;width:100%}.summary-row{break-inside:avoid}#toast{display:none}.content-inner{padding:0}.content-inner .section-heading a.hover-link,.content-inner button.icon-action,.content-inner a.icon-action,.content-inner .bottom-actions{display:none}.footer p:first-of-type{display:none}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip){border:2px solid var(--gray400)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip){color:var(--textHeaders);border-bottom:2px solid var(--gray400)}.content-inner pre code.makeup{border-color:var(--gray400);white-space:break-spaces;break-inside:avoid}.content-inner blockquote code.inline,.content-inner code.inline{border-color:var(--gray400)}}@media print{.page-cheatmd .content-inner *{background-color:transparent!important;border-color:var(--gray400)!important}.page-cheatmd .content-inner{max-width:100%;width:100%;padding:0;font-size:.7em}.page-cheatmd .content-inner section:is(.col-2,.col-2-left,.col-3){column-gap:30px}.page-cheatmd .content-inner section.col-2{column-count:2}.page-cheatmd .content-inner section.col-2-left{display:grid}.page-cheatmd .content-inner section.col-3{column-count:3}.page-cheatmd .content-inner h1{margin-top:0;margin-bottom:.5em}.page-cheatmd .content-inner h2.section-heading{font-weight:700;margin-top:1em;column-span:all}.page-cheatmd .content-inner section.h2{break-inside:avoid}.page-cheatmd .content-inner h3{font-weight:700;color:var(--mainDark)}.page-cheatmd .content-inner h3:after{height:2px;background-color:var(--gray400)}.page-cheatmd .content-inner section.h3{min-width:300px;break-inside:avoid}.page-cheatmd .content-inner h4{padding:.5em 0;border:none;font-weight:700;color:#000}.page-cheatmd .content-inner .h2 p{padding-left:0;padding-right:0;border:none!important}.page-cheatmd .content-inner code{line-height:1.5em}.page-cheatmd .content-inner .h2 table{font-variant-numeric:tabular-nums;break-inside:avoid}.page-cheatmd .content-inner .h2 :is(th,td){vertical-align:top;padding-left:0;padding-right:0}.page-cheatmd .content-inner .h2 thead{border-style:solid none;border-width:1px}.page-cheatmd .content-inner .h2 tr{border-bottom:none}.page-cheatmd .content-inner .h2 th{font-weight:700}.page-cheatmd .content-inner .h2 li{padding-left:0;padding-right:0;vertical-align:middle;border-bottom:none}.page-cheatmd .content-inner pre:hover button.copy-button,.page-cheatmd .content-inner div.tooltip{display:none}.page-cheatmd .content-inner footer p:not(.built-using){display:none}}code.makeup .unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.makeup .hll{background-color:#ffc}.makeup .bp{color:#3465a4}.makeup .c,.makeup .c1,.makeup .ch,.makeup .cm,.makeup .cp,.makeup .cpf,.makeup .cs{color:#4d4d4d}.makeup .dl{color:#408200}.makeup .err{color:#a40000;border:#ef2929}.makeup .fm,.makeup .g{color:#4d4d4c}.makeup .gd{color:#a40000}.makeup .ge{color:#4d4d4c;font-style:italic}.makeup .gh{color:navy;font-weight:700}.makeup .gi{color:#00a000}.makeup .go{color:#4d4d4c;font-style:italic}.makeup .gp{color:#4d4d4d}.makeup .gr{color:#ef2929}.makeup .gs{color:#4d4d4c;font-weight:700}.makeup .gt{color:#a40000;font-weight:700}.makeup .gu{color:purple;font-weight:700}.makeup .il{color:#0000cf;font-weight:700}.makeup .k,.makeup .kc,.makeup .kd,.makeup .kn,.makeup .kp,.makeup .kr,.makeup .kt{color:#204a87}.makeup .l{color:#4d4d4c}.makeup .ld{color:#c00}.makeup .m,.makeup .mb,.makeup .mf,.makeup .mh,.makeup .mi,.makeup .mo{color:#2937ab}.makeup .n{color:#4d4d4c}.makeup .na{color:#8a7000}.makeup .nb{color:#204a87}.makeup .nc{color:#0000cf}.makeup .nd{color:#5c35cc;font-weight:700}.makeup .ne{color:#c00;font-weight:700}.makeup .nf{color:#b65800}.makeup .ni{color:#bc5400}.makeup .nl{color:#b65800}.makeup .nn{color:#4d4d4c}.makeup .no{color:#a06600}.makeup .nt{color:#204a87;font-weight:700}.makeup .nv,.makeup .nx{color:#4d4d4c}.makeup .o{color:#bc5400}.makeup .ow{color:#204a87}.makeup .p,.makeup .py{color:#4d4d4c}.makeup .s,.makeup .s1,.makeup .s2,.makeup .sa,.makeup .sb,.makeup .sc{color:#408200}.makeup .sd{color:#8f5902;font-style:italic}.makeup .se{color:#204a87}.makeup .sh{color:#408200}.makeup .si{color:#204a87}.makeup .sr{color:#c00}.makeup .ss{color:#a06600}.makeup .sx{color:#408200}.makeup .vc,.makeup .vg,.makeup .vi,.makeup .vm,.makeup .x{color:#4d4d4c}.dark .makeup{color:#dce1e6}.dark .makeup .hll{background-color:#49483e}.dark .makeup .bp{color:#dce1e6}.dark .makeup .c,.dark .makeup .c1,.dark .makeup .ch,.dark .makeup .cm,.dark .makeup .cp,.dark .makeup .cpf,.dark .makeup .cs{color:#969386}.dark .makeup .dl{color:#e6db74}.dark .makeup .err{color:#960050;background-color:#1e0010}.dark .makeup .fm{color:#a6e22e}.dark .makeup .gd{color:#ff5385}.dark .makeup .ge{font-style:italic}.dark .makeup .gi{color:#a6e22e}.dark .makeup .gp{color:#969386}.dark .makeup .gs{font-weight:700}.dark .makeup .gu{color:#969386}.dark .makeup .gt{color:#ff5385;font-weight:700}.dark .makeup .il{color:#ae81ff}.dark .makeup .k,.dark .makeup .kc,.dark .makeup .kd{color:#66d9ef}.dark .makeup .kn{color:#ff5385}.dark .makeup .kp,.dark .makeup .kr,.dark .makeup .kt{color:#66d9ef}.dark .makeup .l,.dark .makeup .ld,.dark .makeup .m,.dark .makeup .mb,.dark .makeup .mf,.dark .makeup .mh,.dark .makeup .mi,.dark .makeup .mo{color:#ae81ff}.dark .makeup .n{color:#dce1e6}.dark .makeup .na{color:#a6e22e}.dark .makeup .nb{color:#dce1e6}.dark .makeup .nc,.dark .makeup .nd,.dark .makeup .ne,.dark .makeup .nf{color:#a6e22e}.dark .makeup .ni,.dark .makeup .nl,.dark .makeup .nn{color:#dce1e6}.dark .makeup .no{color:#66d9ef}.dark .makeup .nt{color:#ff5385}.dark .makeup .nv{color:#dce1e6}.dark .makeup .nx{color:#a6e22e}.dark .makeup .o,.dark .makeup .ow{color:#ff5385}.dark .makeup .p,.dark .makeup .py{color:#dce1e6}.dark .makeup .s,.dark .makeup .s1,.dark .makeup .s2,.dark .makeup .sa,.dark .makeup .sb,.dark .makeup .sc,.dark .makeup .sd{color:#e6db74}.dark .makeup .se{color:#ae81ff}.dark .makeup .sh,.dark .makeup .si,.dark .makeup .sr,.dark .makeup .ss,.dark .makeup .sx{color:#e6db74}.dark .makeup .vc,.dark .makeup .vg,.dark .makeup .vi,.dark .makeup .vm{color:#dce1e6}.tabset{--borderWidth: 1px;--tabsetPadding: var(--baseLineHeight);margin:var(--baseLineHeight) 0}.tabset-tablist{display:flex;overflow-x:auto}.tabset-tab{padding:.6rem var(--tabsetPadding);min-height:46px;font-family:var(--sansFontFamily);background-color:var(--tabBackground);color:var(--tab);border:var(--borderWidth) solid var(--tabBorder);margin-right:calc(-1 * var(--borderWidth));border-top-width:4px;border-top-color:var(--tabBorderTop);border-radius:0;border-top-left-radius:var(--borderRadius);border-top-right-radius:var(--borderRadius);box-shadow:0 -3px 4px var(--tabShadow) inset;cursor:pointer}.tabset-tab[aria-selected=true]{border-bottom-color:var(--tabBackground);border-top-color:var(--mainLight);box-shadow:none}.tabset-tab[aria-selected=true]:focus-visible{background-color:var(--mainLight);border-color:var(--mainLight);color:var(--white)}.tabset-panel{padding:0 var(--tabsetPadding);border:var(--borderWidth) solid var(--tabBorder);margin-top:calc(-1 * var(--borderWidth));border-bottom-left-radius:var(--borderRadius);border-bottom-right-radius:var(--borderRadius)}@media screen and (max-width: 768px){.tabset{--tabsetPadding: calc(var(--baseLineHeight) / 2)}.tabset-panel{padding-top:calc(var(--tabsetPadding) / 2);padding-bottom:calc(var(--tabsetPadding) / 2)}.tabset-panel pre,.tabset-panel blockquote{margin-left:calc(-1 * var(--tabsetPadding))!important;margin-right:calc(-1 * var(--tabsetPadding))!important}.tabset-panel>pre code{border-left-width:0;border-right-width:0}}body.preview{--sidebarWidth: 0px;overflow:hidden}body.preview .content{height:auto}body.preview .content-inner{padding:0}body.preview .sidebar,body.preview #sidebar-menu,body.preview .hover-link,body.preview .detail-link{display:none}body.preview :is(h1,h2,h3):first-of-type{margin-top:0}body:not(.dark) .content-inner img[src*="#gh-dark-mode-only"],body.dark .content-inner img[src*="#gh-light-mode-only"]{display:none} -/*! Bundled license information: - -normalize.css/normalize.css: - (*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css *) -*/ diff --git a/dist/html-erlang-YKQ677RH.css b/dist/html-erlang-YKQ677RH.css new file mode 100644 index 0000000..466d467 --- /dev/null +++ b/dist/html-erlang-YKQ677RH.css @@ -0,0 +1,6 @@ +:root{--main: hsl(0, 100%, 44%);--mainDark: hsl(0, 100%, 34%);--mainDarkest: hsl(0, 100%, 24%);--mainLight: hsl(0, 100%, 64%);--mainLightest: hsl(0, 100%, 74%);--searchBarFocusColor: hsl(0, 100%, 50%);--searchBarBorderColor: rgb(255, 71, 71, .1);--linksNoUnderline: #0969da;--linksNoUnderlineVisited: #085fc4}body.dark{--linksNoUnderline: #71b7ff;--linksNoUnderlineVisited: #65a4e5}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:300;src:url(./lato-latin-ext-300-normal-VPGGJKJL.woff2) format("woff2"),url(./lato-all-300-normal-GIV56FBX.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:300;src:url(./lato-latin-300-normal-YUMVEFOL.woff2) format("woff2"),url(./lato-all-300-normal-GIV56FBX.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:400;src:url(./lato-latin-ext-400-normal-N27NCBWW.woff2) format("woff2"),url(./lato-all-400-normal-MNITWADU.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:400;src:url(./lato-latin-400-normal-W7754I4D.woff2) format("woff2"),url(./lato-all-400-normal-MNITWADU.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:700;src:url(./lato-latin-ext-700-normal-Q2L5DVMW.woff2) format("woff2"),url(./lato-all-700-normal-XMT5XFBS.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Lato;font-style:normal;font-display:swap;font-weight:700;src:url(./lato-latin-700-normal-2XVSBPG4.woff2) format("woff2"),url(./lato-all-700-normal-XMT5XFBS.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:400;src:url(./inconsolata-vietnamese-400-normal-IGQPHHJH.woff2) format("woff2"),url(./inconsolata-all-400-normal-HMVRHNDU.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:400;src:url(./inconsolata-latin-ext-400-normal-K7HVGTP7.woff2) format("woff2"),url(./inconsolata-all-400-normal-HMVRHNDU.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:400;src:url(./inconsolata-latin-400-normal-RGKDDNDD.woff2) format("woff2"),url(./inconsolata-all-400-normal-HMVRHNDU.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:700;src:url(./inconsolata-vietnamese-700-normal-LHEGSN35.woff2) format("woff2"),url(./inconsolata-all-700-normal-WFUKXZPS.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:700;src:url(./inconsolata-latin-ext-700-normal-4MPBLFZC.woff2) format("woff2"),url(./inconsolata-all-700-normal-WFUKXZPS.woff) format("woff");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inconsolata;font-style:normal;font-display:swap;font-weight:700;src:url(./inconsolata-latin-700-normal-DTS2D7TO.woff2) format("woff2"),url(./inconsolata-all-700-normal-WFUKXZPS.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--content-width: 949px;--content-gutter: 60px;--borderRadius: 4px;--navTabBorderWidth: 4px;--defaultFontFamily: -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";--sansFontFamily: "Lato", sans-serif;--monoFontFamily: "Inconsolata", Menlo, Courier, monospace;--baseFontSize: 18px;--baseLineHeight: 1.5em;--gray25: hsl(207, 43%, 98%);--gray50: hsl(207, 43%, 96%);--gray100: hsl(212, 33%, 91%);--gray200: hsl(210, 29%, 88%);--gray300: hsl(210, 26%, 84%);--gray400: hsl(210, 21%, 64%);--gray450: hsl(210, 21%, 49%);--gray500: hsl(210, 21%, 34%);--gray600: hsl(210, 27%, 26%);--gray700: hsl(212, 35%, 17%);--gray750: hsl(214, 46%, 14%);--gray800: hsl(216, 52%, 11%);--gray800-opacity-0: hsla(216, 52%, 11%, 0%);--gray850: hsl(216, 63%, 8%);--gray900: hsl(218, 73%, 4%);--gray900-opacity-50: hsla(218, 73%, 4%, 50%);--gray900-opacity-0: hsla(218, 73%, 4%, 0%);--coldGrayFaint: hsl(240, 5%, 97%);--coldGrayLight: hsl(240, 5%, 88%);--coldGray-lightened-10: hsl(240, 5%, 56%);--coldGray: hsl(240, 5%, 46%);--coldGray-opacity-10: hsla(240, 5%, 46%, 10%);--coldGrayDark: hsl(240, 5%, 28%);--coldGrayDim: hsl(240, 5%, 18%);--yellowLight: hsl(60, 100%, 81%);--yellowDark: hsl(60, 100%, 43%, 62%);--yellow: hsl(60, 100%, 43%);--green-lightened-10: hsl(90, 100%, 45%);--green: hsl(90, 100%, 35%);--white: hsl(0, 0%, 100%);--white-opacity-50: hsla(0, 0%, 100%, 50%);--white-opacity-10: hsla(0, 0%, 100%, 10%);--white-opacity-0: hsla(0, 0%, 100%, 0%);--black: hsl(0, 0%, 0%);--black-opacity-10: hsla(0, 0%, 0%, 10%);--black-opacity-50: hsla(0, 0%, 0%, 50%)}@media screen and (max-width: 768px){:root{--content-width: 100%;--content-gutter: 20px}}:root{--background: var(--white);--contrast: var(--black);--textBody: var(--gray800);--textHeaders: var(--gray900);--textDetailAccent: var(--mainLight);--textDetailBackground: var(--coldGrayFaint);--textFooter: var(--gray700);--links: var(--black);--linksVisited: var(--black);--linksDecoration: var(--gray450);--iconAction: var(--coldGray);--iconActionHover: var(--gray800);--blockquoteBackground: var(--coldGrayFaint);--blockquoteBorder: var(--coldGrayLight);--tableHeadBorder: var(--gray100);--tableBodyBorder: var(--gray50);--warningBackground: hsl( 33, 100%, 97%);--warningHeadingBackground: hsl( 33, 87%, 64%);--warningHeading: var(--black);--errorBackground: hsl( 7, 81%, 96%);--errorHeadingBackground: hsl( 6, 80%, 60%);--errorHeading: var(--white);--infoBackground: hsl(206, 91%, 96%);--infoHeadingBackground: hsl(213, 92%, 62%);--infoHeading: var(--white);--neutralBackground: hsl(212, 29%, 92%);--neutralHeadingBackground: hsl(220, 43%, 11%);--neutralHeading: var(--white);--tipBackground: hsl(142, 31%, 93%);--tipHeadingBackground: hsl(134, 39%, 36%);--tipHeading: var(--white);--fnSpecAttr: var(--coldGray);--fnDeprecated: var(--yellowLight);--blink: var(--yellowLight);--codeBackground: var(--gray25);--codeBorder: var(--gray100);--codeScrollThumb: var(--gray400);--codeScrollBackground: var(--codeBorder);--admCodeBackground: var(--gray25);--admCodeBorder: var(--gray100);--admCodeColor: var(--black);--admInlineCodeColor: var(--black);--admInlineCodeBackground: var(--gray25);--admInlineCodeBorder: var(--gray100);--tabBackground: var(--white);--tabBorder: var(--gray300);--tabBorderTop: var(--gray100);--tab: var(--gray600);--tabShadow: var(--gray25);--bottomActionsBtnBorder: var(--black-opacity-10);--bottomActionsBtnSubheader: var(--mainDark);--modalBackground: var(--white);--settingsInput: var(--gray500);--settingsInputBackground: var(--white);--settingsInputBorder: var(--gray300);--settingsSectionBorder: var(--gray300);--quickSwitchInput: var(--gray500);--quickSwitchContour: var(--coldGray);--success: var(--green);--sidebarAccentMain: var(--black);--sidebarBackground: var(--gray50);--sidebarHeader: var(--gray100);--sidebarMuted: var(--gray800);--sidebarHover: var(--black);--sidebarScrollbarThumb: var(--coldGrayLight);--sidebarScrollbarTrack: var(--sidebarBackground);--sidebarSubheadings: var(--black);--sidebarItem: var(--black);--sidebarInactiveItemBorder: var(--gray500);--sidebarInactiveItemMarker: var(--gray200);--sidebarLanguageAccentBar: var(--mainDark);--sidebarActiveItem: var(--mainDarkest);--searchBarBorder: var(--gray200);--searchAccentMain: var(--gray600);--searchLanguageAccentBar: var(--main);--searchSearch: var(--white);--autocompleteBorder: rgba(3, 9, 19, .1);--autocompletePreview: var(--gray25);--autocompleteHover: var(--grey50, #F0F5F9);--autocompleteBackground: var(--white);--suggestionBorder: var(--gray200);--autocompleteResults: var(--gray600);--autocompleteResultsBold: var(--gray800);--autocompleteSrollbarThumb: var(--gray200);--autocompleteSrollbarTrack: var(--gray50);--autocompleteLabelBack: var(--gray100);--autocompleteLabelFont: var(--gray600)}body.dark{--background: var(--gray900);--contrast: var(--white);--textBody: var(--gray200);--textHeaders: var(--gray100);--textDetailAccent: var(--mainLight);--textDetailBackground: var(--gray700);--textFooter: var(--gray300);--links: var(--gray100);--linksVisited: var(--gray100);--linksDecoration: var(--gray450);--iconAction: var(--coldGray-lightened-10);--iconActionHover: var(--white);--blockquoteBackground: var(--coldGray-opacity-10);--blockquoteBorder: var(--coldGrayDim);--tableHeadBorder: var(--gray600);--tableBodyBorder: var(--gray700);--warningBackground: hsla( 33, 30%, 60%, 10%);--warningHeadingBackground: hsla( 33, 66%, 35%, 80%);--warningHeading: var(--white);--errorBackground: hsla( 7, 30%, 60%, 10%);--errorHeadingBackground: hsla( 6, 70%, 40%, 80%);--errorHeading: var(--white);--infoBackground: hsla(206, 30%, 60%, 10%);--infoHeadingBackground: hsla(213, 55%, 35%, 80%);--infoHeading: var(--white);--neutralBackground: hsl(210, 30%, 60%, 10%);--neutralHeadingBackground: var(--gray600);--neutralHeading: var(--white);--tipBackground: hsla(142, 30%, 60%, 10%);--tipHeadingBackground: hsla(134, 45%, 30%, 80%);--tipHeading: var(--white);--fnSpecAttr: var(--gray400);--fnDeprecated: var(--yellowDark);--blink: var(--gray600);--codeBackground: var(--gray750);--codeBorder: var(--gray600);--codeScrollThumb: var(--gray500);--codeScrollBackground: var(--codeBorder);--admCodeBackground: var(--gray750);--admCodeBorder: var(--gray600);--admCodeColor: var(--gray100);--admInlineCodeColor: var(--gray100);--admInlineCodeBackground: var(--gray750);--admInlineCodeBorder: var(--gray600);--tabBackground: var(--gray900);--tabBorder: var(--gray700);--tabBorderTop: var(--gray700);--tab: var(--white);--tabShadow: var(--black);--bottomActionsBtnBorder: var(--white-opacity-10);--bottomActionsBtnSubheader: var(--mainLight);--modalBackground: var(--gray800);--settingsInput: var(--white);--settingsInputBackground: var(--gray700);--settingsInputBorder: var(--gray700);--settingsSectionBorder: var(--gray700);--quickSwitchInput: var(--gray300);--quickSwitchContour: var(--gray500);--success: var(--green-lightened-10);--sidebarAccentMain: var(--gray50);--sidebarBackground: var(--gray800);--sidebarHeader: var(--gray700);--sidebarMuted: var(--gray300);--sidebarHover: var(--white);--sidebarScrollbarThumb: var(--coldGray);--sidebarScrollbarTrack: var(--sidebarBackground);--sidebarSubheadings: var(--gray400);--sidebarItem: var(--gray200);--sidebarInactiveItemBorder: var(--gray400);--sidebarInactiveItemMarker: var(--gray600);--sidebarLanguageAccentBar: var(--mainLight);--sidebarActiveItem: var(--mainLightest);--searchBarBorder: var(--gray500);--searchAccentMain: var(--gray300);--searchSearch: var(--gray900);--autocompleteBorder: rgba(28,42,60,.75);--autocompletePreview: var(--gray750);--autocompleteHover: var(--gray700);--autocompleteBackground: var(--gray800);--suggestionBorder: var(--gray600);--autocompleteResults: var(--gray200);--autocompleteResultsBold: var(--gray100);--autocompleteSrollbarThumb: var(--gray600);--autocompleteSrollbarTrack: var(--gray850);--autocompleteLabelBack: var(--gray600);--autocompleteLabelFont: rgba(255, 255, 255, .8)}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}@font-face{font-family:remixicon;src:url(./remixicon-NKANDIL5.woff2) format("woff2");font-display:swap}[class^=ri-],[class*=" ri-"],.remix-icon{font-family:remixicon;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:root{--icon-arrow-up-s: "\ea78";--icon-arrow-down-s: "\ea4e";--icon-arrow-right-s: "\ea6e";--icon-add: "\ea13";--icon-subtract: "\f1af";--icon-error-warning: "\eca1";--icon-information: "\ee59";--icon-alert: "\ea21";--icon-double-quotes-l: "\ec51";--icon-link-m: "\eeaf";--icon-close-line: "\eb99";--icon-code-s-slash-line: "\ebad";--icon-menu-line: "\ef3e";--icon-search-2-line: "\f0cd";--icon-settings-3-line: "\f0e6";--icon-printer-line: "\f029"}.ri-lg{font-size:1.3333em;line-height:.75em;vertical-align:-.0667em}.ri-settings-3-line:before{content:var(--icon-settings-3-line)}.ri-add-line:before{content:var(--icon-add)}.ri-subtract-line:before{content:var(--icon-subtract)}.ri-arrow-up-s-line:before{content:var(--icon-arrow-up-s)}.ri-arrow-down-s-line:before{content:var(--icon-arrow-down-s)}.ri-arrow-right-s-line:before{content:var(--icon-arrow-right-s)}.ri-search-2-line:before{content:var(--icon-search-2-line)}.ri-menu-line:before{content:var(--icon-menu-line)}.ri-close-line:before{content:var(--icon-close-line)}.ri-link-m:before{content:var(--icon-link-m)}.ri-code-s-slash-line:before{content:var(--icon-code-s-slash-line)}.ri-error-warning-line:before{content:var(--icon-error-warning)}.ri-information-line:before{content:var(--icon-information)}.ri-alert-line:before{content:var(--icon-alert)}.ri-double-quotes-l:before{content:var(--icon-double-quotes-l)}.ri-printer-line:before{content:var(--icon-printer-line)}html,body{box-sizing:border-box;height:100%;width:100%}body{--sidebarWidth: 300px;--sidebarMinWidth: 300px;--sidebarTransitionDuration: .3s;background-color:var(--background);color:var(--textBody);font-size:16px;font-family:var(--sansFontFamily);line-height:1.6875em}*,*:before,*:after{box-sizing:inherit}.body-wrapper{display:flex;height:100%}.sidebar{display:flex;flex-direction:column;width:var(--sidebarWidth);min-width:var(--sidebarMinWidth);height:100%;position:fixed;top:0;left:0;z-index:100;resize:horizontal}.sidebar-button{padding:26px 12px 18px 19px;position:fixed;z-index:200;top:0;left:0;will-change:transform}.sidebar-toggle--animated.sidebar-button{transition:transform var(--sidebarTransitionDuration) ease-in-out}.content{width:calc(100% - var(--sidebarWidth));left:var(--sidebarWidth);height:100%;position:absolute}.content .content-inner{max-width:var(--content-width);min-height:100%;margin:0 auto;padding:0 var(--content-gutter) 10px}.content-inner:focus{outline:none}body:is(.sidebar-opening,.sidebar-opened) .sidebar-button{transform:translate(calc(var(--sidebarWidth) - 100%))}body.sidebar-opening-start .sidebar{left:calc(-1 * var(--sidebarWidth))}body.sidebar-opening-start .content{width:100%;left:0}body.sidebar-opening .sidebar{left:0;transition:left var(--sidebarTransitionDuration) ease-in-out}body.sidebar-opening .content{width:calc(100% - var(--sidebarWidth));left:var(--sidebarWidth);transition:all var(--sidebarTransitionDuration) ease-in-out}body.sidebar-closing .sidebar-button{transform:translate(0)}body.sidebar-closing .sidebar{left:calc(-1 * var(--sidebarWidth));transition:left var(--sidebarTransitionDuration) ease-in-out}body.sidebar-closing .content{width:100%;left:0;transition:all var(--sidebarTransitionDuration) ease-in-out}body.sidebar-closed .sidebar{left:calc(-1 * var(--sidebarWidth));display:none}body.sidebar-closed .content{width:100%;left:0}@media screen and (max-width: 768px){.content,body.sidebar-opening .content{left:0;width:100%}body.sidebar-closed .sidebar-button{position:absolute}}.sidebar{--sidebarFontSize: 16px;--sidebarLineHeight: 20px;font-family:var(--sansFontFamily);font-size:var(--sidebarFontSize);font-weight:300;line-height:var(--sidebarLineHeight);background-color:var(--sidebarBackground);color:var(--sidebarAccentMain);overflow:hidden;scrollbar-color:var(--sidebarScrollbarThumb) var(--sidebarScrollbarTrack)}.non-apple-os .sidebar{font-weight:400}.sidebar ul{list-style:none}.sidebar ul li{margin:0;padding:0 10px}.sidebar a{color:var(--sidebarAccentMain);text-decoration:none;transition:color .3s ease-in-out}.sidebar a:hover{color:var(--sidebarHover)}.sidebar .sidebar-header{background-color:var(--sidebarHeader);width:100%}.sidebar .sidebar-projectInfo{display:flex;justify-content:start;align-items:center;gap:16px;margin:12px 16px 12px 14px;max-width:235px}.sidebar .sidebar-projectImage{align-self:flex-end}.sidebar .sidebar-projectImage img{display:block;max-width:48px;max-height:48px}.sidebar .sidebar-projectName{font-weight:700;font-size:20px;line-height:24px;color:var(--sidebarAccentMain);margin:0;padding:0;max-width:230px;word-wrap:break-word}.sidebar .sidebar-projectVersion{display:block;position:relative;margin:0;padding:0;font-size:var(--sidebarFontSize);line-height:var(--sidebarLineHeight);color:var(--sidebarMuted)}.sidebar .sidebar-projectVersionsDropdown{cursor:pointer;position:relative;margin:0;padding:0 0 0 12px;border:none;-webkit-appearance:none;appearance:none;background-color:transparent;color:var(--sidebarMuted);z-index:2}.sidebar .sidebar-projectVersionsDropdown option{color:initial}.sidebar .sidebar-projectVersionsDropdownCaret{position:absolute;left:0;top:2px;z-index:1;font-size:8px;color:var(--sidebarMuted)}.sidebar .sidebar-projectVersionsDropdown::-ms-expand{display:none}.sidebar .sidebar-listNav{display:flex;margin:0;padding:4px 4px 0}.sidebar .sidebar-listNav :is(li,li button){text-transform:uppercase;letter-spacing:.02em;font-size:14px;color:var(--sidebarMuted)}.sidebar .sidebar-listNav li{display:inline-block;padding:0}.sidebar .sidebar-listNav li button{background:none;border:0;border-radius:0;-webkit-appearance:none;text-align:inherit;color:inherit;font-weight:inherit;cursor:pointer;display:inline-block;line-height:27px;padding:4px 10px 2px;transition:all .15s}.sidebar .sidebar-listNav li:is(.selected) button{background-color:var(--sidebarBackground);border-top:var(--navTabBorderWidth) solid var(--sidebarLanguageAccentBar)}.sidebar .sidebar-listNav li:not(.selected) button{border-top:var(--navTabBorderWidth) solid var(--sidebarHeader)}.sidebar .sidebar-listNav li:is(:hover):not(.selected) button{background-color:var(--sidebarInactiveItemMarker);border-top:var(--navTabBorderWidth) solid var(--sidebarInactiveItemBorder);color:var(--sidebarAccentMain);transition:all .15s}.sidebar .sidebar-tabpanel{flex:1 1 .01%;overflow-y:auto;overscroll-behavior:contain;position:relative;-webkit-overflow-scrolling:touch;margin-top:12px}.sidebar .full-list{margin:0;padding:0 0 20px;position:relative}.sidebar .full-list :is(li,a){overflow:hidden;text-overflow:ellipsis}.sidebar .full-list li{padding:0;margin-right:30px;line-height:27px;white-space:nowrap}.sidebar .full-list li.docs{margin-right:0}.sidebar .full-list li.open>ul{display:block;margin-left:10px}.sidebar .full-list li a.expand+button.icon-expand{appearance:none;background-color:transparent;border:0;padding:0;cursor:pointer;color:inherit;margin-right:10px;font-size:calc(1.2 * var(--sidebarFontSize));line-height:var(--sidebarLineHeight);position:absolute;display:flex;right:0;transform:translateY(calc(-100% - 4px))}.sidebar .full-list li a+button.icon-expand:after{font-family:remixicon;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sidebar .full-list li a.expand+button.icon-expand:after{content:var(--icon-arrow-down-s)}.sidebar .full-list li.open>a.expand+button.icon-expand:after{content:var(--icon-arrow-up-s)}.sidebar .full-list li.docs>a+button.icon-expand{margin-right:12px;font-size:var(--sidebarFontSize);line-height:var(--sidebarFontSize);transform:translateY(calc(-100% - 5px))}.sidebar .full-list li.docs>a+button.icon-expand:after{content:var(--icon-add)}.sidebar .full-list li.docs.open>a+button.icon-expand:after{content:var(--icon-subtract)}.sidebar .full-list li.nesting-context{font-weight:700;font-size:.9em;line-height:1.8em;color:var(--sidebarSubheadings);margin-top:10px;padding-left:15px}.sidebar .full-list li.group{text-transform:uppercase;font-weight:700;font-size:.8em;margin:1.5em 0 0;line-height:1.8em;color:var(--sidebarSubheadings);padding-left:15px}.sidebar .full-list li a{padding:3px 0 3px 15px;color:var(--sidebarItem)}.sidebar .full-list>li>a{display:block;width:100%;height:27px;line-height:var(--sidebarLineHeight)}.sidebar .full-list li .current-section>a{color:var(--sidebarActiveItem)}.sidebar .full-list li .current-section>a+button.icon-expand{color:var(--sidebarActiveItem)}.sidebar .full-list>li>a:hover{border-left:3px solid var(--sidebarLanguageAccentBar);padding-left:12px}.sidebar .full-list>li.current-page>a{color:var(--sidebarActiveItem);border-left:3px solid var(--sidebarLanguageAccentBar);padding-left:12px}.sidebar .full-list>li.current-page>a:after,.sidebar .full-list>li.current-page{color:var(--sidebarActiveItem)}.sidebar .full-list>li:last-child{margin-bottom:30px}.sidebar .full-list>li.group:first-child{margin-top:0}.sidebar .full-list ul{display:none;margin:10px 0 10px 15px;padding:0}.sidebar .full-list ul li{font-weight:300;line-height:var(--sidebarFontSize);padding:0 8px;margin-right:0;color:var(--sidebarAccentMain)}.non-apple-os .sidebar .full-list ul li{font-weight:400}.sidebar .full-list ul li.current-hash{color:var(--sidebarActiveItem)}.sidebar .full-list ul li.current-hash>a{color:var(--sidebarActiveItem)}.sidebar .full-list ul li.current-hash>a:before,.sidebar .full-list>li>ul>li>a:hover:before{content:"\2022";position:absolute;margin-left:-15px;color:var(--sidebarActiveItem)}.sidebar .full-list ul li a{padding-left:15px;display:block;width:100%;height:24px}.sidebar .full-list ul li ul{display:none;margin:9px 0 9px 20px}.sidebar .full-list ul li ul li{margin-right:0;height:20px;color:var(--sidebarAccentMain)}.sidebar .full-list ul li ul li a{border-left:1px solid var(--sidebarInactiveItemMarker);padding:0 10px;height:20px}.sidebar .full-list ul li ul li.current-hash>a:before{content:none}.sidebar .full-list ul li ul li>a:hover{border-color:var(--sidebarLanguageAccentBar)}.sidebar .full-list ul li ul li.current-hash>a{color:var(--sidebarActiveItem);border-color:var(--sidebarLanguageAccentBar)}.sidebar .full-list ul li ul li.current-hash>a{color:var(--sidebarActiveItem);margin-left:0}.sidebar ::-webkit-scrollbar{width:14px}::-webkit-scrollbar-track{background-color:var(--sidebarBackground)}.sidebar ::-webkit-scrollbar-thumb{background-color:var(--sidebarScrollbarThumb);border-radius:10px;border:3px solid var(--sidebarBackground)}.sidebar-button{cursor:pointer;background-color:transparent;border:none;font-size:var(--sidebarFontSize)}.sidebar-button:hover{color:var(--sidebarHover)}.sidebar-button{color:var(--sidebarAccentMain)}.sidebar-closed .sidebar-button{color:var(--contrast)}@media screen and (max-height: 500px){.sidebar{overflow-y:auto}.sidebar .full-list{overflow:visible}}.top-search{background-color:var(--background);top:0;z-index:99;position:relative;width:100%;padding:10px 0}.search-settings{display:flex;column-gap:12px;align-items:center;width:100%;position:relative}.search-bar{border:1px solid var(--searchBarBorder);border-radius:8px;height:48px;position:relative;width:100%}.top-search .search-bar .search-input{background-color:var(--searchSearch);border:1px solid transparent;border-radius:8px;color:var(--searchAccentMain);position:relative;height:46px;padding:8px 35px 8px 43px;width:100%}.top-search .search-bar .search-input::placeholder{color:var(--searchAccentMain);opacity:.5}.top-search .search-bar .search-input:focus{border:1px solid var(--searchBarFocusColor);border-radius:7px;position:relative;box-shadow:0 4px 20px 0 var(--searchBarBorderColor) inset}.top-search .search-bar .search-label{position:relative}.top-search .search-bar .search-button{font-size:14px;color:var(--searchAccentMain);background-color:transparent;border:none;cursor:pointer;left:11px;opacity:.5;padding:5px 1px 5px 5px;position:absolute;top:60%;transform:translateY(-60%);z-index:99}.top-search .search-bar.selected .search-button,.top-search .search-bar .search-button:hover,.top-search .search-bar .search-button:focus{color:var(--top-searchLanguageAccentBar);opacity:1}.top-search .search-bar .search-close-button{font-size:16px;color:var(--searchAccentMain);background-color:transparent;border:none;cursor:pointer;right:11px;margin:0;opacity:.5;padding:5px 1px 5px 0;position:absolute;transform:scaleY(0);top:calc(50% - 13px);transition:.15s transform ease-out;z-index:99}.top-search .search-bar .search-close-button:hover{opacity:.7}.top-search .search-settings button.icon-settings{display:flex;align-items:center;justify-content:flex-end}.top-search .search-settings .icon-settings{font-size:20px;float:right;color:var(--iconAction);text-decoration:none;border:none;transition:color .3s ease-in-out;background-color:transparent;cursor:pointer;padding:0}.top-search .search-settings .icon-settings:hover{color:var(--iconActionHover)}.top-search .search-settings .icon-settings:visited{color:var(--iconAction)}@media screen and (max-width: 768px){.top-search{padding-left:calc(var(--content-gutter) + 36px);padding-right:var(--content-gutter);margin-left:calc(-1 * var(--content-gutter));margin-right:calc(-1 * var(--content-gutter));width:calc(2 * var(--content-gutter) + 100%)}.search-settings{width:100%;box-sizing:border-box}}body.search-focused .search-bar .search-close-button{transform:scaleY(1);transition:transform .15s ease-out .15s}@media screen and (hover: hover){body.search-focused .top-search{position:sticky!important}body.search-focused.sidebar-closed .sidebar-button{position:fixed!important}}@media screen and (hover: none){body.scroll-sticky .top-search{position:sticky!important}body.scroll-sticky.sidebar-closed .sidebar-button{position:fixed!important}}*:focus,button:focus,[type=button]:focus,[type=reset]:focus,[type=submit]:focus{outline:2px solid var(--main);outline-offset:-2px}*:focus:not(:focus-visible),button:focus:not(:focus-visible),[type=button]:focus:not(:focus-visible),[type=reset]:focus:not(:focus-visible),[type=submit]:focus:not(:focus-visible){outline:0}input[type=text],input[type=number],input[type=date],input[type=datetime],input[type=datetime-local],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=time],input[type=url],input[type=week],textarea{outline:0}.content-inner{font-family:var(--defaultFontFamily);font-size:1em;line-height:1.6875em;position:relative;background-color:var(--background);color:var(--textBody)}.content-inner :is(h1,h2,h3,h4,h5,h6){font-family:var(--sansFontFamily);font-weight:700;line-height:1.5em;word-wrap:break-word;color:var(--textHeaders)}.content-inner h1{font-size:2em;margin:.5em 0}.content-inner h1.signature{margin:0}.content-inner h1.section-heading{margin:1.5em 0 .5em}.content-inner h1 small{font-weight:300}.content-inner h1 .icon-action{font-size:1.2rem;font-weight:400}.content-inner h2{font-size:1.6em;margin:1em 0 .5em;font-weight:700}.content-inner h3{font-size:1.375em;margin:1em 0 .5em;font-weight:700}.content-inner li+li{margin-top:.25em}.content-inner :is(a,.a-main){color:var(--links);text-decoration:underline;text-decoration-color:var(--linksDecoration);text-decoration-skip-ink:auto}.content-inner :is(a:visited,.a-main:visited){color:var(--linksVisited)}.content-inner .icon-action{float:right;color:var(--iconAction);text-decoration:none;border:none;transition:color .3s ease-in-out;background-color:transparent;cursor:pointer}.content-inner button.icon-action{margin-top:12px}.content-inner .icon-action:hover{color:var(--iconActionHover)}.content-inner .icon-action:visited{color:var(--iconAction)}.content-inner .livebook-badge-container{display:flex}.content-inner a.livebook-badge{display:inline-flex}.content-inner .note{color:var(--iconAction);margin-right:5px;font-size:14px;font-weight:400}.content-inner blockquote{border-left:3px solid var(--blockquoteBorder);position:relative;margin:1.5625em 0;padding:0 1.2rem;overflow:auto;background-color:var(--blockquoteBackground);border-radius:var(--borderRadius)}.content-inner blockquote p:last-child{padding-bottom:1em;margin-bottom:0}.content-inner table{margin:2em 0;border-collapse:collapse}.content-inner th{text-align:left;font-family:var(--sansFontFamily);text-transform:uppercase;font-weight:700;padding-bottom:.5em}.content-inner thead tr{border-bottom:1px solid var(--tableHeadBorder)}.content-inner tbody tr{border-bottom:1px solid var(--tableBodyBorder)}.content-inner tbody tr:last-child{border-bottom:none}.content-inner tr{vertical-align:bottom;height:2.5em}.content-inner :is(td,th){padding:.25em .25em .25em 1em;line-height:2em;vertical-align:top}.content-inner .section-heading{--icon-size: 16px;--icon-spacing: 5px;display:grid;grid-template:1fr / 1fr}.content-inner .section-heading>:is(.hover-link,.text){grid-row:1;grid-column:1}.content-inner .section-heading .hover-link{text-decoration:none}.content-inner .section-heading i{font-size:var(--icon-size);margin-top:.1em;margin-left:calc(-1 * (var(--icon-size) + var(--icon-spacing)));padding-right:var(--icon-spacing);opacity:0}@media screen and (max-width: 768px){.content-inner .section-heading i{margin-left:calc(-1 * (var(--icon-size)))}}.content-inner blockquote .section-heading i{display:none}.content-inner .section-heading .hover-link:is(:hover,:focus) i{opacity:1}.content-inner .section-heading .text{pointer-events:none}.content-inner .section-heading .text a{pointer-events:all}.content-inner .app-vsn{display:none!important;font-size:.6em;line-height:1.5em}@media screen and (max-width: 768px){.content-inner .app-vsn{display:block!important}}.content-inner img{max-width:100%}.content-inner strong>code{font-weight:700}.content-inner code{font-family:var(--monoFontFamily);font-style:normal;line-height:24px;font-weight:400}@media screen and (max-width: 768px){.content-inner :is(ol,ul){padding-left:calc(1.5 * var(--content-gutter))}}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip){border-radius:10px;border-left:0}.content-inner blockquote.warning{background-color:var(--warningBackground)}.content-inner blockquote.error{background-color:var(--errorBackground)}.content-inner blockquote.info{background-color:var(--infoBackground)}.content-inner blockquote.neutral{background-color:var(--neutralBackground)}.content-inner blockquote.tip{background-color:var(--tipBackground)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip){color:var(--contrast);margin:0 -1.2rem;padding:.7rem 1.2rem .7rem 3.3rem;font-weight:700;font-style:normal}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip):before{color:var(--contrast);position:absolute;left:1rem;font-size:1.8rem;font-family:remixicon;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.content-inner blockquote :is(h3,h4).warning{background-color:var(--warningHeadingBackground);color:var(--warningHeading)}.content-inner blockquote :is(h3,h4).warning:before{content:var(--icon-error-warning);color:var(--warningHeading)}.content-inner blockquote :is(h3,h4).error{background-color:var(--errorHeadingBackground);color:var(--errorHeading)}.content-inner blockquote :is(h3,h4).error:before{content:var(--icon-error-warning);color:var(--errorHeading)}.content-inner blockquote :is(h3,h4).info{background-color:var(--infoHeadingBackground);color:var(--infoHeading)}.content-inner blockquote :is(h3,h4).info:before{content:var(--icon-information);color:var(--infoHeading)}.content-inner blockquote :is(h3,h4).neutral{background-color:var(--neutralHeadingBackground);color:var(--neutralHeading)}.content-inner blockquote :is(h3,h4).neutral:before{content:var(--icon-double-quotes-l);color:var(--neutralHeading)}.content-inner blockquote :is(h3,h4).tip{background-color:var(--tipHeadingBackground);color:var(--tipHeading)}.content-inner blockquote :is(h3,h4).tip:before{content:var(--icon-information);color:var(--tipHeading)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip) code{margin:0 .5ch}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip) code{background-color:var(--admInlineCodeBackground);border:1px solid var(--admInlineCodeBorder);color:var(--admInlineCodeColor)}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip) pre code{background-color:var(--admCodeBackground);border:1px solid var(--admCodeBorder);color:var(--admCodeColor)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip) :is(a,a:visited){color:inherit;text-decoration-color:currentColor}@media screen and (max-width: 768px){.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip){margin-left:calc(-1 * var(--content-gutter));margin-right:calc(-1 * var(--content-gutter));padding-left:var(--content-gutter);padding-right:var(--content-gutter);border-radius:0}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip){margin:0 calc(-1 * var(--content-gutter))}}.content-inner .summary h2{font-weight:700}.content-inner .summary h2 a{text-decoration:none;border:none}.content-inner .summary span.deprecated{color:var(--darkDeprecated);font-weight:400;font-style:italic}.content-inner .summary .summary-row .summary-signature{font-family:var(--monoFontFamily);font-weight:700}.content-inner .summary .summary-row .summary-signature a{text-decoration:none;border:none}.content-inner .summary .summary-row .summary-synopsis{font-family:var(--defaultFontFamily);font-style:italic;padding:0 1.2em;margin:0 0 .5em}.content-inner .summary .summary-row .summary-synopsis p{margin:0;padding:0}.content-inner :is(a.no-underline,pre a){color:var(--linksNoUnderline);text-shadow:none;text-decoration:none;background-image:none}.content-inner :is(a.no-underline,pre a):is(:visited,:active,:focus,:hover){color:var(--linksNoUnderlineVisited)}.content-inner code{background-color:var(--codeBackground);vertical-align:baseline;border-radius:2px;padding:.1em .2em;border:1px solid var(--codeBorder);text-transform:none}.content-inner pre{margin:var(--baseLineHeight) 0}.content-inner pre code{display:block;overflow-x:auto;white-space:inherit;padding:.5em 1em}.content-inner pre code::-webkit-scrollbar{width:.4rem;height:.4rem}.content-inner pre code::-webkit-scrollbar-thumb{border-radius:.25rem;background-color:var(--codeScrollThumb)}.content-inner pre code::-webkit-scrollbar-track{background-color:var(--codeScrollBackground)}.content-inner pre code::-webkit-scrollbar-corner{background-color:var(--codeScrollBackground)}.content-inner pre code.output{margin:0 12px;max-height:400px;overflow:auto}.content-inner pre code.output+.copy-button{margin-right:12px}.content-inner pre code.output:before{content:"Output";display:block;position:absolute;top:-16px;left:12px;padding:2px 4px;font-size:12px;font-family:var(--monoFontFamily);line-height:1;color:var(--textHeaders);background-color:var(--codeBackground);border:1px solid var(--codeBorder);border-bottom:0;border-radius:2px}@media screen and (max-width: 768px){.content-inner>pre,.content-inner section>pre{margin-left:calc(-1 * var(--content-gutter));margin-right:calc(-1 * var(--content-gutter))}.content-inner>pre code,.content-inner section>pre code{padding-left:var(--content-gutter);padding-right:var(--content-gutter);border-radius:0;border-left-width:0;border-right-width:0}}@keyframes blink-background{0%{background-color:var(--textDetailBackground)}to{background-color:var(--blink)}}.content-inner .detail:target .detail-header{animation-duration:.55s;animation-name:blink-background;animation-iteration-count:1;animation-timing-function:ease-in-out}.content-inner .detail-header{margin:2 0 1em;padding:.5em 1em;background-color:var(--textDetailBackground);border-left:3px solid var(--textDetailAccent);font-size:1em;font-family:var(--monoFontFamily);position:relative}.content-inner .detail-header .note{float:right}.content-inner .detail-header .signature{display:inline-block;font-family:var(--monoFontFamily);font-size:1rem;font-weight:700}.content-inner .detail-header:hover a.detail-link,.content-inner .detail-header a.detail-link:focus{opacity:1;text-decoration:none}.content-inner .detail-header a.detail-link{transition:opacity .3s ease-in-out;position:absolute;top:0;left:0;display:block;opacity:0;padding:.6em;line-height:1.5em;margin-left:-2.5em;text-decoration:none;border:none}@media screen and (max-width: 768px){.content-inner .detail-header a.detail-link{margin-left:-30px}}.content-inner .specs pre{font-family:var(--monoFontFamily);font-size:.9em;font-style:normal;line-height:24px;white-space:pre-wrap;margin:0;padding:0}.content-inner .specs .attribute{color:var(--fnSpecAttr)}.content-inner .docstring{margin:1.2em 0 3em 1.2em}@media screen and (max-width: 768px){.content-inner .docstring{margin-left:0}}.content-inner .docstring:is(h2,h3,h4,h5){font-weight:700}.content-inner .docstring h2{font-size:1.1em}.content-inner .docstring h3{font-size:1em}.content-inner .docstring h4{font-size:.95em}.content-inner .docstring h5{font-size:.9em}.content-inner div.deprecated{display:block;padding:9px 15px;background-color:var(--fnDeprecated)}.content-inner .footer{margin:4em auto 1em;text-align:center;font-style:italic;font-size:14px}.content-inner .footer,.content-inner .footer :is(a,.footer-button){color:var(--textFooter)}.content-inner .footer .line{display:inline-block}.content-inner .footer .footer-button{background-color:transparent;border:0;cursor:pointer;font-style:italic;padding:0 4px}.content-inner .footer .footer-hex-package{margin-right:4px}.content-inner .bottom-actions{display:flex;justify-content:space-between;margin-top:4em}.content-inner .bottom-actions .bottom-actions-button{display:flex;text-decoration:none;flex-direction:column;border-radius:var(--borderRadius);border:1px solid var(--bottomActionsBtnBorder);padding:8px 16px;min-width:150px}.content-inner .bottom-actions .bottom-actions-button .subheader{font-size:.8em;color:var(--bottomActionsBtnSubheader);white-space:nowrap}.content-inner .bottom-actions .bottom-actions-button[rel=prev] .subheader{text-align:right}@media screen and (max-width: 768px){.content-inner .bottom-actions{flex-direction:column-reverse}.content-inner .bottom-actions .bottom-actions-item:not(:first-child){margin-bottom:16px}}.page-cheatmd .content-inner{--horizontal-space: 1.5em;--vertical-space: 1em}@media (max-width: 600px){.page-cheatmd .content-inner{--horizontal-space: 1em;--vertical-space: .75em}}.page-cheatmd .content-inner{max-width:1200px}.page-cheatmd .content-inner h1{margin-bottom:var(--vertical-space)}.page-cheatmd .content-inner h2{margin:var(--vertical-space) 0;column-span:all;color:var(--gray700);font-weight:500}.page-cheatmd.dark .content-inner h2{color:var(--gray200)}.page-cheatmd .content-inner h3{color:var(--main);text-decoration-color:var(--main);margin:0 0 1em;font-weight:400}.page-cheatmd .content-inner h3 :is(a,a:visited){color:var(--main);text-decoration-color:var(--main)}.page-cheatmd .content-inner section.h3{min-width:300px;margin:0;padding:0 0 calc(var(--vertical-space) * 2) 0;break-inside:avoid}.page-cheatmd .content-inner h3 .text{overflow:hidden}.page-cheatmd .content-inner h3 .text:after{content:"";margin-left:calc(var(--horizontal-space) / 2);vertical-align:baseline;display:inline-block;width:100%;height:1px;margin-right:-100%;margin-bottom:5px;background-color:var(--codeBorder)}.page-cheatmd .content-inner h4{display:block;margin:0;padding:.25em var(--horizontal-space);font-weight:400;background:var(--gray100);color:#567;border:solid 1px 1px 0 1px var(--gray100)}.page-cheatmd.dark .content-inner h4{background:#192f50;color:var(--textBody);border:1px solid #192f50;border-bottom:0}.page-cheatmd .content-inner .h2 p{margin:0;display:block;background:var(--gray50);padding:var(--vertical-space) var(--horizontal-space)}.page-cheatmd.dark .content-inner .h2 p{background:var(--gray700)}.page-cheatmd .content-inner .h2 p>code{color:#eb5757;border-radius:var(--borderRadius);padding:.2em .4em}.page-cheatmd .content-inner pre code{padding:var(--vertical-space) var(--horizontal-space)}.page-cheatmd .content-inner pre code::-webkit-scrollbar{width:.4rem;height:.6rem}.page-cheatmd .content-inner .h2 pre{margin:0}.page-cheatmd .content-inner .h2 pre+pre{margin-top:-1px}.page-cheatmd .content-inner pre.wrap{white-space:break-spaces}@media screen and (max-width: 768px){.page-cheatmd .content-inner pre code{border-left-width:1px!important;border-right-width:1px!important}}.page-cheatmd .content-inner .h2 table{display:table;box-sizing:border-box;width:100%;border-collapse:collapse;margin:0}.page-cheatmd .content-inner .h2 th{padding:var(--vertical-space) var(--horizontal-space);line-height:inherit;margin-bottom:-1px;vertical-align:middle;border-bottom:1px solid var(--codeBorder)}.page-cheatmd .content-inner .h2 td{padding:var(--vertical-space) var(--horizontal-space);border:0;border-bottom:1px solid var(--codeBorder)}.page-cheatmd .content-inner .h2 tr:first-child{border-top:1px solid var(--codeBorder)}.page-cheatmd .content-inner .h2 td code{color:#eb5757;border-radius:var(--borderRadius);padding:.2em .4em}.page-cheatmd .content-inner .h2 thead{background-color:var(--gray50)}.page-cheatmd.dark .content-inner .h2 thead{background-color:var(--gray700)}.page-cheatmd .content-inner .h2 tbody{background-color:var(--codeBackground)}.page-cheatmd .content-inner .h2 :is(ul,ol){margin:0;padding:0}.page-cheatmd .content-inner .h2 li{list-style-position:inside;padding:.5em var(--horizontal-space);line-height:2em;vertical-align:middle;background-color:var(--codeBackground);border-bottom:1px solid var(--codeBorder);margin-top:0}.page-cheatmd .content-inner .h2 :is(ul,ol)+pre code{border-top:0}.page-cheatmd .content-inner .h2 li>code{color:#eb5757;border-radius:var(--borderRadius);padding:.2em .4em}.page-cheatmd .content-inner section.width-50{display:block;width:50%;margin:0}.page-cheatmd .content-inner section.width-50>section>table{width:100%}.page-cheatmd .content-inner section:is(.col-2,.col-2-left,.col-3){column-gap:40px}.page-cheatmd .content-inner section.col-2{column-count:2;height:auto}.page-cheatmd .content-inner section.col-2-left{display:grid;grid-template-columns:calc(100% / 3) auto}.page-cheatmd .content-inner section.col-2-left>h2{grid-column-end:span 2}.page-cheatmd .content-inner section.col-3{column-count:3;height:auto}.page-cheatmd .content-inner section.list-4>ul{display:flex;flex-wrap:wrap}.page-cheatmd .content-inner section.list-4>ul>li{flex:0 0 25%}.page-cheatmd .content-inner section.list-6>ul{display:flex;flex-wrap:wrap}.page-cheatmd .content-inner section.list-6>ul>li{flex:0 0 calc(100% / 6)}@media screen and (max-width: 1400px){.page-cheatmd .content-inner section.col-3{column-count:2}.page-cheatmd .content-inner section.col-2-left{display:flex;flex-direction:column}}@media screen and (max-width: 1200px){.page-cheatmd .content-inner section:is(.col-2,.col-3){display:flex;flex-direction:column}.page-cheatmd .content-inner section.list-6>ul>li{flex:0 0 25%}}@media screen and (max-width: 1000px){.page-cheatmd .content-inner section:is(.list-4,.list-6)>ul>li{flex:0 0 calc(100% / 3)}}@media screen and (max-width: 600px){.page-cheatmd .content-inner section:is(.list-4,.list-6)>ul>li{flex:0 0 50%}.page-cheatmd .content-inner section.width-50{width:100%}}#search{min-height:200px;position:relative}#search .loading{height:64px;width:64px;position:absolute;top:50%;left:calc(50% - 32px)}#search .loading div{box-sizing:border-box;display:block;position:absolute;width:51px;height:51px;margin:6px;border:6px solid var(--coldGray);border-radius:50%;animation:loading 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:var(--coldGray) transparent transparent transparent}#search .loading div:nth-child(1){animation-delay:-.45s}#search .loading div:nth-child(2){animation-delay:-.3s}#search .loading div:nth-child(3){animation-delay:-.15s}@keyframes loading{0%{transform:rotate(0)}to{transform:rotate(360deg)}}#search .result{margin:2em 0 2.5em}#search .result p{margin:0}#search .result-id{font-size:1.4em;margin:0}#search .result-id a{text-decoration:none;transition:color .1s ease-in-out;color:var(--links)}#search .result-id a:is(:visited,:active,:focus){color:var(--linksVisited)}#search .result-id a:hover{color:var(--main)}#search :is(.result-id,.result-elem) em{font-style:normal;color:var(--main)}#search .result-id small{font-weight:400}@keyframes keyboard-shortcuts-show{0%{opacity:0}to{opacity:1}}.modal{animation-duration:.15s;animation-name:keyboard-shortcuts-show;animation-iteration-count:1;animation-timing-function:ease-in-out;display:none;background-color:#000000bf;position:fixed;inset:0;z-index:300}.modal.shown{display:block}.modal .modal-contents{margin:75px auto 0;max-width:500px;background-color:var(--modalBackground);border-radius:var(--borderRadius);box-shadow:2px 2px 8px #0003;padding:25px 35px 35px}@media screen and (max-width: 768px){.modal .modal-contents{padding:20px}}.modal .modal-header{display:flex;align-items:start}.modal .modal-title{display:inline-block;flex-grow:1;font-size:1.2rem;font-weight:700;margin-bottom:20px}.modal .modal-title button{border:none;background-color:transparent;color:var(--textHeaders);font-weight:700;margin-right:30px;padding-left:0;text-align:left;transition:color .15s}.modal .modal-title button:hover{color:var(--main);cursor:pointer}.modal .modal-title button.active{color:var(--main)}.modal .modal-close{cursor:pointer;display:block;font-size:1.5rem;margin:-8px -8px 0 0;padding:8px;opacity:.7;background-color:transparent;color:var(--textHeaders);border:none;transition:opacity .15s}.modal .modal-close:hover{opacity:1}#keyboard-shortcuts-content dl.shortcut-row{display:flex;align-items:center;justify-content:space-between;margin:0;padding:6px 0 8px;border-bottom:1px solid var(--settingsSectionBorder)}#keyboard-shortcuts-content dl.shortcut-row:last-of-type{border-bottom-style:none}#keyboard-shortcuts-content dl.shortcut-row:first-child{padding-top:0}#keyboard-shortcuts-content :is(.shortcut-keys,.shortcut-description){display:inline-block}#keyboard-shortcuts-content kbd>kbd{background-color:var(--settingsInputBorder);color:var(--contrast);border-radius:var(--borderRadius);font-family:inherit;font-weight:700;display:inline-block;line-height:1;padding:4px 7px 6px;min-width:26px;text-align:center}#keyboard-shortcuts-content :is(.shortcut-keys,.shortcut-description){margin:0}#quick-switch-modal-body{width:100%;position:relative}#quick-switch-modal-body .ri-search-2-line{position:absolute;left:0;top:0;padding:4px 10px;color:var(--quickSwitchContour);font-weight:700}#quick-switch-modal-body #quick-switch-input{width:100%;padding:8px 6px 8px 38px;border:none;color:var(--quickSwitchInput);background-color:transparent;border-bottom:1px solid var(--quickSwitchContour);box-sizing:border-box;transition:all .12s ease-out}#quick-switch-modal-body #quick-switch-results{margin:0}#quick-switch-modal-body .quick-switch-result{padding:2px 5px;border-bottom:1px dotted var(--quickSwitchContour);transition:all .12s ease-out}#quick-switch-modal-body .quick-switch-result:last-child{border-bottom:none}#quick-switch-modal-body .quick-switch-result:hover{cursor:pointer}#quick-switch-modal-body .quick-switch-result:is(:hover,.selected){border-left:4px solid var(--main);background-color:var(--codeBackground)}.autocomplete{display:none;position:absolute;width:calc(100% - 32px);top:55px}.autocomplete .triangle{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-bottom:12px solid var(--autocompleteBackground);position:absolute;top:8px;left:26px;transform:translate(-50%);z-index:100;background-color:transparent}.autocomplete-preview{width:100%;margin:0;height:100%;line-height:20px;background-color:var(--background);font-family:var(--sansFontFamily);border:4px solid var(--autocompleteBorder);padding:12px 16px}.autocomplete-preview div,.autocomplete-preview span{display:none}.autocomplete-preview.loading div{float:left;display:block;border:5px solid var(--autocompleteBorder);border-radius:50%;border-top:5px solid var(--textDetailAccent);width:20px;height:20px;animation:spinner 4s linear infinite}.autocomplete-preview.loading span{color:var(--autocompleteResults);display:inline;margin-left:6px}.autocomplete-preview.loading span:after{color:var(--autocompleteResults);content:"Loading"}@keyframes spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.autocomplete-preview.loading iframe{height:0}.autocomplete-preview iframe{width:100%;height:100%;border:0}.autocomplete-results{list-style:none;margin:0;padding:15px 20px;display:flex;justify-content:space-between;color:var(--autocompleteResults);font-family:var(--sansFontFamily);font-weight:300;font-size:.9rem}.autocomplete-results .bold{color:var(--autocompleteResultsBold);font-weight:400}.autocomplete.shown{display:block}.autocomplete-container{position:absolute;top:15px;width:100%;z-index:200}.autocomplete-suggestions{background-color:var(--autocompleteBackground);border-radius:8px;box-shadow:0 15px 99px 0 var(--autocompleteBorder);overflow-y:auto;max-height:450px;white-space:normal;overflow-x:hidden;overscroll-behavior-y:contain}.autocomplete-suggestions.previewing:has(.selected){max-height:80vh}.autocomplete-suggestions.previewing:has(.selected) .autocomplete-suggestion:not(.selected){display:none}.autocomplete-suggestions.previewing:not(:has(.selected)) .autocomplete-preview{display:none}.autocomplete-suggestions:not(.previewing) .autocomplete-preview{display:none}.autocomplete-suggestion{color:inherit;display:block;padding:12px 20px;text-decoration:none;transition:background-color .3s ease-in-out;border-top:1px solid var(--suggestionBorder);font-size:.9rem}.autocomplete-suggestion:hover,.autocomplete-suggestion.selected{background-color:var(--autocompleteHover)}.autocomplete-suggestion:not(.selected) .autocomplete-preview-indicator{display:none}.autocomplete-preview-indicator{float:right}.autocomplete-preview-indicator button{color:var(--iconAction);display:flex;align-items:center;text-decoration:none;border:1px solid var(--suggestionBorder);border-radius:8px;transition:color .3s ease-in-out;background-color:var(--autocompletePreview);cursor:pointer;padding:4px 8px;font-size:14px}.autocomplete-preview-indicator button:hover{color:var(--iconActionHover);background-color:var(--autocompleteHover)}.autocomplete-preview-indicator button i{margin-right:4px}.autocomplete-suggestions.previewing .autocomplete-preview-indicator-closed{display:none}.autocomplete-suggestions:not(.previewing) .autocomplete-preview-indicator-open{display:none}.autocomplete-suggestion:hover:not(.selected) .autocomplete-preview-indicator-closed{display:block}.autocomplete-suggestion em{font-style:normal;font-weight:700}.autocomplete-suggestion .description{opacity:.6;padding-top:3px}.autocomplete-suggestion .label{background-color:var(--autocompleteLabelBack);opacity:.6;color:var(--autocompleteLabelFont);padding:4px 8px;border-radius:4px;margin-left:5px;text-transform:uppercase;font-family:var(--sansFontFamily);font-size:.7rem}.autocomplete-suggestion .header{margin-right:5px}.autocomplete-suggestion .title,.autocomplete-suggestion .description{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.autocomplete-suggestions a{text-decoration:none!important}.autocomplete-suggestions::-webkit-scrollbar{width:5px;border-radius:7px;flex-shrink:0}.autocomplete-suggestions::-webkit-scrollbar-thumb{background-color:var(--autocompleteSrollbarThumb);border-radius:7px}.autocomplete-suggestions::-webkit-scrollbar-track{background-color:var(--autocompleteSrollbarTrack)}@media screen and (max-width: 1023px){.autocomplete-results .press-return{display:none}}.tooltip{box-shadow:0 0 10px var(--black-opacity-10);max-height:300px;max-width:500px;padding:0;position:absolute;pointer-events:none;margin:0;z-index:99;top:0;left:0;visibility:hidden;transform:translateY(20px);opacity:0;transition:.2s visibility ease-out,.2s transform ease-out,.2s opacity ease-out}.tooltip.tooltip-shown{visibility:visible;transform:translateY(0);opacity:1}.tooltip .tooltip-body{border:1px solid var(--codeBorder)}.tooltip .tooltip-body .signature{min-width:320px;width:100%}.tooltip .tooltip-body .detail-header{border-left:0;margin-bottom:0;margin-top:0}.tooltip .tooltip-body .docstring{background-color:var(--background);padding:1.2em;margin:0;width:498px}.tooltip .tooltip-body .docstring-plain{max-width:498px;width:auto}.tooltip .tooltip-body .version-info{float:right;line-height:1.6rem;font-family:var(--monoFontFamily);font-size:.9rem;font-weight:400;margin-bottom:-6px;opacity:.3;padding-left:.3em}pre{position:relative}pre:hover .copy-button,pre .copy-button:focus{opacity:1}.copy-button{display:flex;opacity:0;position:absolute;top:5px;right:5px;padding:4px;background-color:var(--codeBackground);border:none;cursor:pointer;transition:all .15s;font-family:var(--defaultFontFamily);font-size:14px;line-height:24px;color:currentColor}.copy-button svg{opacity:.5;transition:all .15s}pre .copy-button:hover svg,pre .copy-button:focus-visible svg{opacity:1}.copy-button svg{width:20px}.copy-button.clicked{opacity:1;color:var(--success)}.copy-button.clicked svg{display:none;color:currentColor}#settings-modal-content{margin-top:10px}#settings-modal-content .hidden{display:none}#settings-modal-content .input{box-sizing:border-box;width:80%;padding:8px;font-size:14px;background-color:var(--settingsInputBackground);color:var(--settingsInput);border:1px solid var(--settingsInputBorder);border-radius:8px;transition:border-color .15s}#settings-modal-content .input:focus{border-color:var(--main)}#settings-modal-content .input::placeholder{color:var(--gray400)}#settings-modal-content .switch-button-container{display:flex;align-items:center;justify-content:space-between;border-top:1px solid var(--settingsSectionBorder);padding:10px 0}#settings-modal-content .switch-button-container:first-of-type{border-top-style:none;padding-top:0}#settings-modal-content .switch-button-container>div>span{font-size:18px}#settings-modal-content .switch-button-container>div>p{font-size:14px;font-weight:300;line-height:1.4;margin:0;padding-bottom:6px;padding-right:10px}#settings-modal-content .switch-button{position:relative;display:inline-block;flex-shrink:0;width:40px;height:20px;user-select:none;transition:all .15s}#settings-modal-content .switch-button__checkbox{appearance:none;position:absolute;display:block;width:20px;height:20px;border-radius:1000px;background-color:#91a4b7;border:3px solid #e5edf5;cursor:pointer;transition:all .3s}#settings-modal-content .switch-button__bg{display:block;width:100%;height:100%;border-radius:1000px;background-color:#e5edf5;cursor:pointer;transition:all .3s}#settings-modal-content .switch-button__checkbox:checked{background-color:#fff;border-color:var(--main);transform:translate(100%)}#settings-modal-content .switch-button__checkbox:checked+.switch-button__bg{background-color:var(--main)}#settings-modal-content .switch-button__checkbox:focus{outline:0}#settings-modal-content .switch-button__checkbox:focus+.switch-button__bg{outline:2px solid var(--main);outline-offset:2px}#settings-modal-content .switch-button__checkbox:focus:not(:focus-visible)+.switch-button__bg{outline:0}#settings-modal-content .settings-select{cursor:pointer;position:relative;border:none;background-color:transparent;color:var(--textBody)}#settings-modal-content .settings-select option{color:initial}#toast{opacity:0;position:fixed;z-index:1;left:50%;bottom:1rem;min-width:3rem;margin:0 -1.2rem;padding:.7rem 1.2rem;text-align:center;font-weight:700;border-radius:10px;border:1px solid var(--codeBorder);background-color:var(--codeBackground);color:var(--textBody);transition:opacity .4s ease-in-out,transform .3s ease-out;cursor:default}#toast.show{opacity:1;transform:translateY(-.75rem)}@media (prefers-reduced-motion: reduce){#toast{transition:none}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0;user-select:none}@media print{.body-wrapper{display:block}.sidebar,.sidebar-button,.top-search{display:none}.content{padding-left:0;overflow:visible;left:0;width:100%}.summary-row{break-inside:avoid}#toast{display:none}.content-inner{padding:0}.content-inner .section-heading a.hover-link,.content-inner button.icon-action,.content-inner a.icon-action,.content-inner .bottom-actions{display:none}.footer p:first-of-type{display:none}.content-inner blockquote:is(.warning,.error,.info,.neutral,.tip){border:2px solid var(--gray400)}.content-inner blockquote :is(h3,h4):is(.warning,.error,.info,.neutral,.tip){color:var(--textHeaders);border-bottom:2px solid var(--gray400)}.content-inner pre code.makeup{border-color:var(--gray400);white-space:break-spaces;break-inside:avoid}.content-inner blockquote code.inline,.content-inner code.inline{border-color:var(--gray400)}}@media print{.page-cheatmd .content-inner *{background-color:transparent!important;border-color:var(--gray400)!important}.page-cheatmd .content-inner{max-width:100%;width:100%;padding:0;font-size:.7em}.page-cheatmd .content-inner section:is(.col-2,.col-2-left,.col-3){column-gap:30px}.page-cheatmd .content-inner section.col-2{column-count:2}.page-cheatmd .content-inner section.col-2-left{display:grid}.page-cheatmd .content-inner section.col-3{column-count:3}.page-cheatmd .content-inner h1{margin-top:0;margin-bottom:.5em}.page-cheatmd .content-inner h2.section-heading{font-weight:700;margin-top:1em;column-span:all}.page-cheatmd .content-inner section.h2{break-inside:avoid}.page-cheatmd .content-inner h3{font-weight:700;color:var(--mainDark)}.page-cheatmd .content-inner h3:after{height:2px;background-color:var(--gray400)}.page-cheatmd .content-inner section.h3{min-width:300px;break-inside:avoid}.page-cheatmd .content-inner h4{padding:.5em 0;border:none;font-weight:700;color:#000}.page-cheatmd .content-inner .h2 p{padding-left:0;padding-right:0;border:none!important}.page-cheatmd .content-inner code{line-height:1.5em}.page-cheatmd .content-inner .h2 table{font-variant-numeric:tabular-nums;break-inside:avoid}.page-cheatmd .content-inner .h2 :is(th,td){vertical-align:top;padding-left:0;padding-right:0}.page-cheatmd .content-inner .h2 thead{border-style:solid none;border-width:1px}.page-cheatmd .content-inner .h2 tr{border-bottom:none}.page-cheatmd .content-inner .h2 th{font-weight:700}.page-cheatmd .content-inner .h2 li{padding-left:0;padding-right:0;vertical-align:middle;border-bottom:none}.page-cheatmd .content-inner pre:hover button.copy-button,.page-cheatmd .content-inner div.tooltip{display:none}.page-cheatmd .content-inner footer p:not(.built-using){display:none}}code.makeup .unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.makeup .hll{background-color:#ffc}.makeup .bp{color:#3465a4}.makeup .c,.makeup .c1,.makeup .ch,.makeup .cm,.makeup .cp,.makeup .cpf,.makeup .cs{color:#4d4d4d}.makeup .dl{color:#408200}.makeup .err{color:#a40000;border:#ef2929}.makeup .fm,.makeup .g{color:#4d4d4c}.makeup .gd{color:#a40000}.makeup .ge{color:#4d4d4c;font-style:italic}.makeup .gh{color:navy;font-weight:700}.makeup .gi{color:#00a000}.makeup .go{color:#4d4d4c;font-style:italic}.makeup .gp{color:#4d4d4d}.makeup .gr{color:#ef2929}.makeup .gs{color:#4d4d4c;font-weight:700}.makeup .gt{color:#a40000;font-weight:700}.makeup .gu{color:purple;font-weight:700}.makeup .il{color:#0000cf;font-weight:700}.makeup .k,.makeup .kc,.makeup .kd,.makeup .kn,.makeup .kp,.makeup .kr,.makeup .kt{color:#204a87}.makeup .l{color:#4d4d4c}.makeup .ld{color:#c00}.makeup .m,.makeup .mb,.makeup .mf,.makeup .mh,.makeup .mi,.makeup .mo{color:#2937ab}.makeup .n{color:#4d4d4c}.makeup .na{color:#8a7000}.makeup .nb{color:#204a87}.makeup .nc{color:#0000cf}.makeup .nd{color:#5c35cc;font-weight:700}.makeup .ne{color:#c00;font-weight:700}.makeup .nf{color:#b65800}.makeup .ni{color:#bc5400}.makeup .nl{color:#b65800}.makeup .nn{color:#4d4d4c}.makeup .no{color:#a06600}.makeup .nt{color:#204a87;font-weight:700}.makeup .nv,.makeup .nx{color:#4d4d4c}.makeup .o{color:#bc5400}.makeup .ow{color:#204a87}.makeup .p,.makeup .py{color:#4d4d4c}.makeup .s,.makeup .s1,.makeup .s2,.makeup .sa,.makeup .sb,.makeup .sc{color:#408200}.makeup .sd{color:#8f5902;font-style:italic}.makeup .se{color:#204a87}.makeup .sh{color:#408200}.makeup .si{color:#204a87}.makeup .sr{color:#c00}.makeup .ss{color:#a06600}.makeup .sx{color:#408200}.makeup .vc,.makeup .vg,.makeup .vi,.makeup .vm,.makeup .x{color:#4d4d4c}.dark .makeup{color:#dce1e6}.dark .makeup .hll{background-color:#49483e}.dark .makeup .bp{color:#dce1e6}.dark .makeup .c,.dark .makeup .c1,.dark .makeup .ch,.dark .makeup .cm,.dark .makeup .cp,.dark .makeup .cpf,.dark .makeup .cs{color:#969386}.dark .makeup .dl{color:#e6db74}.dark .makeup .err{color:#960050;background-color:#1e0010}.dark .makeup .fm{color:#a6e22e}.dark .makeup .gd{color:#ff5385}.dark .makeup .ge{font-style:italic}.dark .makeup .gi{color:#a6e22e}.dark .makeup .gp{color:#969386}.dark .makeup .gs{font-weight:700}.dark .makeup .gu{color:#969386}.dark .makeup .gt{color:#ff5385;font-weight:700}.dark .makeup .il{color:#ae81ff}.dark .makeup .k,.dark .makeup .kc,.dark .makeup .kd{color:#66d9ef}.dark .makeup .kn{color:#ff5385}.dark .makeup .kp,.dark .makeup .kr,.dark .makeup .kt{color:#66d9ef}.dark .makeup .l,.dark .makeup .ld,.dark .makeup .m,.dark .makeup .mb,.dark .makeup .mf,.dark .makeup .mh,.dark .makeup .mi,.dark .makeup .mo{color:#ae81ff}.dark .makeup .n{color:#dce1e6}.dark .makeup .na{color:#a6e22e}.dark .makeup .nb{color:#dce1e6}.dark .makeup .nc,.dark .makeup .nd,.dark .makeup .ne,.dark .makeup .nf{color:#a6e22e}.dark .makeup .ni,.dark .makeup .nl,.dark .makeup .nn{color:#dce1e6}.dark .makeup .no{color:#66d9ef}.dark .makeup .nt{color:#ff5385}.dark .makeup .nv{color:#dce1e6}.dark .makeup .nx{color:#a6e22e}.dark .makeup .o,.dark .makeup .ow{color:#ff5385}.dark .makeup .p,.dark .makeup .py{color:#dce1e6}.dark .makeup .s,.dark .makeup .s1,.dark .makeup .s2,.dark .makeup .sa,.dark .makeup .sb,.dark .makeup .sc,.dark .makeup .sd{color:#e6db74}.dark .makeup .se{color:#ae81ff}.dark .makeup .sh,.dark .makeup .si,.dark .makeup .sr,.dark .makeup .ss,.dark .makeup .sx{color:#e6db74}.dark .makeup .vc,.dark .makeup .vg,.dark .makeup .vi,.dark .makeup .vm{color:#dce1e6}.tabset{--borderWidth: 1px;--tabsetPadding: var(--baseLineHeight);margin:var(--baseLineHeight) 0}.tabset-tablist{display:flex;overflow-x:auto}.tabset-tab{padding:.6rem var(--tabsetPadding);min-height:46px;font-family:var(--sansFontFamily);background-color:var(--tabBackground);color:var(--tab);border:var(--borderWidth) solid var(--tabBorder);margin-right:calc(-1 * var(--borderWidth));border-top-width:4px;border-top-color:var(--tabBorderTop);border-radius:0;border-top-left-radius:var(--borderRadius);border-top-right-radius:var(--borderRadius);box-shadow:0 -3px 4px var(--tabShadow) inset;cursor:pointer}.tabset-tab[aria-selected=true]{border-bottom-color:var(--tabBackground);border-top-color:var(--mainLight);box-shadow:none}.tabset-tab[aria-selected=true]:focus-visible{background-color:var(--mainLight);border-color:var(--mainLight);color:var(--white)}.tabset-panel{padding:0 var(--tabsetPadding);border:var(--borderWidth) solid var(--tabBorder);margin-top:calc(-1 * var(--borderWidth));border-bottom-left-radius:var(--borderRadius);border-bottom-right-radius:var(--borderRadius)}@media screen and (max-width: 768px){.tabset{--tabsetPadding: calc(var(--baseLineHeight) / 2)}.tabset-panel{padding-top:calc(var(--tabsetPadding) / 2);padding-bottom:calc(var(--tabsetPadding) / 2)}.tabset-panel pre,.tabset-panel blockquote{margin-left:calc(-1 * var(--tabsetPadding))!important;margin-right:calc(-1 * var(--tabsetPadding))!important}.tabset-panel>pre code{border-left-width:0;border-right-width:0}}body.preview{--sidebarWidth: 0px;overflow:hidden}body.preview .content{height:auto}body.preview .content-inner{padding:0}body.preview .sidebar,body.preview #sidebar-menu,body.preview .hover-link,body.preview .detail-link{display:none}body.preview :is(h1,h2,h3):first-of-type{margin-top:0}body:not(.dark) .content-inner img[src*="#gh-dark-mode-only"],body.dark .content-inner img[src*="#gh-light-mode-only"]{display:none} +/*! Bundled license information: + +normalize.css/normalize.css: + (*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css *) +*/ diff --git a/dist/search_data-1514AF50.js b/dist/search_data-1514AF50.js new file mode 100644 index 0000000..40b842d --- /dev/null +++ b/dist/search_data-1514AF50.js @@ -0,0 +1 @@ +searchData={"content_type":"text/plain","items":[{"doc":"erf is a library that provides a design-first framework to build RESTful APIs in Erlang.","ref":"erf.html","title":"erf","type":"module"},{"doc":"Returns the router for an instance of the server.","ref":"erf.html#get_router/1","title":"erf.get_router/1","type":"function"},{"doc":null,"ref":"erf.html#init/1","title":"erf.init/1","type":"function"},{"doc":"Reloads the configuration for an instance of the server.","ref":"erf.html#reload_conf/2","title":"erf.reload_conf/2","type":"function"},{"doc":"Starts the supervision tree for an instance of the server.","ref":"erf.html#start_link/1","title":"erf.start_link/1","type":"function"},{"doc":"Stops the supervision tree for an instance of the server.","ref":"erf.html#stop/1","title":"erf.stop/1","type":"function"},{"doc":null,"ref":"erf.html#t:api/0","title":"erf.api/0","type":"type"},{"doc":null,"ref":"erf.html#t:body/0","title":"erf.body/0","type":"type"},{"doc":null,"ref":"erf.html#t:conf/0","title":"erf.conf/0","type":"type"},{"doc":null,"ref":"erf.html#t:header/0","title":"erf.header/0","type":"type"},{"doc":null,"ref":"erf.html#t:method/0","title":"erf.method/0","type":"type"},{"doc":null,"ref":"erf.html#t:path_parameter/0","title":"erf.path_parameter/0","type":"type"},{"doc":null,"ref":"erf.html#t:query_parameter/0","title":"erf.query_parameter/0","type":"type"},{"doc":null,"ref":"erf.html#t:request/0","title":"erf.request/0","type":"type"},{"doc":null,"ref":"erf.html#t:response/0","title":"erf.response/0","type":"type"},{"doc":null,"ref":"erf.html#t:static_dir/0","title":"erf.static_dir/0","type":"type"},{"doc":null,"ref":"erf.html#t:static_file/0","title":"erf.static_file/0","type":"type"},{"doc":null,"ref":"erf.html#t:static_route/0","title":"erf.static_route/0","type":"type"},{"doc":"erf 's configuration manager module.","ref":"erf_conf.html","title":"erf_conf","type":"module"},{"doc":"Clears the configuration for the given Name .","ref":"erf_conf.html#clear/1","title":"erf_conf.clear/1","type":"function"},{"doc":"Returns the configuration for the given Name .","ref":"erf_conf.html#get/1","title":"erf_conf.get/1","type":"function"},{"doc":"Returns the log level for the given Name .","ref":"erf_conf.html#log_level/1","title":"erf_conf.log_level/1","type":"function"},{"doc":"Returns the postprocess middlewares for the given Name .","ref":"erf_conf.html#postprocess_middlewares/1","title":"erf_conf.postprocess_middlewares/1","type":"function"},{"doc":"Returns the preprocess middlewares for the given Name .","ref":"erf_conf.html#preprocess_middlewares/1","title":"erf_conf.preprocess_middlewares/1","type":"function"},{"doc":"Returns the router for the given Name .","ref":"erf_conf.html#router/1","title":"erf_conf.router/1","type":"function"},{"doc":"Returns the router module name for the given Name .","ref":"erf_conf.html#router_mod/1","title":"erf_conf.router_mod/1","type":"function"},{"doc":"Sets the configuration for the given Name .","ref":"erf_conf.html#set/2","title":"erf_conf.set/2","type":"function"},{"doc":null,"ref":"erf_conf.html#t:t/0","title":"erf_conf.t/0","type":"type"},{"doc":"erf 's interface to interact with its underlying HTTP server.","ref":"erf_http_server.html","title":"erf_http_server","type":"behaviour"},{"doc":null,"ref":"erf_http_server.html#c:start_link/3","title":"erf_http_server.start_link/3","type":"callback"},{"doc":null,"ref":"erf_http_server.html#start_link/4","title":"erf_http_server.start_link/4","type":"function"},{"doc":null,"ref":"erf_http_server.html#t:conf/0","title":"erf_http_server.conf/0","type":"type"},{"doc":null,"ref":"erf_http_server.html#t:extra_conf/0","title":"erf_http_server.extra_conf/0","type":"type"},{"doc":null,"ref":"erf_http_server.html#t:t/0","title":"erf_http_server.t/0","type":"type"},{"doc":"An elli implementation for erf_http_server .","ref":"erf_http_server_elli.html","title":"erf_http_server_elli","type":"module"},{"doc":null,"ref":"erf_http_server_elli.html#start_link/3","title":"erf_http_server_elli.start_link/3","type":"function"},{"doc":null,"ref":"erf_http_server_elli.html#t:extra_conf/0","title":"erf_http_server_elli.extra_conf/0","type":"type"},{"doc":"Module that parses a specification file into an API AST.","ref":"erf_parser.html","title":"erf_parser","type":"behaviour"},{"doc":null,"ref":"erf_parser.html#c:parse/1","title":"erf_parser.parse/1","type":"callback"},{"doc":"Parses an specification file into an API AST given a specification format.","ref":"erf_parser.html#parse/2","title":"erf_parser.parse/2","type":"function"},{"doc":null,"ref":"erf_parser.html#t:api/0","title":"erf_parser.api/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:body/0","title":"erf_parser.body/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:endpoint/0","title":"erf_parser.endpoint/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:method/0","title":"erf_parser.method/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:operation/0","title":"erf_parser.operation/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:parameter/0","title":"erf_parser.parameter/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:parameter_name/0","title":"erf_parser.parameter_name/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:parameter_type/0","title":"erf_parser.parameter_type/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:path/0","title":"erf_parser.path/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:ref/0","title":"erf_parser.ref/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:request/0","title":"erf_parser.request/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:response/0","title":"erf_parser.response/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:schema/0","title":"erf_parser.schema/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:status_code/0","title":"erf_parser.status_code/0","type":"type"},{"doc":"An OpenAPI Specification 3.0 erf_parser .","ref":"erf_parser_oas_3_0.html","title":"erf_parser_oas_3_0","type":"module"},{"doc":"Parses an OpenAPI Specification 3.0 file into an API AST.","ref":"erf_parser_oas_3_0.html#parse/1","title":"erf_parser_oas_3_0.parse/1","type":"function"},{"doc":null,"ref":"erf_parser_oas_3_0.html#t:ctx/0","title":"erf_parser_oas_3_0.ctx/0","type":"type"},{"doc":null,"ref":"erf_parser_oas_3_0.html#t:spec/0","title":"erf_parser_oas_3_0.spec/0","type":"type"},{"doc":"Behaviour for erf 's postprocessing middlewares.","ref":"erf_postprocess_middleware.html","title":"erf_postprocess_middleware","type":"behaviour"},{"doc":null,"ref":"erf_postprocess_middleware.html#c:postprocess/2","title":"erf_postprocess_middleware.postprocess/2","type":"callback"},{"doc":"A module that implements this behaviour.","ref":"erf_postprocess_middleware.html#t:t/0","title":"erf_postprocess_middleware.t/0","type":"type"},{"doc":"Behaviour for erf 's preprocessing middlewares.","ref":"erf_preprocess_middleware.html","title":"erf_preprocess_middleware","type":"behaviour"},{"doc":null,"ref":"erf_preprocess_middleware.html#c:preprocess/1","title":"erf_preprocess_middleware.preprocess/1","type":"callback"},{"doc":"A module that implements this behaviour.","ref":"erf_preprocess_middleware.html#t:t/0","title":"erf_preprocess_middleware.t/0","type":"type"},{"doc":null,"ref":"erf_router.html","title":"erf_router","type":"module"},{"doc":"Generates an Erlang Syntax Tree of a router module from an API AST.","ref":"erf_router.html#generate/2","title":"erf_router.generate/2","type":"function"},{"doc":"Handles an HTTP request.","ref":"erf_router.html#handle/2","title":"erf_router.handle/2","type":"function"},{"doc":"Loads a router module into the Erlang Runtime System.","ref":"erf_router.html#load/1","title":"erf_router.load/1","type":"function"},{"doc":null,"ref":"erf_router.html#t:callback/0","title":"erf_router.callback/0","type":"type"},{"doc":null,"ref":"erf_router.html#t:generator_opts/0","title":"erf_router.generator_opts/0","type":"type"},{"doc":null,"ref":"erf_router.html#t:t/0","title":"erf_router.t/0","type":"type"},{"doc":"erf 's static files handler utility module.","ref":"erf_static.html","title":"erf_static","type":"module"},{"doc":"Returns the MIME type for the given file extension. https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types","ref":"erf_static.html#mime_type/1","title":"erf_static.mime_type/1","type":"function"},{"doc":null,"ref":"erf_util.html","title":"erf_util","type":"module"},{"doc":"Naive function to convert a binary or string to PascalCase.","ref":"erf_util.html#to_pascal_case/1","title":"erf_util.to_pascal_case/1","type":"function"},{"doc":"Naive function to convert a binary or string to snake_case.","ref":"erf_util.html#to_snake_case/1","title":"erf_util.to_snake_case/1","type":"function"},{"doc":"# erf - A design-first Erlang REST Framework\n[![erf ci](https://github.com/nomasystems/erf/actions/workflows/ci.yml/badge.svg)](https://github.com/nomasystems/erf/actions/workflows/ci.yml)\n[![erf docs](https://github.com/nomasystems/erf/actions/workflows/docs.yml/badge.svg)](https://nomasystems.github.io/erf)\n\n`erf` is a design-first Erlang REST framework. It provides an interface to spawn specification-driven HTTP servers with several automated features that aim to ease the development, operation and maintenance of design-first RESTful services. Its HTTP protocol features are provided as a wrapper of the [elli](https://github.com/elli-lib/elli) HTTP 1.1 server.","ref":"readme.html","title":"Overview","type":"extras"},{"doc":"When following a code-first approach to develop APIs, the interface is produced as a result of the implementation and, therefore, client-side code, integration tests and other parts of the system that depend on the API behaviour, need to wait until the server-side work is done.\n\nDesign-first is an approach to API development that prioritises the design of the API before its implementation. The explicit contract produced in this design, which should be the result of an agreement between the stakeholders of the API, aims to reduce bottlenecks in the development process.","ref":"readme.html#what-is-design-first","title":"What is design-first? - Overview","type":"extras"},{"doc":"`erf` is an HTTP server framework that, taking an API design in the form of an specification file and a callback module as input, starts a server and dynamically generates code to efficiently type-check and route requests to callback functions. Its main goal is to provide a tool to REST API development in Erlang that reduces the development time by automating the implementation of boilerplate code that can be inferred from the API specification.","ref":"readme.html#how-does-erf-help-developing-design-first-restful-services","title":"How does `erf` help developing design-first RESTful services? - Overview","type":"extras"},{"doc":"1. Design your API using OpenAPI 3.0. For example: [users.openapi.json](examples/users/priv/users.openapi.json).\n\n2. Add `erf` as a dependency in your `rebar3` project.\n```erl\n{deps, [\n {erf, {git, \"git@github.com:nomasystems/erf.git\", {branch, \"main\"}}}\n]}.\n```\n\n3. Implement a callback module for your API. A hypothetical example for [users.openapi.json](examples/users/priv/users.openapi.json) would be [users_callback.erl](examples/users/src/users_callback.erl).\n```erl\n%% An erf callback for the users REST API.\n-module(users_callback).\n\n%%% EXTERNAL EXPORTS\n-export([\n create_user/1,\n get_user/1,\n delete_user/1\n]).\n\n%%%-------------------------------------------------------\n%%% EXTERNAL EXPORTS\n%%%-------------------------------------------------------\ncreate_user(#{body := Body} = _Request) ->\n Id = base64:encode(crypto:strong_rand_bytes(16)),\n ets:insert(users, {Id, Body#{<<\"id\">> => Id}}),\n {201, [], Body#{<<\"id\">> => Id}}.\n\nget_user(#{path_parameters := PathParameters} = _Request) ->\n Id = proplists:get_value(<<\"userId\">>, PathParameters),\n case ets:lookup(users, Id) of\n [] ->\n {404, [], #{\n <<\"message\">> =>\n <<\"User \", Id/binary, \" not found\">>\n }};\n [{Id, User}] ->\n {200, [], User}\n end.\n\ndelete_user(#{path_parameters := PathParameters} = _Request) ->\n Id = proplists:get_value(<<\"userId\">>, PathParameters),\n case ets:lookup(users, Id) of\n [] ->\n {404, [], #{\n <<\"message\">> =>\n <<\"User \", Id/binary, \" not found\">>\n }};\n [_User] ->\n ets:delete(users, Id),\n {204, [], #{<<\"id\">> => Id}}\n end.\n```\n\n4. Start an `erf` instance using the [`erf:start_link/1`](https://nomasystems.github.io/erf/erf.html#start_link/1) function under the supervisor of your application. For example:\n```erl\n-module(users_sup).\n\n%%% BEHAVIOURS\n-behaviour(supervisor).\n\n%%% START/STOP EXPORTS\n-export([start_link/0]).\n\n%%% INTERNAL EXPORTS\n-export([init/1]).\n\n%%%-------------------------------------------------------\n%%% START/STOP EXPORTS\n%%%-------------------------------------------------------\nstart_link() ->\n supervisor:start_link({local, ?MODULE}, ?MODULE, []).\n\n%%%-------------------------------------------------------\n%%% INTERNAL EXPORTS\n%%%-------------------------------------------------------\ninit([]) ->\n % Users storage\n ets:new(users, [public, named_table]),\n UsersAPIConf = #{\n spec_path => <<\"priv/users.openapi.json\">>,\n callback => users_callback,\n preprocess_middlewares => [users_preprocess],\n postprocess_middlewares => [users_postprocess],\n port => 8080\n },\n UsersChildSpec = {\n public_api_server,\n {erf, start_link, [UsersAPIConf]},\n permanent,\n 5000,\n worker,\n [erf]\n },\n {ok, {{one_for_one, 5, 10}, [UsersChildSpec]}}.\n```\nNotice the configured preprocess and postprocess middlewares. They implement a basic authorization mechanism, short-circuiting the request and returning a 403 HTTP error code if the `X-API-KEY: api-key` header is missing, and they print in console the time in microseconds that authorized requests take to complete.\n\n5. Start requesting your service.\n```sh\n$ curl -vvv 'localhost:8080/users' -H 'Content-Type: application/json' -H 'X-API-KEY: api-key' -d '{\"username\": \"foo\", \"password\": \"foobar\"}'\n* Trying 127.0.0.1:8080...\n* Connected to localhost (127.0.0.1) port 8080 (#0)\n> POST /users HTTP/1.1\n> Host: localhost:8080\n> User-Agent: curl/8.0.1\n> Accept: */*\n> Content-Type: application/json\n> Content-Length: 44\n>\n< HTTP/1.1 201 Created\n< connection: Keep-Alive\n< content-length: 73\n< content-type: application/json\n<\n* Connection #0 to host localhost left intact\n{\"id\":\"b7R7bJSbaTmoiWwecy2IwA==\",\"password\":\"foobar\",\"username\":\"foo\"}\n```\n\n## `erf` configuration\n\n`erf`'s main entry point (i.e., the `start_link/1` function) receives an API specification, a callback module and a set of optional values that enable its configuration.\n\nThe configuration is provided as map with the following type spec:\n```erl\n%%% erf.erl\n-type conf() :: #{\n spec_path := binary(),\n callback := module(),\n port => inet:port_number(),\n name => atom(),\n spec_parser => module(),\n preprocess_middlewares => [module()],\n postprocess_middlewares => [module()],\n ssl => boolean(),\n certfile => binary(),\n keyfile => binary(),\n static_routes => [static_route()],\n swagger_ui => boolean(),\n min_acceptors => pos_integer(),\n accept_timeout => pos_integer(),\n request_timeout => pos_integer(),\n header_timeout => pos_integer(),\n body_timeout => pos_integer(),\n max_body_size => pos_integer(),\n log_level => logger:level()\n}.\n```\n\nA detailed description of each parameter can be found in the following list:\n- `spec_path` : Path to API specification file.\n- `callback`: Name of the callback module.\n- `port`: Port the server will listen to. Defaults to `8080`.\n- `name`: Name under which the server is registered. Defaults to `erf`.\n- `spec_parser`: Name of the specification parser module. Defaults to `erf_parser_oas_3_0`.\n- `preprocess_middlewares`: List of names of middlewares to be invoked before the request is forwarded to the callback. Defaults to `[]`.\n- `postprocess_middlewares`: List of names of middlewares to be invoked after the response is returned by the callback. Defaults to `[]`.\n- `ssl`: Boolean flag that enables/disables SSL. Defaults to `false`.\n- `certfile`: Path to the SSL certificate file. Defaults to `undefined`.\n- `keyfile`: Path to the SSL key file. Defaults to `undefined`.\n- `static_routes`: List of routes that serve static files. Defaults to `[]`.\n- `swagger_ui`: Boolean flag that enables/disables the Swagger UI. Defaults to `false`.\n- `min_acceptors`: Minimum number of acceptor processes. Defaults to `20`.\n- `accept_timeout`: Timeout in ms for accepting an incoming request. Defaults to `10000`.\n- `request_timeout`: Timeout in ms for receiving more packets when waiting for the request line. Defaults to `60000`.\n- `header_timeout`: Timeout in ms for receiving more packets when waiting for the headers. Defaults to `10000`.\n- `body_timeout`: Timeout in ms for receiving more packets when waiting for the body. Defaults to `30000`.\n- `max_body_size`: Maximum size in bytes for the body of allowed received messages. Defaults to `1024000`.\n- `log_level`: Severity associated to logged messages. Defaults to `error`.","ref":"readme.html#quickstart","title":"Quickstart - Overview","type":"extras"},{"doc":"`erf` dynamically generates a router that type check the received requests against the API specification. If the request passes the validation, it is deconstructed and passed to the middleware and callback modules. But, how do those middleware and callback modules must look like?\n\n- **Preprocess middlewares** receive a request, do something with it (such as adding an entry to an access log) and return it for the next middleware or callback module to process it. This allows each preprocess middleware to modify the content of the request, updating any of its fields such as the `context` field, specifically dedicated to store contextual information middlewares might want to provide. Preprocess middlewares can short-circuit the processing flow, returning `{stop, Response}` or `{stop, Response, Request}` instead of just `Request`. The first of those alternatives prevents the following preprocess middlewares to execute, as well as the callback module, skipping directly to the postprocess middlewares. The second alternative response format does the same but allows to modify the request information.\n\n- **Callback module**.\nThe router expects your callback module to export one function per operation defined in your API specification. It also expects each operation to include an `operationId` that, after being transformed to _snake_case_, will identify the function that is going to be called. Such function receives an `erf:request()` and must return an `erf:response()`.\n\n- **Postprocess middlewares** can also update the request, like the preprocess middlewares, by returning a `{erf:response(), erf:request()}` tuple or just return a `erf:response()` and leave the received request intact. This middlewares cannot short-circuit the processing flow.\n\nAn example of an API specification and a supported callback can be seen in [Quickstart](#quickstart). Files `users_preprocess.erl` and `users_postprocess.erl` under `examples/users` exemplify how to use `erf` middlewares. Try out the example by running `rebar3 as examples shell` from the root of this project.","ref":"readme.html#callback-modules-middlewares","title":"Callback modules & middlewares - Overview","type":"extras"},{"doc":"The design principles behind `erf` allow its instances to be reconfigured in runtime with no needed downtime. While not every configuration key is updatable once the server is started (e.g., the port), some interesting features of the framework can be updated on-the-fly.\n\nThe following type spec corresponds to the runtime configuration of an `erf` instance. At the same time, is the type spec of the second argument for the `erf:reload/2` function.\n```erl\n%%% erf_conf.erl\n-type t() :: #{\n callback => module(),\n log_level => logger:level(),\n preprocess_middlewares => [module()],\n postprocess_middlewares => [module()],\n router => erl_syntax:syntaxTree(), % not manually updatable\n router_mod => module(), % not manually updatable\n spec_path => binary(),\n spec_parser => module(),\n static_routes => [erf:static_route()],\n swagger_ui => boolean()\n}.\n```\n> __NOTE:__ the `router` and `router_mod` keys are not updatable as they are automatically computed when new configuration is provided.","ref":"readme.html#hot-configuration-reloading","title":"Hot-configuration reloading - Overview","type":"extras"},{"doc":"As shown in [`erf` configuration](#erf-configuration), the server supports routes that serve static files. The type spec for static routes is the following:\n```erl\n%%% erf.erl\n-type static_dir() :: {dir, binary()}.\n-type static_file() :: {file, binary()}.\n-type static_route() :: {Path :: binary(), Resource :: static_file() | static_dir()}.\n```\n\nThis feature enables `erf` to serve a [Swagger UI](https://github.com/swagger-api/swagger-ui) version with your API specification. Just set the `swagger_ui` flag to `true` and open your web browser in the server host under the `/swagger` path.","ref":"readme.html#static-routes","title":"Static routes - Overview","type":"extras"},{"doc":"Diagnosing the cause of a `400 Bad Request error` for a specific request can become challenging due to the automated generation of the router's source code. To simplify the process of analyzing this generated code, `erf` provides the `get_router/1` function. This function offers the router's source code in binary form, allowing you to conveniently manipulate it using the most suitable handler for your particular use case, whether it's printing the code to a file or using `io` operations.","ref":"readme.html#troubleshooting","title":"Troubleshooting - Overview","type":"extras"},{"doc":"","ref":"readme.html#specification-constraints","title":"Specification constraints - Overview","type":"extras"},{"doc":"- Path parameters MUST be of type `string`. You can use the `pattern` keyword to refine your type spec.","ref":"readme.html#oas-3-0","title":"OAS 3.0 - Overview","type":"extras"},{"doc":"We :heart: contributions! Please feel free to submit issues, create pull requests or just spread the word about `erf` in the open-source community. Don't forget to check out our [contribution guidelines](CONTRIBUTING.md) to ensure smooth collaboration! :rocket:","ref":"readme.html#contributing","title":"Contributing - Overview","type":"extras"},{"doc":"If you need help or have any questions, please don't hesitate to open an issue or contact the maintainers directly.","ref":"readme.html#support","title":"Support - Overview","type":"extras"},{"doc":"`erf` is released under the Apache 2.0 License. For more information, please see the [LICENSE](LICENSE) file.","ref":"readme.html#license","title":"License - Overview","type":"extras"},{"doc":"This project uses OpenAPI specification (OAS) schemas and examples, which are licensed under the Apache 2.0 license. See the associated [LICENSE](priv/oas/LICENSE) file for more information.\n\nAdditionally, it allows for `swagger-ui` hosting, which is licensed under the Apache 2.0 license. For more details, please refer to the associated [LICENSE](priv/swagger-ui/LICENSE) file.","ref":"readme.html#additional-licenses","title":"Additional Licenses - Overview","type":"extras"},{"doc":"# Contributing to erf\n\nAny contribution is welcome. Here you have the guidelines you must follow to contribute to the project.","ref":"contributing.html","title":"Contributing","type":"extras"},{"doc":"[Doubts or questions](#doubts-or-questions) \n[Documentation](#documentation) \n[Bug reports](#bug-reports) \n[Feature requests](#feature-requests) \n[Development](#development)","ref":"contributing.html#table-of-contents","title":"Table of Contents - Contributing","type":"extras"},{"doc":"If you have any doubt or question about the project, please:\n\n1. Read the [documentation](README.md) in case it helps you to clarify the concepts.\n2. Check out [the issue tracker](https://github.com/nomasystems/erf/issues?q=is%3Aissue+label%3Aquestion). Maybe your question is already reflected there.\n3. If none of the above makes it clearer for you, create a new question in the issue tracker. The team will try to answer as soon as possible.","ref":"contributing.html#doubts-or-questions","title":"Doubts or questions - Contributing","type":"extras"},{"doc":"Do you find that something is missing/wrong in the docs? Please, create a new documentation issue in the issue tracker. We will get back to you as soon as possible.","ref":"contributing.html#documentation","title":"Documentation - Contributing","type":"extras"},{"doc":"Bug reports help us improve the code. We take them very seriously and thank you for taking the time to create them.\n\nIf you find a bug in the code, please:\n \n1. Read the [documentation](README.md) to make sure you find an unexpected behaviour.\n2. Check out [the issue tracker](https://github.com/nomasystems/erf/issues?q=is%3Aissue+label%3Abug). Maybe your bug report is already reflected there.\n3. If you still think this is a new bug report, please create a new bug report in the issue tracker, and make sure you fill all the fields so the person solving the problem has all the necessary information.","ref":"contributing.html#bug-reports","title":"Bug reports - Contributing","type":"extras"},{"doc":"Feature requests are welcome. If you think that the project is missing a feature, please:\n \n1. Read the [documentation](README.md) to make sure the feature is not already included.\n2. Check out [the issue tracker](https://github.com/nomasystems/erf/issues?q=is%3Aissue+label%3Aenhancement). Maybe your feature was already requested by someone else.\n3. If your feature is not reflected in any of the above, please create a new feature request in the issue tracker, giving as much context and detail as needed.","ref":"contributing.html#feature-requests","title":"Feature requests - Contributing","type":"extras"},{"doc":"In order to develop something for the project, you must follow these rules:\n\n1. Find an appropriate issue to solve:\n * Only verified issues with complete information must be addressed (avoid issues with label `needs triage`, as they must be reviewed by the nomasystems group).\n * If an issue is already assigned to another user, it means that this user is already solving the issue. Please, respect other people's work and don't interfere.\n * Issues labeled with `good first issue` are quicker and simpler, so they can be a good starting point when contributing.\n2. Assign the issue to yourself, so other developers know that you are already working on it. Don't be ashamed if you find later that you won't be able to solve the issue, just left it unassigned so someone else can work on it.\n3. Create a branch to solve the issue:\n * If the issue has the label `documentation`:\n - The new branch must be created from the branch named `develop`.\n - The name of the new branch must be `docs/{IssueIdentifier}-{IssueTitle in kebab-case}`.\n * If the issue has the label `bug`:\n - The new branch must be created from the branch named `main`.\n - The name of the new branch must be `fix/{IssueIdentifier}-{IssueTitle in kebab-case}`.\n * If the issue has the label `enhancement`:\n - The new branch must be created from the branch named `develop`.\n - The name of the new branch must be `feat/{IssueIdentifier}-{IssueTitle in kebab-case}`.\n4. Make the changes in the new branch. Don't forget to:\n * Add new test cases checking that the bug is solved / the new feature is successfully implemented.\n * Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to create commit messages. If a commit closes an issue, the footer must include the expression `closes #IssueIdentifier`.\n5. When the issue is solved, create a new pull request:\n * Add a description with the changes you've made.\n * Link the issue to the PR.\n * Left it unassigned, someone from the nomasystems group will review it as soon as possible.","ref":"contributing.html#development","title":"Development - Contributing","type":"extras"},{"doc":"Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.","ref":"license.html","title":"License","type":"extras"}],"producer":{"name":"ex_doc","version":[48,46,51,52,46,50]}} \ No newline at end of file diff --git a/dist/search_data-3FC7F05E.js b/dist/search_data-3FC7F05E.js deleted file mode 100644 index ff4c56e..0000000 --- a/dist/search_data-3FC7F05E.js +++ /dev/null @@ -1 +0,0 @@ -searchData={"content_type":"text/plain","items":[{"doc":"erf is a library that provides a design-first framework to build RESTful APIs in Erlang.","ref":"erf.html","title":"erf","type":"module"},{"doc":"Returns the router for an instance of the server.","ref":"erf.html#get_router/1","title":"erf.get_router/1","type":"function"},{"doc":null,"ref":"erf.html#init/1","title":"erf.init/1","type":"function"},{"doc":"Reloads the configuration for an instance of the server.","ref":"erf.html#reload_conf/2","title":"erf.reload_conf/2","type":"function"},{"doc":"Starts the supervision tree for an instance of the server.","ref":"erf.html#start_link/1","title":"erf.start_link/1","type":"function"},{"doc":"Stops the supervision tree for an instance of the server.","ref":"erf.html#stop/1","title":"erf.stop/1","type":"function"},{"doc":null,"ref":"erf.html#t:api/0","title":"erf.api/0","type":"type"},{"doc":null,"ref":"erf.html#t:body/0","title":"erf.body/0","type":"type"},{"doc":null,"ref":"erf.html#t:conf/0","title":"erf.conf/0","type":"type"},{"doc":null,"ref":"erf.html#t:header/0","title":"erf.header/0","type":"type"},{"doc":null,"ref":"erf.html#t:method/0","title":"erf.method/0","type":"type"},{"doc":null,"ref":"erf.html#t:path_parameter/0","title":"erf.path_parameter/0","type":"type"},{"doc":null,"ref":"erf.html#t:query_parameter/0","title":"erf.query_parameter/0","type":"type"},{"doc":null,"ref":"erf.html#t:request/0","title":"erf.request/0","type":"type"},{"doc":null,"ref":"erf.html#t:response/0","title":"erf.response/0","type":"type"},{"doc":null,"ref":"erf.html#t:static_dir/0","title":"erf.static_dir/0","type":"type"},{"doc":null,"ref":"erf.html#t:static_file/0","title":"erf.static_file/0","type":"type"},{"doc":null,"ref":"erf.html#t:static_route/0","title":"erf.static_route/0","type":"type"},{"doc":"erf 's configuration manager module.","ref":"erf_conf.html","title":"erf_conf","type":"module"},{"doc":"Clears the configuration for the given Name .","ref":"erf_conf.html#clear/1","title":"erf_conf.clear/1","type":"function"},{"doc":"Returns the configuration for the given Name .","ref":"erf_conf.html#get/1","title":"erf_conf.get/1","type":"function"},{"doc":"Returns the log level for the given Name .","ref":"erf_conf.html#log_level/1","title":"erf_conf.log_level/1","type":"function"},{"doc":"Returns the postprocess middlewares for the given Name .","ref":"erf_conf.html#postprocess_middlewares/1","title":"erf_conf.postprocess_middlewares/1","type":"function"},{"doc":"Returns the preprocess middlewares for the given Name .","ref":"erf_conf.html#preprocess_middlewares/1","title":"erf_conf.preprocess_middlewares/1","type":"function"},{"doc":"Returns the router for the given Name .","ref":"erf_conf.html#router/1","title":"erf_conf.router/1","type":"function"},{"doc":"Returns the router module name for the given Name .","ref":"erf_conf.html#router_mod/1","title":"erf_conf.router_mod/1","type":"function"},{"doc":"Sets the configuration for the given Name .","ref":"erf_conf.html#set/2","title":"erf_conf.set/2","type":"function"},{"doc":null,"ref":"erf_conf.html#t:t/0","title":"erf_conf.t/0","type":"type"},{"doc":"Module that parses a specification file into an API AST.","ref":"erf_parser.html","title":"erf_parser","type":"behaviour"},{"doc":null,"ref":"erf_parser.html#c:parse/1","title":"erf_parser.parse/1","type":"callback"},{"doc":"Parses an specification file into an API AST given a specification format.","ref":"erf_parser.html#parse/2","title":"erf_parser.parse/2","type":"function"},{"doc":null,"ref":"erf_parser.html#t:api/0","title":"erf_parser.api/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:body/0","title":"erf_parser.body/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:endpoint/0","title":"erf_parser.endpoint/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:method/0","title":"erf_parser.method/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:operation/0","title":"erf_parser.operation/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:parameter/0","title":"erf_parser.parameter/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:parameter_name/0","title":"erf_parser.parameter_name/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:parameter_type/0","title":"erf_parser.parameter_type/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:path/0","title":"erf_parser.path/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:ref/0","title":"erf_parser.ref/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:request/0","title":"erf_parser.request/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:response/0","title":"erf_parser.response/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:schema/0","title":"erf_parser.schema/0","type":"type"},{"doc":null,"ref":"erf_parser.html#t:status_code/0","title":"erf_parser.status_code/0","type":"type"},{"doc":"An OpenAPI Specification 3.0 erf_parser .","ref":"erf_parser_oas_3_0.html","title":"erf_parser_oas_3_0","type":"module"},{"doc":"Parses an OpenAPI Specification 3.0 file into an API AST.","ref":"erf_parser_oas_3_0.html#parse/1","title":"erf_parser_oas_3_0.parse/1","type":"function"},{"doc":null,"ref":"erf_parser_oas_3_0.html#t:ctx/0","title":"erf_parser_oas_3_0.ctx/0","type":"type"},{"doc":null,"ref":"erf_parser_oas_3_0.html#t:spec/0","title":"erf_parser_oas_3_0.spec/0","type":"type"},{"doc":"Behaviour for erf 's postprocessing middlewares.","ref":"erf_postprocess_middleware.html","title":"erf_postprocess_middleware","type":"behaviour"},{"doc":null,"ref":"erf_postprocess_middleware.html#c:postprocess/2","title":"erf_postprocess_middleware.postprocess/2","type":"callback"},{"doc":"A module that implements this behaviour.","ref":"erf_postprocess_middleware.html#t:t/0","title":"erf_postprocess_middleware.t/0","type":"type"},{"doc":"Behaviour for erf 's preprocessing middlewares.","ref":"erf_preprocess_middleware.html","title":"erf_preprocess_middleware","type":"behaviour"},{"doc":null,"ref":"erf_preprocess_middleware.html#c:preprocess/1","title":"erf_preprocess_middleware.preprocess/1","type":"callback"},{"doc":"A module that implements this behaviour.","ref":"erf_preprocess_middleware.html#t:t/0","title":"erf_preprocess_middleware.t/0","type":"type"},{"doc":null,"ref":"erf_router.html","title":"erf_router","type":"module"},{"doc":"Generates an Erlang Syntax Tree of a router module from an API AST.","ref":"erf_router.html#generate/2","title":"erf_router.generate/2","type":"function"},{"doc":"Loads a router module into the Erlang Runtime System.","ref":"erf_router.html#load/1","title":"erf_router.load/1","type":"function"},{"doc":null,"ref":"erf_router.html#t:callback/0","title":"erf_router.callback/0","type":"type"},{"doc":null,"ref":"erf_router.html#t:generator_opts/0","title":"erf_router.generator_opts/0","type":"type"},{"doc":null,"ref":"erf_router.html#t:t/0","title":"erf_router.t/0","type":"type"},{"doc":"erf 's static files handler utility module.","ref":"erf_static.html","title":"erf_static","type":"module"},{"doc":"Returns the MIME type for the given file extension. https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types","ref":"erf_static.html#mime_type/1","title":"erf_static.mime_type/1","type":"function"},{"doc":null,"ref":"erf_util.html","title":"erf_util","type":"module"},{"doc":"Naive function to convert a binary or string to PascalCase.","ref":"erf_util.html#to_pascal_case/1","title":"erf_util.to_pascal_case/1","type":"function"},{"doc":"Naive function to convert a binary or string to snake_case.","ref":"erf_util.html#to_snake_case/1","title":"erf_util.to_snake_case/1","type":"function"},{"doc":"# erf - A design-first Erlang REST Framework\n[![erf ci](https://github.com/nomasystems/erf/actions/workflows/ci.yml/badge.svg)](https://github.com/nomasystems/erf/actions/workflows/ci.yml)\n[![erf docs](https://github.com/nomasystems/erf/actions/workflows/docs.yml/badge.svg)](https://nomasystems.github.io/erf)\n\n`erf` is a design-first Erlang REST framework. It provides an interface to spawn specification-driven HTTP servers with several automated features that aim to ease the development, operation and maintenance of design-first RESTful services. Its HTTP protocol features are provided as a wrapper of the [elli](https://github.com/elli-lib/elli) HTTP 1.1 server.","ref":"readme.html","title":"Overview","type":"extras"},{"doc":"When following a code-first approach to develop APIs, the interface is produced as a result of the implementation and, therefore, client-side code, integration tests and other parts of the system that depend on the API behaviour, need to wait until the server-side work is done.\n\nDesign-first is an approach to API development that prioritises the design of the API before its implementation. The explicit contract produced in this design, which should be the result of an agreement between the stakeholders of the API, aims to reduce bottlenecks in the development process.","ref":"readme.html#what-is-design-first","title":"What is design-first? - Overview","type":"extras"},{"doc":"`erf` is an HTTP server framework that, taking an API design in the form of an specification file and a callback module as input, starts a server and dynamically generates code to efficiently type-check and route requests to callback functions. Its main goal is to provide a tool to REST API development in Erlang that reduces the development time by automating the implementation of boilerplate code that can be inferred from the API specification.","ref":"readme.html#how-does-erf-help-developing-design-first-restful-services","title":"How does `erf` help developing design-first RESTful services? - Overview","type":"extras"},{"doc":"1. Design your API using OpenAPI 3.0. For example: [users.openapi.json](examples/users/priv/users.openapi.json).\n\n2. Add `erf` as a dependency in your `rebar3` project.\n```erl\n{deps, [\n {erf, {git, \"git@github.com:nomasystems/erf.git\", {branch, \"main\"}}}\n]}.\n```\n\n3. Implement a callback module for your API. A hypothetical example for [users.openapi.json](examples/users/priv/users.openapi.json) would be [users_callback.erl](examples/users/src/users_callback.erl).\n```erl\n%% An erf callback for the users REST API.\n-module(users_callback).\n\n%%% EXTERNAL EXPORTS\n-export([\n create_user/1,\n get_user/1,\n delete_user/1\n]).\n\n%%%-------------------------------------------------------\n%%% EXTERNAL EXPORTS\n%%%-------------------------------------------------------\ncreate_user(#{body := Body} = _Request) ->\n Id = base64:encode(crypto:strong_rand_bytes(16)),\n ets:insert(users, {Id, Body#{<<\"id\">> => Id}}),\n {201, [], Body#{<<\"id\">> => Id}}.\n\nget_user(#{path_parameters := PathParameters} = _Request) ->\n Id = proplists:get_value(<<\"userId\">>, PathParameters),\n case ets:lookup(users, Id) of\n [] ->\n {404, [], #{\n <<\"message\">> =>\n <<\"User \", Id/binary, \" not found\">>\n }};\n [{Id, User}] ->\n {200, [], User}\n end.\n\ndelete_user(#{path_parameters := PathParameters} = _Request) ->\n Id = proplists:get_value(<<\"userId\">>, PathParameters),\n case ets:lookup(users, Id) of\n [] ->\n {404, [], #{\n <<\"message\">> =>\n <<\"User \", Id/binary, \" not found\">>\n }};\n [_User] ->\n ets:delete(users, Id),\n {204, [], #{<<\"id\">> => Id}}\n end.\n```\n\n4. Start an `erf` instance using the [`erf:start_link/1`](https://nomasystems.github.io/erf/erf.html#start_link/1) function under the supervisor of your application. For example:\n```erl\n-module(users_sup).\n\n%%% BEHAVIOURS\n-behaviour(supervisor).\n\n%%% START/STOP EXPORTS\n-export([start_link/0]).\n\n%%% INTERNAL EXPORTS\n-export([init/1]).\n\n%%%-------------------------------------------------------\n%%% START/STOP EXPORTS\n%%%-------------------------------------------------------\nstart_link() ->\n supervisor:start_link({local, ?MODULE}, ?MODULE, []).\n\n%%%-------------------------------------------------------\n%%% INTERNAL EXPORTS\n%%%-------------------------------------------------------\ninit([]) ->\n % Users storage\n ets:new(users, [public, named_table]),\n UsersAPIConf = #{\n spec_path => <<\"priv/users.openapi.json\">>,\n callback => users_callback,\n preprocess_middlewares => [users_preprocess],\n postprocess_middlewares => [users_postprocess],\n port => 8080\n },\n UsersChildSpec = {\n public_api_server,\n {erf, start_link, [UsersAPIConf]},\n permanent,\n 5000,\n worker,\n [erf]\n },\n {ok, {{one_for_one, 5, 10}, [UsersChildSpec]}}.\n```\nNotice the configured preprocess and postprocess middlewares. They implement a basic authorization mechanism, short-circuiting the request and returning a 403 HTTP error code if the `X-API-KEY: api-key` header is missing, and they print in console the time in microseconds that authorized requests take to complete.\n\n5. Start requesting your service.\n```sh\n$ curl -vvv 'localhost:8080/users' -H 'Content-Type: application/json' -H 'X-API-KEY: api-key' -d '{\"username\": \"foo\", \"password\": \"foobar\"}'\n* Trying 127.0.0.1:8080...\n* Connected to localhost (127.0.0.1) port 8080 (#0)\n> POST /users HTTP/1.1\n> Host: localhost:8080\n> User-Agent: curl/8.0.1\n> Accept: */*\n> Content-Type: application/json\n> Content-Length: 44\n>\n< HTTP/1.1 201 Created\n< connection: Keep-Alive\n< content-length: 73\n< content-type: application/json\n<\n* Connection #0 to host localhost left intact\n{\"id\":\"b7R7bJSbaTmoiWwecy2IwA==\",\"password\":\"foobar\",\"username\":\"foo\"}\n```\n\n## `erf` configuration\n\n`erf`'s main entry point (i.e., the `start_link/1` function) receives an API specification, a callback module and a set of optional values that enable its configuration.\n\nThe configuration is provided as map with the following type spec:\n```erl\n%%% erf.erl\n-type conf() :: #{\n spec_path := binary(),\n callback := module(),\n port => inet:port_number(),\n name => atom(),\n spec_parser => module(),\n preprocess_middlewares => [module()],\n postprocess_middlewares => [module()],\n ssl => boolean(),\n certfile => binary(),\n keyfile => binary(),\n static_routes => [static_route()],\n swagger_ui => boolean(),\n min_acceptors => pos_integer(),\n accept_timeout => pos_integer(),\n request_timeout => pos_integer(),\n header_timeout => pos_integer(),\n body_timeout => pos_integer(),\n max_body_size => pos_integer(),\n log_level => logger:level()\n}.\n```\n\nA detailed description of each parameter can be found in the following list:\n- `spec_path` : Path to API specification file.\n- `callback`: Name of the callback module.\n- `port`: Port the server will listen to. Defaults to `8080`.\n- `name`: Name under which the server is registered. Defaults to `erf`.\n- `spec_parser`: Name of the specification parser module. Defaults to `erf_parser_oas_3_0`.\n- `preprocess_middlewares`: List of names of middlewares to be invoked before the request is forwarded to the callback. Defaults to `[]`.\n- `postprocess_middlewares`: List of names of middlewares to be invoked after the response is returned by the callback. Defaults to `[]`.\n- `ssl`: Boolean flag that enables/disables SSL. Defaults to `false`.\n- `certfile`: Path to the SSL certificate file. Defaults to `undefined`.\n- `keyfile`: Path to the SSL key file. Defaults to `undefined`.\n- `static_routes`: List of routes that serve static files. Defaults to `[]`.\n- `swagger_ui`: Boolean flag that enables/disables the Swagger UI. Defaults to `false`.\n- `min_acceptors`: Minimum number of acceptor processes. Defaults to `20`.\n- `accept_timeout`: Timeout in ms for accepting an incoming request. Defaults to `10000`.\n- `request_timeout`: Timeout in ms for receiving more packets when waiting for the request line. Defaults to `60000`.\n- `header_timeout`: Timeout in ms for receiving more packets when waiting for the headers. Defaults to `10000`.\n- `body_timeout`: Timeout in ms for receiving more packets when waiting for the body. Defaults to `30000`.\n- `max_body_size`: Maximum size in bytes for the body of allowed received messages. Defaults to `1024000`.\n- `log_level`: Severity associated to logged messages. Defaults to `error`.","ref":"readme.html#quickstart","title":"Quickstart - Overview","type":"extras"},{"doc":"`erf` dynamically generates a router that type check the received requests against the API specification. If the request passes the validation, it is deconstructed and passed to the middleware and callback modules. But, how do those middleware and callback modules must look like?\n\n- **Preprocess middlewares** receive a request, do something with it (such as adding an entry to an access log) and return it for the next middleware or callback module to process it. This allows each preprocess middleware to modify the content of the request, updating any of its fields such as the `context` field, specifically dedicated to store contextual information middlewares might want to provide. Preprocess middlewares can short-circuit the processing flow, returning `{stop, Response}` or `{stop, Response, Request}` instead of just `Request`. The first of those alternatives prevents the following preprocess middlewares to execute, as well as the callback module, skipping directly to the postprocess middlewares. The second alternative response format does the same but allows to modify the request information.\n\n- **Callback module**.\nThe router expects your callback module to export one function per operation defined in your API specification. It also expects each operation to include an `operationId` that, after being transformed to _snake_case_, will identify the function that is going to be called. Such function receives an `erf:request()` and must return an `erf:response()`.\n\n- **Postprocess middlewares** can also update the request, like the preprocess middlewares, by returning a `{erf:response(), erf:request()}` tuple or just return a `erf:response()` and leave the received request intact. This middlewares cannot short-circuit the processing flow.\n\nAn example of an API specification and a supported callback can be seen in [Quickstart](#quickstart). Files `users_preprocess.erl` and `users_postprocess.erl` under `examples/users` exemplify how to use `erf` middlewares. Try out the example by running `rebar3 as examples shell` from the root of this project.","ref":"readme.html#callback-modules-middlewares","title":"Callback modules & middlewares - Overview","type":"extras"},{"doc":"The design principles behind `erf` allow its instances to be reconfigured in runtime with no needed downtime. While not every configuration key is updatable once the server is started (e.g., the port), some interesting features of the framework can be updated on-the-fly.\n\nThe following type spec corresponds to the runtime configuration of an `erf` instance. At the same time, is the type spec of the second argument for the `erf:reload/2` function.\n```erl\n%%% erf_conf.erl\n-type t() :: #{\n callback => module(),\n log_level => logger:level(),\n preprocess_middlewares => [module()],\n postprocess_middlewares => [module()],\n router => erl_syntax:syntaxTree(), % not manually updatable\n router_mod => module(), % not manually updatable\n spec_path => binary(),\n spec_parser => module(),\n static_routes => [erf:static_route()],\n swagger_ui => boolean()\n}.\n```\n> __NOTE:__ the `router` and `router_mod` keys are not updatable as they are automatically computed when new configuration is provided.","ref":"readme.html#hot-configuration-reloading","title":"Hot-configuration reloading - Overview","type":"extras"},{"doc":"As shown in [`erf` configuration](#erf-configuration), the server supports routes that serve static files. The type spec for static routes is the following:\n```erl\n%%% erf.erl\n-type static_dir() :: {dir, binary()}.\n-type static_file() :: {file, binary()}.\n-type static_route() :: {Path :: binary(), Resource :: static_file() | static_dir()}.\n```\n\nThis feature enables `erf` to serve a [Swagger UI](https://github.com/swagger-api/swagger-ui) version with your API specification. Just set the `swagger_ui` flag to `true` and open your web browser in the server host under the `/swagger` path.","ref":"readme.html#static-routes","title":"Static routes - Overview","type":"extras"},{"doc":"Diagnosing the cause of a `400 Bad Request error` for a specific request can become challenging due to the automated generation of the router's source code. To simplify the process of analyzing this generated code, `erf` provides the `get_router/1` function. This function offers the router's source code in binary form, allowing you to conveniently manipulate it using the most suitable handler for your particular use case, whether it's printing the code to a file or using `io` operations.","ref":"readme.html#troubleshooting","title":"Troubleshooting - Overview","type":"extras"},{"doc":"","ref":"readme.html#specification-constraints","title":"Specification constraints - Overview","type":"extras"},{"doc":"- Path parameters MUST be of type `string`. You can use the `pattern` keyword to refine your type spec.","ref":"readme.html#oas-3-0","title":"OAS 3.0 - Overview","type":"extras"},{"doc":"We :heart: contributions! Please feel free to submit issues, create pull requests or just spread the word about `erf` in the open-source community. Don't forget to check out our [contribution guidelines](CONTRIBUTING.md) to ensure smooth collaboration! :rocket:","ref":"readme.html#contributing","title":"Contributing - Overview","type":"extras"},{"doc":"If you need help or have any questions, please don't hesitate to open an issue or contact the maintainers directly.","ref":"readme.html#support","title":"Support - Overview","type":"extras"},{"doc":"`erf` is released under the Apache 2.0 License. For more information, please see the [LICENSE](LICENSE) file.","ref":"readme.html#license","title":"License - Overview","type":"extras"},{"doc":"This project uses OpenAPI specification (OAS) schemas and examples, which are licensed under the Apache 2.0 license. See the associated [LICENSE](priv/oas/LICENSE) file for more information.\n\nAdditionally, it allows for `swagger-ui` hosting, which is licensed under the Apache 2.0 license. For more details, please refer to the associated [LICENSE](priv/swagger-ui/LICENSE) file.","ref":"readme.html#additional-licenses","title":"Additional Licenses - Overview","type":"extras"},{"doc":"# Contributing to erf\n\nAny contribution is welcome. Here you have the guidelines you must follow to contribute to the project.","ref":"contributing.html","title":"Contributing","type":"extras"},{"doc":"[Doubts or questions](#doubts-or-questions) \n[Documentation](#documentation) \n[Bug reports](#bug-reports) \n[Feature requests](#feature-requests) \n[Development](#development)","ref":"contributing.html#table-of-contents","title":"Table of Contents - Contributing","type":"extras"},{"doc":"If you have any doubt or question about the project, please:\n\n1. Read the [documentation](README.md) in case it helps you to clarify the concepts.\n2. Check out [the issue tracker](https://github.com/nomasystems/erf/issues?q=is%3Aissue+label%3Aquestion). Maybe your question is already reflected there.\n3. If none of the above makes it clearer for you, create a new question in the issue tracker. The team will try to answer as soon as possible.","ref":"contributing.html#doubts-or-questions","title":"Doubts or questions - Contributing","type":"extras"},{"doc":"Do you find that something is missing/wrong in the docs? Please, create a new documentation issue in the issue tracker. We will get back to you as soon as possible.","ref":"contributing.html#documentation","title":"Documentation - Contributing","type":"extras"},{"doc":"Bug reports help us improve the code. We take them very seriously and thank you for taking the time to create them.\n\nIf you find a bug in the code, please:\n \n1. Read the [documentation](README.md) to make sure you find an unexpected behaviour.\n2. Check out [the issue tracker](https://github.com/nomasystems/erf/issues?q=is%3Aissue+label%3Abug). Maybe your bug report is already reflected there.\n3. If you still think this is a new bug report, please create a new bug report in the issue tracker, and make sure you fill all the fields so the person solving the problem has all the necessary information.","ref":"contributing.html#bug-reports","title":"Bug reports - Contributing","type":"extras"},{"doc":"Feature requests are welcome. If you think that the project is missing a feature, please:\n \n1. Read the [documentation](README.md) to make sure the feature is not already included.\n2. Check out [the issue tracker](https://github.com/nomasystems/erf/issues?q=is%3Aissue+label%3Aenhancement). Maybe your feature was already requested by someone else.\n3. If your feature is not reflected in any of the above, please create a new feature request in the issue tracker, giving as much context and detail as needed.","ref":"contributing.html#feature-requests","title":"Feature requests - Contributing","type":"extras"},{"doc":"In order to develop something for the project, you must follow these rules:\n\n1. Find an appropriate issue to solve:\n * Only verified issues with complete information must be addressed (avoid issues with label `needs triage`, as they must be reviewed by the nomasystems group).\n * If an issue is already assigned to another user, it means that this user is already solving the issue. Please, respect other people's work and don't interfere.\n * Issues labeled with `good first issue` are quicker and simpler, so they can be a good starting point when contributing.\n2. Assign the issue to yourself, so other developers know that you are already working on it. Don't be ashamed if you find later that you won't be able to solve the issue, just left it unassigned so someone else can work on it.\n3. Create a branch to solve the issue:\n * If the issue has the label `documentation`:\n - The new branch must be created from the branch named `develop`.\n - The name of the new branch must be `docs/{IssueIdentifier}-{IssueTitle in kebab-case}`.\n * If the issue has the label `bug`:\n - The new branch must be created from the branch named `main`.\n - The name of the new branch must be `fix/{IssueIdentifier}-{IssueTitle in kebab-case}`.\n * If the issue has the label `enhancement`:\n - The new branch must be created from the branch named `develop`.\n - The name of the new branch must be `feat/{IssueIdentifier}-{IssueTitle in kebab-case}`.\n4. Make the changes in the new branch. Don't forget to:\n * Add new test cases checking that the bug is solved / the new feature is successfully implemented.\n * Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to create commit messages. If a commit closes an issue, the footer must include the expression `closes #IssueIdentifier`.\n5. When the issue is solved, create a new pull request:\n * Add a description with the changes you've made.\n * Link the issue to the PR.\n * Left it unassigned, someone from the nomasystems group will review it as soon as possible.","ref":"contributing.html#development","title":"Development - Contributing","type":"extras"},{"doc":"Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.","ref":"license.html","title":"License","type":"extras"}],"producer":{"name":"ex_doc","version":[48,46,51,50,46,50]}} \ No newline at end of file diff --git a/dist/sidebar_items-28F82D22.js b/dist/sidebar_items-28F82D22.js new file mode 100644 index 0000000..225f23d --- /dev/null +++ b/dist/sidebar_items-28F82D22.js @@ -0,0 +1 @@ +sidebarNodes={"extras":[{"group":"","headers":[{"anchor":"modules","id":"Modules"}],"id":"api-reference","title":"API Reference"},{"group":"","headers":[{"anchor":"what-is-design-first","id":"What is design-first?"},{"anchor":"how-does-erf-help-developing-design-first-restful-services","id":"How does erf help developing design-first RESTful services?"},{"anchor":"quickstart","id":"Quickstart"},{"anchor":"erf-configuration","id":"erf configuration"},{"anchor":"callback-modules-middlewares","id":"Callback modules & middlewares"},{"anchor":"hot-configuration-reloading","id":"Hot-configuration reloading"},{"anchor":"static-routes","id":"Static routes"},{"anchor":"troubleshooting","id":"Troubleshooting"},{"anchor":"specification-constraints","id":"Specification constraints"},{"anchor":"contributing","id":"Contributing"},{"anchor":"support","id":"Support"},{"anchor":"license","id":"License"}],"id":"readme","title":"Overview"},{"group":"","headers":[{"anchor":"table-of-contents","id":"Table of Contents"},{"anchor":"doubts-or-questions","id":"Doubts or questions"},{"anchor":"documentation","id":"Documentation"},{"anchor":"bug-reports","id":"Bug reports"},{"anchor":"feature-requests","id":"Feature requests"},{"anchor":"development","id":"Development"}],"id":"contributing","title":"Contributing"},{"group":"","headers":[],"id":"license","title":"License"}],"modules":[{"deprecated":false,"group":"","id":"erf","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:api/0","deprecated":false,"id":"api/0","title":"api/0"},{"anchor":"t:body/0","deprecated":false,"id":"body/0","title":"body/0"},{"anchor":"t:conf/0","deprecated":false,"id":"conf/0","title":"conf/0"},{"anchor":"t:header/0","deprecated":false,"id":"header/0","title":"header/0"},{"anchor":"t:method/0","deprecated":false,"id":"method/0","title":"method/0"},{"anchor":"t:path_parameter/0","deprecated":false,"id":"path_parameter/0","title":"path_parameter/0"},{"anchor":"t:query_parameter/0","deprecated":false,"id":"query_parameter/0","title":"query_parameter/0"},{"anchor":"t:request/0","deprecated":false,"id":"request/0","title":"request/0"},{"anchor":"t:response/0","deprecated":false,"id":"response/0","title":"response/0"},{"anchor":"t:static_dir/0","deprecated":false,"id":"static_dir/0","title":"static_dir/0"},{"anchor":"t:static_file/0","deprecated":false,"id":"static_file/0","title":"static_file/0"},{"anchor":"t:static_route/0","deprecated":false,"id":"static_route/0","title":"static_route/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"get_router/1","deprecated":false,"id":"get_router/1","title":"get_router(Name)"},{"anchor":"init/1","deprecated":false,"id":"init/1","title":"init(_)"},{"anchor":"reload_conf/2","deprecated":false,"id":"reload_conf/2","title":"reload_conf(Name, Conf)"},{"anchor":"start_link/1","deprecated":false,"id":"start_link/1","title":"start_link(Conf)"},{"anchor":"stop/1","deprecated":false,"id":"stop/1","title":"stop(Name)"}]}],"sections":[],"title":"erf"},{"deprecated":false,"group":"","id":"erf_conf","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"clear/1","deprecated":false,"id":"clear/1","title":"clear(Name)"},{"anchor":"get/1","deprecated":false,"id":"get/1","title":"get(Name)"},{"anchor":"log_level/1","deprecated":false,"id":"log_level/1","title":"log_level(Name)"},{"anchor":"postprocess_middlewares/1","deprecated":false,"id":"postprocess_middlewares/1","title":"postprocess_middlewares(Name)"},{"anchor":"preprocess_middlewares/1","deprecated":false,"id":"preprocess_middlewares/1","title":"preprocess_middlewares(Name)"},{"anchor":"router/1","deprecated":false,"id":"router/1","title":"router(Name)"},{"anchor":"router_mod/1","deprecated":false,"id":"router_mod/1","title":"router_mod(Name)"},{"anchor":"set/2","deprecated":false,"id":"set/2","title":"set(Name, Conf)"}]}],"sections":[],"title":"erf_conf"},{"deprecated":false,"group":"","id":"erf_http_server","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:conf/0","deprecated":false,"id":"conf/0","title":"conf/0"},{"anchor":"t:extra_conf/0","deprecated":false,"id":"extra_conf/0","title":"extra_conf/0"},{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"callbacks","name":"Callbacks","nodes":[{"anchor":"c:start_link/3","deprecated":false,"id":"start_link/3","title":"start_link/3"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"start_link/4","deprecated":false,"id":"start_link/4","title":"start_link(Module, ModuleExtraConf, Name, Conf)"}]}],"sections":[],"title":"erf_http_server"},{"deprecated":false,"group":"","id":"erf_http_server_elli","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:extra_conf/0","deprecated":false,"id":"extra_conf/0","title":"extra_conf/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"start_link/3","deprecated":false,"id":"start_link/3","title":"start_link(Name, Conf, ExtraConf)"}]}],"sections":[],"title":"erf_http_server_elli"},{"deprecated":false,"group":"","id":"erf_parser","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:api/0","deprecated":false,"id":"api/0","title":"api/0"},{"anchor":"t:body/0","deprecated":false,"id":"body/0","title":"body/0"},{"anchor":"t:endpoint/0","deprecated":false,"id":"endpoint/0","title":"endpoint/0"},{"anchor":"t:method/0","deprecated":false,"id":"method/0","title":"method/0"},{"anchor":"t:operation/0","deprecated":false,"id":"operation/0","title":"operation/0"},{"anchor":"t:parameter/0","deprecated":false,"id":"parameter/0","title":"parameter/0"},{"anchor":"t:parameter_name/0","deprecated":false,"id":"parameter_name/0","title":"parameter_name/0"},{"anchor":"t:parameter_type/0","deprecated":false,"id":"parameter_type/0","title":"parameter_type/0"},{"anchor":"t:path/0","deprecated":false,"id":"path/0","title":"path/0"},{"anchor":"t:ref/0","deprecated":false,"id":"ref/0","title":"ref/0"},{"anchor":"t:request/0","deprecated":false,"id":"request/0","title":"request/0"},{"anchor":"t:response/0","deprecated":false,"id":"response/0","title":"response/0"},{"anchor":"t:schema/0","deprecated":false,"id":"schema/0","title":"schema/0"},{"anchor":"t:status_code/0","deprecated":false,"id":"status_code/0","title":"status_code/0"}]},{"key":"callbacks","name":"Callbacks","nodes":[{"anchor":"c:parse/1","deprecated":false,"id":"parse/1","title":"parse/1"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"parse/2","deprecated":false,"id":"parse/2","title":"parse(SpecPath, SpecParser)"}]}],"sections":[],"title":"erf_parser"},{"deprecated":false,"group":"","id":"erf_parser_oas_3_0","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:ctx/0","deprecated":false,"id":"ctx/0","title":"ctx/0"},{"anchor":"t:spec/0","deprecated":false,"id":"spec/0","title":"spec/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"parse/1","deprecated":false,"id":"parse/1","title":"parse(SpecPath)"}]}],"sections":[],"title":"erf_parser_oas_3_0"},{"deprecated":false,"group":"","id":"erf_postprocess_middleware","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"callbacks","name":"Callbacks","nodes":[{"anchor":"c:postprocess/2","deprecated":false,"id":"postprocess/2","title":"postprocess/2"}]}],"sections":[],"title":"erf_postprocess_middleware"},{"deprecated":false,"group":"","id":"erf_preprocess_middleware","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"callbacks","name":"Callbacks","nodes":[{"anchor":"c:preprocess/1","deprecated":false,"id":"preprocess/1","title":"preprocess/1"}]}],"sections":[],"title":"erf_preprocess_middleware"},{"deprecated":false,"group":"","id":"erf_router","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:callback/0","deprecated":false,"id":"callback/0","title":"callback/0"},{"anchor":"t:generator_opts/0","deprecated":false,"id":"generator_opts/0","title":"generator_opts/0"},{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"generate/2","deprecated":false,"id":"generate/2","title":"generate(API, Opts)"},{"anchor":"handle/2","deprecated":false,"id":"handle/2","title":"handle(Name, Request)"},{"anchor":"load/1","deprecated":false,"id":"load/1","title":"load(Router)"}]}],"sections":[],"title":"erf_router"},{"deprecated":false,"group":"","id":"erf_static","nodeGroups":[{"key":"functions","name":"Functions","nodes":[{"anchor":"mime_type/1","deprecated":false,"id":"mime_type/1","title":"mime_type(Extension)"}]}],"sections":[],"title":"erf_static"},{"deprecated":false,"group":"","id":"erf_util","nodeGroups":[{"key":"functions","name":"Functions","nodes":[{"anchor":"to_pascal_case/1","deprecated":false,"id":"to_pascal_case/1","title":"to_pascal_case(BinOrStr)"},{"anchor":"to_snake_case/1","deprecated":false,"id":"to_snake_case/1","title":"to_snake_case(BinOrStr)"}]}],"sections":[],"title":"erf_util"}],"tasks":[]} \ No newline at end of file diff --git a/dist/sidebar_items-CD0FFEC6.js b/dist/sidebar_items-CD0FFEC6.js deleted file mode 100644 index 71ff4a7..0000000 --- a/dist/sidebar_items-CD0FFEC6.js +++ /dev/null @@ -1 +0,0 @@ -sidebarNodes={"extras":[{"group":"","headers":[{"anchor":"modules","id":"Modules"}],"id":"api-reference","title":"API Reference"},{"group":"","headers":[{"anchor":"what-is-design-first","id":"What is design-first?"},{"anchor":"how-does-erf-help-developing-design-first-restful-services","id":"How does erf help developing design-first RESTful services?"},{"anchor":"quickstart","id":"Quickstart"},{"anchor":"erf-configuration","id":"erf configuration"},{"anchor":"callback-modules-middlewares","id":"Callback modules & middlewares"},{"anchor":"hot-configuration-reloading","id":"Hot-configuration reloading"},{"anchor":"static-routes","id":"Static routes"},{"anchor":"troubleshooting","id":"Troubleshooting"},{"anchor":"specification-constraints","id":"Specification constraints"},{"anchor":"contributing","id":"Contributing"},{"anchor":"support","id":"Support"},{"anchor":"license","id":"License"}],"id":"readme","title":"Overview"},{"group":"","headers":[{"anchor":"table-of-contents","id":"Table of Contents"},{"anchor":"doubts-or-questions","id":"Doubts or questions"},{"anchor":"documentation","id":"Documentation"},{"anchor":"bug-reports","id":"Bug reports"},{"anchor":"feature-requests","id":"Feature requests"},{"anchor":"development","id":"Development"}],"id":"contributing","title":"Contributing"},{"group":"","headers":[],"id":"license","title":"License"}],"modules":[{"deprecated":false,"group":"","id":"erf","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:api/0","deprecated":false,"id":"api/0","title":"api/0"},{"anchor":"t:body/0","deprecated":false,"id":"body/0","title":"body/0"},{"anchor":"t:conf/0","deprecated":false,"id":"conf/0","title":"conf/0"},{"anchor":"t:header/0","deprecated":false,"id":"header/0","title":"header/0"},{"anchor":"t:method/0","deprecated":false,"id":"method/0","title":"method/0"},{"anchor":"t:path_parameter/0","deprecated":false,"id":"path_parameter/0","title":"path_parameter/0"},{"anchor":"t:query_parameter/0","deprecated":false,"id":"query_parameter/0","title":"query_parameter/0"},{"anchor":"t:request/0","deprecated":false,"id":"request/0","title":"request/0"},{"anchor":"t:response/0","deprecated":false,"id":"response/0","title":"response/0"},{"anchor":"t:static_dir/0","deprecated":false,"id":"static_dir/0","title":"static_dir/0"},{"anchor":"t:static_file/0","deprecated":false,"id":"static_file/0","title":"static_file/0"},{"anchor":"t:static_route/0","deprecated":false,"id":"static_route/0","title":"static_route/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"get_router/1","deprecated":false,"id":"get_router/1","title":"get_router(Name)"},{"anchor":"init/1","deprecated":false,"id":"init/1","title":"init(_)"},{"anchor":"reload_conf/2","deprecated":false,"id":"reload_conf/2","title":"reload_conf(Name, Conf)"},{"anchor":"start_link/1","deprecated":false,"id":"start_link/1","title":"start_link(Conf)"},{"anchor":"stop/1","deprecated":false,"id":"stop/1","title":"stop(Name)"}]}],"sections":[],"title":"erf"},{"deprecated":false,"group":"","id":"erf_conf","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"clear/1","deprecated":false,"id":"clear/1","title":"clear(Name)"},{"anchor":"get/1","deprecated":false,"id":"get/1","title":"get(Name)"},{"anchor":"log_level/1","deprecated":false,"id":"log_level/1","title":"log_level(Name)"},{"anchor":"postprocess_middlewares/1","deprecated":false,"id":"postprocess_middlewares/1","title":"postprocess_middlewares(Name)"},{"anchor":"preprocess_middlewares/1","deprecated":false,"id":"preprocess_middlewares/1","title":"preprocess_middlewares(Name)"},{"anchor":"router/1","deprecated":false,"id":"router/1","title":"router(Name)"},{"anchor":"router_mod/1","deprecated":false,"id":"router_mod/1","title":"router_mod(Name)"},{"anchor":"set/2","deprecated":false,"id":"set/2","title":"set(Name, Conf)"}]}],"sections":[],"title":"erf_conf"},{"deprecated":false,"group":"","id":"erf_parser","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:api/0","deprecated":false,"id":"api/0","title":"api/0"},{"anchor":"t:body/0","deprecated":false,"id":"body/0","title":"body/0"},{"anchor":"t:endpoint/0","deprecated":false,"id":"endpoint/0","title":"endpoint/0"},{"anchor":"t:method/0","deprecated":false,"id":"method/0","title":"method/0"},{"anchor":"t:operation/0","deprecated":false,"id":"operation/0","title":"operation/0"},{"anchor":"t:parameter/0","deprecated":false,"id":"parameter/0","title":"parameter/0"},{"anchor":"t:parameter_name/0","deprecated":false,"id":"parameter_name/0","title":"parameter_name/0"},{"anchor":"t:parameter_type/0","deprecated":false,"id":"parameter_type/0","title":"parameter_type/0"},{"anchor":"t:path/0","deprecated":false,"id":"path/0","title":"path/0"},{"anchor":"t:ref/0","deprecated":false,"id":"ref/0","title":"ref/0"},{"anchor":"t:request/0","deprecated":false,"id":"request/0","title":"request/0"},{"anchor":"t:response/0","deprecated":false,"id":"response/0","title":"response/0"},{"anchor":"t:schema/0","deprecated":false,"id":"schema/0","title":"schema/0"},{"anchor":"t:status_code/0","deprecated":false,"id":"status_code/0","title":"status_code/0"}]},{"key":"callbacks","name":"Callbacks","nodes":[{"anchor":"c:parse/1","deprecated":false,"id":"parse/1","title":"parse/1"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"parse/2","deprecated":false,"id":"parse/2","title":"parse(SpecPath, SpecParser)"}]}],"sections":[],"title":"erf_parser"},{"deprecated":false,"group":"","id":"erf_parser_oas_3_0","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:ctx/0","deprecated":false,"id":"ctx/0","title":"ctx/0"},{"anchor":"t:spec/0","deprecated":false,"id":"spec/0","title":"spec/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"parse/1","deprecated":false,"id":"parse/1","title":"parse(SpecPath)"}]}],"sections":[],"title":"erf_parser_oas_3_0"},{"deprecated":false,"group":"","id":"erf_postprocess_middleware","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"callbacks","name":"Callbacks","nodes":[{"anchor":"c:postprocess/2","deprecated":false,"id":"postprocess/2","title":"postprocess/2"}]}],"sections":[],"title":"erf_postprocess_middleware"},{"deprecated":false,"group":"","id":"erf_preprocess_middleware","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"callbacks","name":"Callbacks","nodes":[{"anchor":"c:preprocess/1","deprecated":false,"id":"preprocess/1","title":"preprocess/1"}]}],"sections":[],"title":"erf_preprocess_middleware"},{"deprecated":false,"group":"","id":"erf_router","nodeGroups":[{"key":"types","name":"Types","nodes":[{"anchor":"t:callback/0","deprecated":false,"id":"callback/0","title":"callback/0"},{"anchor":"t:generator_opts/0","deprecated":false,"id":"generator_opts/0","title":"generator_opts/0"},{"anchor":"t:t/0","deprecated":false,"id":"t/0","title":"t/0"}]},{"key":"functions","name":"Functions","nodes":[{"anchor":"generate/2","deprecated":false,"id":"generate/2","title":"generate(API, Opts)"},{"anchor":"load/1","deprecated":false,"id":"load/1","title":"load(Router)"}]}],"sections":[],"title":"erf_router"},{"deprecated":false,"group":"","id":"erf_static","nodeGroups":[{"key":"functions","name":"Functions","nodes":[{"anchor":"mime_type/1","deprecated":false,"id":"mime_type/1","title":"mime_type(Extension)"}]}],"sections":[],"title":"erf_static"},{"deprecated":false,"group":"","id":"erf_util","nodeGroups":[{"key":"functions","name":"Functions","nodes":[{"anchor":"to_pascal_case/1","deprecated":false,"id":"to_pascal_case/1","title":"to_pascal_case(BinOrStr)"},{"anchor":"to_snake_case/1","deprecated":false,"id":"to_snake_case/1","title":"to_snake_case(BinOrStr)"}]}],"sections":[],"title":"erf_util"}],"tasks":[]} \ No newline at end of file diff --git a/erf.html b/erf.html index ed0fb9b..b3440b3 100644 --- a/erf.html +++ b/erf.html @@ -4,20 +4,19 @@ - + erf — erf v0.1.2 - + - + - - + @@ -383,25 +382,19 @@

conf/0

-type conf() ::
-          #{spec_path := binary(),
-            callback := module(),
-            port => inet:port_number(),
-            name => atom(),
-            spec_parser => module(),
-            preprocess_middlewares => [module()],
-            postprocess_middlewares => [module()],
-            ssl => boolean(),
-            certfile => binary(),
-            keyfile => binary(),
+          #{spec_path := binary(),
+            callback := module(),
+            port => inet:port_number(),
+            name => atom(),
+            spec_parser => module(),
+            preprocess_middlewares => [module()],
+            postprocess_middlewares => [module()],
+            ssl => boolean(),
+            certfile => binary(),
+            keyfile => binary(),
             static_routes => [static_route()],
-            swagger_ui => boolean(),
-            min_acceptors => pos_integer(),
-            accept_timeout => pos_integer(),
-            request_timeout => pos_integer(),
-            header_timeout => pos_integer(),
-            body_timeout => pos_integer(),
-            max_body_size => pos_integer(),
-            log_level => logger:level()}.
+ swagger_ui => boolean(), + log_level => logger:level()}.
@@ -417,7 +410,7 @@

conf/0

header/0

- + View Source @@ -429,7 +422,7 @@

header/0

-
-type header() :: {binary(), binary()}.
+
-type header() :: {binary(), binary()}.
@@ -445,7 +438,7 @@

header/0

method/0

- + View Source @@ -473,7 +466,7 @@

method/0

path_parameter/0

- + View Source @@ -485,7 +478,7 @@

path_parameter/0

-
-type path_parameter() :: {binary(), binary()}.
+
-type path_parameter() :: {binary(), binary()}.
@@ -501,7 +494,7 @@

path_parameter/0

query_parameter/0

- + View Source @@ -513,7 +506,7 @@

query_parameter/0

-
-type query_parameter() :: {binary(), binary()}.
+
-type query_parameter() :: {binary(), binary()}.
@@ -529,7 +522,7 @@

query_parameter/0

request/0

- + View Source @@ -542,17 +535,17 @@

request/0

-type request() ::
-          #{scheme := undefined | binary(),
-            host := undefined | binary(),
+          #{scheme := undefined | binary(),
+            host := undefined | binary(),
             port := undefined | 1..65535,
-            path := [binary()],
+            path := [binary()],
             path_parameters => [path_parameter()],
             method := method(),
             query_parameters := [query_parameter()],
             headers := [header()],
             body := body(),
-            peer := undefined | binary(),
-            context => any()}.
+ peer := undefined | binary(), + context => any()}.
@@ -568,7 +561,7 @@

request/0

response/0

- + View Source @@ -581,7 +574,7 @@

response/0

-type response() ::
-          {StatusCode :: pos_integer(), Headers :: [header()], Body :: body() | {file, binary()}}.
+ {StatusCode :: pos_integer(), Headers :: [header()], Body :: body() | {file, binary()}}.
@@ -597,7 +590,7 @@

response/0

static_dir/0

- + View Source @@ -609,7 +602,7 @@

static_dir/0

-
-type static_dir() :: {dir, binary()}.
+
-type static_dir() :: {dir, binary()}.
@@ -625,7 +618,7 @@

static_dir/0

static_file/0

- + View Source @@ -637,7 +630,7 @@

static_file/0

-
-type static_file() :: {file, binary()}.
+
-type static_file() :: {file, binary()}.
@@ -653,7 +646,7 @@

static_file/0

static_route/0

- + View Source @@ -665,7 +658,7 @@

static_route/0

-
-type static_route() :: {Path :: binary(), Resource :: static_file() | static_dir()}.
+
-type static_route() :: {Path :: binary(), Resource :: static_file() | static_dir()}.
@@ -693,7 +686,7 @@

get_router(Name)

- + View Source @@ -707,10 +700,10 @@

get_router(Name)

-spec get_router(Name) -> Result
                     when
-                        Name :: atom(),
+                        Name :: atom(),
                         Result :: {ok, Router} | {error, Reason},
-                        Router :: binary(),
-                        Reason :: term().
+ Router :: binary(), + Reason :: term(). @@ -726,7 +719,7 @@

get_router(Name)

init(_)

- + View Source @@ -748,7 +741,7 @@

init(_)

reload_conf(Name, Conf)

- + View Source @@ -762,10 +755,10 @@

reload_conf(Name, Conf)

-spec reload_conf(Name, Conf) -> Result
                      when
-                         Name :: atom(),
+                         Name :: atom(),
                          Conf :: erf_conf:t(),
                          Result :: ok | {error, Reason},
-                         Reason :: term().
+ Reason :: term(). @@ -781,7 +774,7 @@

reload_conf(Name, Conf)

start_link(Conf)

- + View Source @@ -797,8 +790,8 @@

start_link(Conf)

when Conf :: conf(), Result :: {ok, Pid} | ignore | {error, Reason}, - Pid :: pid(), - Reason :: term(). + Pid :: pid(), + Reason :: term(). @@ -814,7 +807,7 @@

start_link(Conf)

stop(Name)

- + View Source @@ -826,7 +819,7 @@

stop(Name)

-
-spec stop(Name) -> Result when Name :: atom(), Result :: ok | {error, Reason}, Reason :: term().
+
-spec stop(Name) -> Result when Name :: atom(), Result :: ok | {error, Reason}, Reason :: term().
@@ -857,7 +850,7 @@

stop(Name)

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -868,6 +861,5 @@

stop(Name)

- diff --git a/erf_conf.html b/erf_conf.html index a67c565..bc58ccf 100644 --- a/erf_conf.html +++ b/erf_conf.html @@ -4,20 +4,19 @@ - + erf_conf — erf v0.1.2 - + - + - - + @@ -271,16 +270,16 @@

t/0

-type t() ::
-          #{callback => module(),
-            log_level => logger:level(),
-            preprocess_middlewares => [module()],
-            postprocess_middlewares => [module()],
+          #{callback => module(),
+            log_level => logger:level(),
+            preprocess_middlewares => [module()],
+            postprocess_middlewares => [module()],
             router => erl_syntax:syntaxTree(),
-            router_mod => module(),
-            spec_path => binary(),
-            spec_parser => module(),
+            router_mod => module(),
+            spec_path => binary(),
+            spec_parser => module(),
             static_routes => [erf:static_route()],
-            swagger_ui => boolean()}.
+ swagger_ui => boolean()}.
@@ -320,7 +319,7 @@

clear(Name)

-
-spec clear(Name) -> Result when Name :: atom(), Result :: ok.
+
-spec clear(Name) -> Result when Name :: atom(), Result :: ok.
@@ -348,7 +347,7 @@

get(Name)

-
-spec get(Name) -> Result when Name :: atom(), Result :: {ok, Conf} | {error, not_found}, Conf :: t().
+
-spec get(Name) -> Result when Name :: atom(), Result :: {ok, Conf} | {error, not_found}, Conf :: t().
@@ -378,9 +377,9 @@

log_level(Name)

-spec log_level(Name) -> Result
                    when
-                       Name :: atom(),
+                       Name :: atom(),
                        Result :: {ok, LogLevel} | {error, not_found},
-                       LogLevel :: logger:level().
+ LogLevel :: logger:level(). @@ -410,9 +409,9 @@

postprocess_middlewares(Name)

-spec postprocess_middlewares(Name) -> Result
                                  when
-                                     Name :: atom(),
+                                     Name :: atom(),
                                      Result :: {ok, PostprocessMiddlewares} | {error, not_found},
-                                     PostprocessMiddlewares :: [module()].
+ PostprocessMiddlewares :: [module()]. @@ -442,9 +441,9 @@

preprocess_middlewares(Name)

-spec preprocess_middlewares(Name) -> Result
                                 when
-                                    Name :: atom(),
+                                    Name :: atom(),
                                     Result :: {ok, PreprocessMiddlewares} | {error, not_found},
-                                    PreprocessMiddlewares :: [module()].
+ PreprocessMiddlewares :: [module()]. @@ -474,7 +473,7 @@

router(Name)

-spec router(Name) -> Result
                 when
-                    Name :: atom(),
+                    Name :: atom(),
                     Result :: {ok, Router} | {error, not_found},
                     Router :: erl_syntax:syntaxTree().
@@ -506,9 +505,9 @@

router_mod(Name)

-spec router_mod(Name) -> Result
                     when
-                        Name :: atom(),
+                        Name :: atom(),
                         Result :: {ok, RouterMod} | {error, not_found},
-                        RouterMod :: module().
+ RouterMod :: module(). @@ -536,7 +535,7 @@

set(Name, Conf)

-
-spec set(Name, Conf) -> Result when Name :: atom(), Conf :: t(), Result :: ok.
+
-spec set(Name, Conf) -> Result when Name :: atom(), Conf :: t(), Result :: ok.
@@ -567,7 +566,7 @@

set(Name, Conf)

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -578,6 +577,5 @@

set(Name, Conf)

- diff --git a/erf_http_server.html b/erf_http_server.html new file mode 100644 index 0000000..163503f --- /dev/null +++ b/erf_http_server.html @@ -0,0 +1,421 @@ + + + + + + + + + + + erf_http_server — erf v0.1.2 + + + + + + + + + + + + + +
+ + + + + +
+ + +
+ + +
+

+ + + + View Source + + + erf_http_server behaviour + (erf v0.1.2) + +

+ + +
+erf's interface to interact with its underlying HTTP server. +
+ +
+ +
+

+ + + + Summary +

+
+

+ Types +

+ +
+
+ conf/0 + +
+ +
+ +
+
+ extra_conf/0 + +
+ +
+ +
+
+ t/0 + +
+ +
+ +
+
+

+ Callbacks +

+ +
+
+ start_link/3 + +
+ +
+ +
+ + +
+ + +
+

+ + + + Types +

+
+
+ + + +
+ +
+ +
-type conf() ::
+          #{port => inet:port_number(), ssl => boolean(), certfile => binary(), keyfile => binary()}.
+ +
+ + +
+
+
+ + + +
+ +
+ +
-type extra_conf() :: term().
+ +
+ + +
+
+
+ + + +
+ +
+ +
-type t() :: module().
+ +
+ + +
+
+ +
+
+ +
+

+ + + + Callbacks +

+
+
+ + + +
+ +
+ +
-callback start_link(Name, Conf, ExtraConf) -> Result
+                        when
+                            Name :: atom(),
+                            Conf :: conf(),
+                            ExtraConf :: extra_conf(),
+                            Result :: supervisor:startlink_ret().
+ +
+ + +
+
+ +
+
+ +
+

+ + + + Functions +

+
+
+ +
+ + + Link to this function + +

start_link(Module, ModuleExtraConf, Name, Conf)

+ + + + View Source + + + +
+ +
+ +
+ +
-spec start_link(Module, ModuleExtraConf, Name, Conf) -> Result
+                    when
+                        Module :: module(),
+                        ModuleExtraConf :: extra_conf(),
+                        Name :: atom(),
+                        Conf :: conf(),
+                        Result :: supervisor:startlink_ret().
+ +
+ + +
+
+ +
+
+ + +
+
+
+ + + diff --git a/erf_http_server_elli.html b/erf_http_server_elli.html new file mode 100644 index 0000000..641c7aa --- /dev/null +++ b/erf_http_server_elli.html @@ -0,0 +1,294 @@ + + + + + + + + + + + erf_http_server_elli — erf v0.1.2 + + + + + + + + + + + + + +
+ + + + + +
+ + +
+ + +
+

+ + + + View Source + + + erf_http_server_elli + (erf v0.1.2) + +

+ + +
+An elli implementation for erf_http_server. +
+ +
+ +
+

+ + + + Summary +

+
+

+ Types +

+ +
+
+ extra_conf/0 + +
+ +
+ +
+
+

+ Functions +

+ + + +
+ +
+ + +
+

+ + + + Types +

+
+
+ + + +
+ +
+ +
-type extra_conf() ::
+          #{min_acceptors => pos_integer(),
+            accept_timeout => pos_integer(),
+            request_timeout => pos_integer(),
+            header_timeout => pos_integer(),
+            body_timeout => pos_integer(),
+            max_body_size => pos_integer()}.
+ +
+ + +
+
+ +
+
+ +
+

+ + + + Functions +

+
+
+ +
+ + + Link to this function + +

start_link(Name, Conf, ExtraConf)

+ + + + View Source + + + +
+ +
+ +
+ +
-spec start_link(Name, Conf, ExtraConf) -> Result
+                    when
+                        Name :: atom(),
+                        Conf :: erf_http_server:conf(),
+                        ExtraConf :: extra_conf(),
+                        Result :: supervisor:startlink_ret().
+ +
+ + +
+
+ +
+
+ + +
+
+
+ + + diff --git a/erf_parser.html b/erf_parser.html index 8d35778..dbfcd17 100644 --- a/erf_parser.html +++ b/erf_parser.html @@ -4,20 +4,19 @@ - + erf_parser — erf v0.1.2 - + - + - - + @@ -319,8 +318,8 @@

api/0

-type api() ::
-          #{name := binary(),
-            version := binary(),
+          #{name := binary(),
+            version := binary(),
             endpoints := [endpoint()],
             schemas := #{ref() => schema()}}.
@@ -350,7 +349,7 @@

body/0

-
-type body() :: #{ref := ref(), required := boolean()}.
+
-type body() :: #{ref := ref(), required := boolean()}.
@@ -435,7 +434,7 @@

operation/0

-type operation() ::
-          #{id := binary(),
+          #{id := binary(),
             method := method(),
             parameters := [parameter()],
             request := request(),
@@ -468,7 +467,7 @@ 

parameter/0

-type parameter() ::
-          #{ref := ref(), name := parameter_name(), type := parameter_type(), required := boolean()}.
+ #{ref := ref(), name := parameter_name(), type := parameter_type(), required := boolean()}.
@@ -496,7 +495,7 @@

parameter_name/0

-
-type parameter_name() :: binary().
+
-type parameter_name() :: binary().
@@ -552,7 +551,7 @@

path/0

-
-type path() :: binary().
+
-type path() :: binary().
@@ -580,7 +579,7 @@

ref/0

-
-type ref() :: binary().
+
-type ref() :: binary().
@@ -734,10 +733,10 @@

parse/1

-callback parse(SpecPath) -> Result
                    when
-                       SpecPath :: binary(),
+                       SpecPath :: binary(),
                        Result :: {ok, API} | {error, Reason},
                        API :: api(),
-                       Reason :: term().
+ Reason :: term().
@@ -779,11 +778,11 @@

parse(SpecPath, SpecParser)

-spec parse(SpecPath, SpecParser) -> Result
                when
-                   SpecPath :: binary(),
-                   SpecParser :: module(),
+                   SpecPath :: binary(),
+                   SpecParser :: module(),
                    Result :: {ok, API} | {error, Reason},
                    API :: api(),
-                   Reason :: term().
+ Reason :: term(). @@ -814,7 +813,7 @@

parse(SpecPath, SpecParser)

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -825,6 +824,5 @@

parse(SpecPath, SpecParser)

- diff --git a/erf_parser_oas_3_0.html b/erf_parser_oas_3_0.html index edeae94..e08f0b1 100644 --- a/erf_parser_oas_3_0.html +++ b/erf_parser_oas_3_0.html @@ -4,20 +4,19 @@ - + erf_parser_oas_3_0 — erf v0.1.2 - + - + - - + @@ -209,10 +208,10 @@

ctx/0

-type ctx() ::
-          #{base_path := binary(),
-            base_name := binary(),
-            namespace := binary(),
-            resolved := [binary()],
+          #{base_path := binary(),
+            base_name := binary(),
+            namespace := binary(),
+            resolved := [binary()],
             spec := spec()}.
@@ -283,10 +282,10 @@

parse(SpecPath)

-spec parse(SpecPath) -> Result
                when
-                   SpecPath :: binary(),
+                   SpecPath :: binary(),
                    Result :: {ok, API} | {error, Reason},
                    API :: erf:api(),
-                   Reason :: term().
+ Reason :: term(). @@ -317,7 +316,7 @@

parse(SpecPath)

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -328,6 +327,5 @@

parse(SpecPath)

- diff --git a/erf_postprocess_middleware.html b/erf_postprocess_middleware.html index f4ae88f..eeaf100 100644 --- a/erf_postprocess_middleware.html +++ b/erf_postprocess_middleware.html @@ -4,20 +4,19 @@ - + erf_postprocess_middleware — erf v0.1.2 - + - + - - + @@ -200,7 +199,7 @@

t/0

-
-type t() :: module().
+
-type t() :: module().
@@ -275,7 +274,7 @@

postprocess/2

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -286,6 +285,5 @@

postprocess/2

- diff --git a/erf_preprocess_middleware.html b/erf_preprocess_middleware.html index 927e410..0d835dc 100644 --- a/erf_preprocess_middleware.html +++ b/erf_preprocess_middleware.html @@ -4,20 +4,19 @@ - + erf_preprocess_middleware — erf v0.1.2 - + - + - - + @@ -200,7 +199,7 @@

t/0

-
-type t() :: module().
+
-type t() :: module().
@@ -276,7 +275,7 @@

preprocess/1

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -287,6 +286,5 @@

preprocess/1

- diff --git a/erf_router.html b/erf_router.html index 4d00104..df04661 100644 --- a/erf_router.html +++ b/erf_router.html @@ -4,20 +4,19 @@ - + erf_router — erf v0.1.2 - + - + - - + @@ -178,6 +177,16 @@

+
+ + +
Handles an HTTP request.
+ +
+
load(Router) @@ -210,7 +219,7 @@

callback/0

- + View Source @@ -222,7 +231,7 @@

callback/0

-
-type callback() :: module().
+
-type callback() :: module().
@@ -238,7 +247,7 @@

callback/0

generator_opts/0

- + View Source @@ -266,7 +275,7 @@

generator_opts/0

t/0

- + View Source @@ -306,7 +315,7 @@

generate(API, Opts)

- + View Source @@ -323,7 +332,7 @@

generate(API, Opts)

API :: erf:api(), Opts :: generator_opts(), Result :: {Mod, Router}, - Mod :: module(), + Mod :: module(), Router :: t().
@@ -331,6 +340,35 @@

generate(API, Opts)

Generates an Erlang Syntax Tree of a router module from an API AST. +
+ +
+ + + Link to this function + +

handle(Name, Request)

+ + + + View Source + + + +
+ +
+ +
+ +
-spec handle(Name, Request) -> Result
+                when Name :: atom(), Request :: erf:request(), Result :: erf:response().
+ +
+ +Handles an HTTP request. +
+
@@ -340,7 +378,7 @@

generate(API, Opts)

load(Router)

- + View Source @@ -356,8 +394,8 @@

load(Router)

when Router :: t(), Result :: ok | {ok, Warnings} | error | {error, {Errors, Warnings}}, - Errors :: [term()], - Warnings :: [term()]. + Errors :: [term()], + Warnings :: [term()].
@@ -388,7 +426,7 @@

load(Router)

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -399,6 +437,5 @@

load(Router)

- diff --git a/erf_static.html b/erf_static.html index 86411b5..8c1113c 100644 --- a/erf_static.html +++ b/erf_static.html @@ -4,20 +4,19 @@ - + erf_static — erf v0.1.2 - + - + - - + @@ -186,7 +185,7 @@

mime_type(Extension)

-
-spec mime_type(Extension) -> MimeType when Extension :: binary(), MimeType :: binary().
+
-spec mime_type(Extension) -> MimeType when Extension :: binary(), MimeType :: binary().
@@ -217,7 +216,7 @@

mime_type(Extension)

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -228,6 +227,5 @@

mime_type(Extension)

- diff --git a/erf_util.html b/erf_util.html index 9e0d96d..66e245d 100644 --- a/erf_util.html +++ b/erf_util.html @@ -4,20 +4,19 @@ - + erf_util — erf v0.1.2 - + - + - - + @@ -193,7 +192,7 @@

to_pascal_case(BinOrStr)

-spec to_pascal_case(BinOrStr) -> PascalCase
-                        when BinOrStr :: binary() | string(), PascalCase :: binary().
+ when BinOrStr :: binary() | string(), PascalCase :: binary().
@@ -221,7 +220,7 @@

to_snake_case(BinOrStr)

-
-spec to_snake_case(BinOrStr) -> SnakeCase when BinOrStr :: binary() | string(), SnakeCase :: binary().
+
-spec to_snake_case(BinOrStr) -> SnakeCase when BinOrStr :: binary() | string(), SnakeCase :: binary().
@@ -252,7 +251,7 @@

to_snake_case(BinOrStr)

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -263,6 +262,5 @@

to_snake_case(BinOrStr)

- diff --git a/index.html b/index.html index 154ec7e..4ec781c 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ erf v0.1.2 — Documentation - + diff --git a/license.html b/license.html index d8f8110..aa0ab98 100644 --- a/license.html +++ b/license.html @@ -4,20 +4,19 @@ - + License — erf v0.1.2 - + - + - - + @@ -366,7 +365,7 @@

Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -377,6 +376,5 @@

- diff --git a/readme.html b/readme.html index 7de0d34..66a9671 100644 --- a/readme.html +++ b/readme.html @@ -4,20 +4,19 @@ - + Overview — erf v0.1.2 - + - + - - + @@ -141,88 +140,88 @@

Quickstart

-
  1. Design your API using OpenAPI 3.0. For example: users.openapi.json.

  2. Add erf as a dependency in your rebar3 project.

    {deps, [
    - {erf, {git, "git@github.com:nomasystems/erf.git", {branch, "main"}}}
    -]}.
  3. Implement a callback module for your API. A hypothetical example for users.openapi.json would be users_callback.erl.

    %% An <code>erf</code> callback for the users REST API.
    --module(users_callback).
    +
    1. Design your API using OpenAPI 3.0. For example: users.openapi.json.

    2. Add erf as a dependency in your rebar3 project.

      {deps, [
      + {erf, {git, "git@github.com:nomasystems/erf.git", {branch, "main"}}}
      +]}.
    3. Implement a callback module for your API. A hypothetical example for users.openapi.json would be users_callback.erl.

      %% An <code>erf</code> callback for the users REST API.
      +-module(users_callback).
       
       %%% EXTERNAL EXPORTS
      --export([
      +-export([
        create_user/1,
        get_user/1,
        delete_user/1
      -]).
      +]).
       
       %%%-------------------------------------------------------
       %%% EXTERNAL EXPORTS
       %%%-------------------------------------------------------
      -create_user(#{body := Body} = _Request) ->
      - Id = base64:encode(crypto:strong_rand_bytes(16)),
      - ets:insert(users, {Id, Body#{<<"id">> => Id}}),
      - {201, [], Body#{<<"id">> => Id}}.
      -
      -get_user(#{path_parameters := PathParameters} = _Request) ->
      - Id = proplists:get_value(<<"userId">>, PathParameters),
      - case ets:lookup(users, Id) of
      -     [] ->
      -         {404, [], #{
      +create_user(#{body := Body} = _Request) ->
      + Id = base64:encode(crypto:strong_rand_bytes(16)),
      + ets:insert(users, {Id, Body#{<<"id">> => Id}}),
      + {201, [], Body#{<<"id">> => Id}}.
      +
      +get_user(#{path_parameters := PathParameters} = _Request) ->
      + Id = proplists:get_value(<<"userId">>, PathParameters),
      + case ets:lookup(users, Id) of
      +     [] ->
      +         {404, [], #{
                    <<"message">> =>
                        <<"User ", Id/binary, " not found">>
      -         }};
      -     [{Id, User}] ->
      -         {200, [], User}
      +         }};
      +     [{Id, User}] ->
      +         {200, [], User}
        end.
       
      -delete_user(#{path_parameters := PathParameters} = _Request) ->
      - Id = proplists:get_value(<<"userId">>, PathParameters),
      - case ets:lookup(users, Id) of
      -     [] ->
      -         {404, [], #{
      +delete_user(#{path_parameters := PathParameters} = _Request) ->
      + Id = proplists:get_value(<<"userId">>, PathParameters),
      + case ets:lookup(users, Id) of
      +     [] ->
      +         {404, [], #{
                    <<"message">> =>
                        <<"User ", Id/binary, " not found">>
      -         }};
      -     [_User] ->
      -         ets:delete(users, Id),
      -         {204, [], #{<<"id">> => Id}}
      - end.
    4. Start an erf instance using the erf:start_link/1 function under the supervisor of your application. For example:

      -module(users_sup).
      +         }};
      +     [_User] ->
      +         ets:delete(users, Id),
      +         {204, [], #{<<"id">> => Id}}
      + end.
    5. Start an erf instance using the erf:start_link/1 function under the supervisor of your application. For example:

      -module(users_sup).
       
       %%% BEHAVIOURS
      --behaviour(supervisor).
      +-behaviour(supervisor).
       
       %%% START/STOP EXPORTS
      --export([start_link/0]).
      +-export([start_link/0]).
       
       %%% INTERNAL EXPORTS
      --export([init/1]).
      +-export([init/1]).
       
       %%%-------------------------------------------------------
       %%% START/STOP EXPORTS
       %%%-------------------------------------------------------
      -start_link() ->
      - supervisor:start_link({local, ?MODULE}, ?MODULE, []).
      +start_link() ->
      + supervisor:start_link({local, ?MODULE}, ?MODULE, []).
       
       %%%-------------------------------------------------------
       %%% INTERNAL EXPORTS
       %%%-------------------------------------------------------
      -init([]) ->
      +init([]) ->
        % Users storage
      - ets:new(users, [public, named_table]),
      - UsersAPIConf = #{
      + ets:new(users, [public, named_table]),
      + UsersAPIConf = #{
            spec_path => <<"priv/users.openapi.json">>,
            callback => users_callback,
      -     preprocess_middlewares => [users_preprocess],
      -     postprocess_middlewares => [users_postprocess],
      +     preprocess_middlewares => [users_preprocess],
      +     postprocess_middlewares => [users_postprocess],
            port => 8080
      - },
      - UsersChildSpec = {
      + },
      + UsersChildSpec = {
            public_api_server,
      -     {erf, start_link, [UsersAPIConf]},
      +     {erf, start_link, [UsersAPIConf]},
            permanent,
            5000,
            worker,
      -     [erf]
      - },
      - {ok, {{one_for_one, 5, 10}, [UsersChildSpec]}}.

      Notice the configured preprocess and postprocess middlewares. They implement a basic authorization mechanism, short-circuiting the request and returning a 403 HTTP error code if the X-API-KEY: api-key header is missing, and they print in console the time in microseconds that authorized requests take to complete.

    6. Start requesting your service.

      $ curl -vvv 'localhost:8080/users' -H 'Content-Type: application/json' -H 'X-API-KEY: api-key' -d '{"username": "foo", "password": "foobar"}'
      +     [erf]
      + },
      + {ok, {{one_for_one, 5, 10}, [UsersChildSpec]}}.

      Notice the configured preprocess and postprocess middlewares. They implement a basic authorization mechanism, short-circuiting the request and returning a 403 HTTP error code if the X-API-KEY: api-key header is missing, and they print in console the time in microseconds that authorized requests take to complete.

    7. Start requesting your service.

      $ curl -vvv 'localhost:8080/users' -H 'Content-Type: application/json' -H 'X-API-KEY: api-key' -d '{"username": "foo", "password": "foobar"}'
       *   Trying 127.0.0.1:8080...
       * Connected to localhost (127.0.0.1) port 8080 (#0)
       > POST /users HTTP/1.1
      @@ -246,27 +245,27 @@ 

      erf configuration

      erf's main entry point (i.e., the start_link/1 function) receives an API specification, a callback module and a set of optional values that enable its configuration.

      The configuration is provided as map with the following type spec:

      %%% erf.erl
      --type conf() :: #{
      -    spec_path := binary(),
      -    callback := module(),
      -    port => inet:port_number(),
      -    name => atom(),
      -    spec_parser => module(),
      -    preprocess_middlewares => [module()],
      -    postprocess_middlewares => [module()],
      -    ssl => boolean(),
      -    certfile => binary(),
      -    keyfile => binary(),
      -    static_routes => [static_route()],
      -    swagger_ui => boolean(),
      -    min_acceptors => pos_integer(),
      -    accept_timeout => pos_integer(),
      -    request_timeout => pos_integer(),
      -    header_timeout => pos_integer(),
      -    body_timeout => pos_integer(),
      -    max_body_size => pos_integer(),
      -    log_level => logger:level()
      -}.

      A detailed description of each parameter can be found in the following list:

      • spec_path : Path to API specification file.
      • callback: Name of the callback module.
      • port: Port the server will listen to. Defaults to 8080.
      • name: Name under which the server is registered. Defaults to erf.
      • spec_parser: Name of the specification parser module. Defaults to erf_parser_oas_3_0.
      • preprocess_middlewares: List of names of middlewares to be invoked before the request is forwarded to the callback. Defaults to [].
      • postprocess_middlewares: List of names of middlewares to be invoked after the response is returned by the callback. Defaults to [].
      • ssl: Boolean flag that enables/disables SSL. Defaults to false.
      • certfile: Path to the SSL certificate file. Defaults to undefined.
      • keyfile: Path to the SSL key file. Defaults to undefined.
      • static_routes: List of routes that serve static files. Defaults to [].
      • swagger_ui: Boolean flag that enables/disables the Swagger UI. Defaults to false.
      • min_acceptors: Minimum number of acceptor processes. Defaults to 20.
      • accept_timeout: Timeout in ms for accepting an incoming request. Defaults to 10000.
      • request_timeout: Timeout in ms for receiving more packets when waiting for the request line. Defaults to 60000.
      • header_timeout: Timeout in ms for receiving more packets when waiting for the headers. Defaults to 10000.
      • body_timeout: Timeout in ms for receiving more packets when waiting for the body. Defaults to 30000.
      • max_body_size: Maximum size in bytes for the body of allowed received messages. Defaults to 1024000.
      • log_level: Severity associated to logged messages. Defaults to error.

      +-type conf() :: #{ + spec_path := binary(), + callback := module(), + port => inet:port_number(), + name => atom(), + spec_parser => module(), + preprocess_middlewares => [module()], + postprocess_middlewares => [module()], + ssl => boolean(), + certfile => binary(), + keyfile => binary(), + static_routes => [static_route()], + swagger_ui => boolean(), + min_acceptors => pos_integer(), + accept_timeout => pos_integer(), + request_timeout => pos_integer(), + header_timeout => pos_integer(), + body_timeout => pos_integer(), + max_body_size => pos_integer(), + log_level => logger:level() +}.

      A detailed description of each parameter can be found in the following list:

      • spec_path : Path to API specification file.
      • callback: Name of the callback module.
      • port: Port the server will listen to. Defaults to 8080.
      • name: Name under which the server is registered. Defaults to erf.
      • spec_parser: Name of the specification parser module. Defaults to erf_parser_oas_3_0.
      • preprocess_middlewares: List of names of middlewares to be invoked before the request is forwarded to the callback. Defaults to [].
      • postprocess_middlewares: List of names of middlewares to be invoked after the response is returned by the callback. Defaults to [].
      • ssl: Boolean flag that enables/disables SSL. Defaults to false.
      • certfile: Path to the SSL certificate file. Defaults to undefined.
      • keyfile: Path to the SSL key file. Defaults to undefined.
      • static_routes: List of routes that serve static files. Defaults to [].
      • swagger_ui: Boolean flag that enables/disables the Swagger UI. Defaults to false.
      • min_acceptors: Minimum number of acceptor processes. Defaults to 20.
      • accept_timeout: Timeout in ms for accepting an incoming request. Defaults to 10000.
      • request_timeout: Timeout in ms for receiving more packets when waiting for the request line. Defaults to 60000.
      • header_timeout: Timeout in ms for receiving more packets when waiting for the headers. Defaults to 10000.
      • body_timeout: Timeout in ms for receiving more packets when waiting for the body. Defaults to 30000.
      • max_body_size: Maximum size in bytes for the body of allowed received messages. Defaults to 1024000.
      • log_level: Severity associated to logged messages. Defaults to error.

      @@ -280,27 +279,27 @@

      Hot-configuration reloading

      The design principles behind erf allow its instances to be reconfigured in runtime with no needed downtime. While not every configuration key is updatable once the server is started (e.g., the port), some interesting features of the framework can be updated on-the-fly.

      The following type spec corresponds to the runtime configuration of an erf instance. At the same time, is the type spec of the second argument for the erf:reload/2 function.

      %%% erf_conf.erl
      --type t() :: #{
      -    callback => module(),
      -    log_level => logger:level(),
      -    preprocess_middlewares => [module()],
      -    postprocess_middlewares => [module()],
      -    router => erl_syntax:syntaxTree(), % not manually updatable
      -    router_mod => module(), % not manually updatable
      -    spec_path => binary(),
      -    spec_parser => module(),
      -    static_routes => [erf:static_route()],
      -    swagger_ui => boolean()
      -}.

      NOTE: the router and router_mod keys are not updatable as they are automatically computed when new configuration is provided.

      +-type t() :: #{ + callback => module(), + log_level => logger:level(), + preprocess_middlewares => [module()], + postprocess_middlewares => [module()], + router => erl_syntax:syntaxTree(), % not manually updatable + router_mod => module(), % not manually updatable + spec_path => binary(), + spec_parser => module(), + static_routes => [erf:static_route()], + swagger_ui => boolean() +}.

    NOTE: the router and router_mod keys are not updatable as they are automatically computed when new configuration is provided.

    Static routes

    As shown in erf configuration, the server supports routes that serve static files. The type spec for static routes is the following:

    %%% erf.erl
    --type static_dir() :: {dir, binary()}.
    --type static_file() :: {file, binary()}.
    --type static_route() :: {Path :: binary(), Resource :: static_file() | static_dir()}.

    This feature enables erf to serve a Swagger UI version with your API specification. Just set the swagger_ui flag to true and open your web browser in the server host under the /swagger path.

    +-type static_dir() :: {dir, binary()}. +-type static_file() :: {file, binary()}. +-type static_route() :: {Path :: binary(), Resource :: static_file() | static_dir()}.

    This feature enables erf to serve a Swagger UI version with your API specification. Just set the swagger_ui flag to true and open your web browser in the server host under the /swagger path.

    @@ -393,7 +392,7 @@

    Built using - ExDoc (v0.32.2) for the + ExDoc (v0.34.2) for the Erlang programming language @@ -404,6 +403,5 @@

    - diff --git a/search.html b/search.html index 73502f6..a5be02e 100644 --- a/search.html +++ b/search.html @@ -4,22 +4,21 @@ - + Search — erf v0.1.2 - + - + - - + @@ -119,7 +118,7 @@

    - +