diff --git a/404.html b/404.html index 58dd744..d8be9eb 100644 --- a/404.html +++ b/404.html @@ -15,7 +15,7 @@ - + @@ -23,10 +23,10 @@ - + - + @@ -306,6 +306,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -408,9 +426,13 @@ -
  • + + + + + +
  • - @@ -418,7 +440,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -657,7 +688,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -726,9 +810,13 @@ -
  • + + + + + +
  • - @@ -736,7 +824,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1238,13 +1335,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1266,31 +1389,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1505,10 +1693,10 @@

    404 - Not found

    + + + Back to top + @@ -1588,6 +1776,7 @@

    404 - Not found

    + - + - + diff --git a/about/index.html b/about/index.html index 5a4c77e..f455e59 100644 --- a/about/index.html +++ b/about/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -431,9 +449,13 @@ -
  • + + + + + +
  • - @@ -441,7 +463,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -680,7 +711,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -749,9 +833,13 @@ -
  • + + + + + +
  • - @@ -759,7 +847,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1261,13 +1358,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1289,31 +1412,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1590,10 +1778,10 @@

    About This Site

    + + + Back to top + @@ -1673,6 +1861,7 @@

    About This Site

    + - + - + diff --git a/assets/javascripts/bundle.1c5acf9f.min.js b/assets/javascripts/bundle.1c5acf9f.min.js deleted file mode 100644 index a098232..0000000 --- a/assets/javascripts/bundle.1c5acf9f.min.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict";(()=>{var _i=Object.create;var Or=Object.defineProperty;var Ai=Object.getOwnPropertyDescriptor;var Ci=Object.getOwnPropertyNames,zt=Object.getOwnPropertySymbols,ki=Object.getPrototypeOf,Mr=Object.prototype.hasOwnProperty,so=Object.prototype.propertyIsEnumerable;var ao=(e,t,r)=>t in e?Or(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,j=(e,t)=>{for(var r in t||(t={}))Mr.call(t,r)&&ao(e,r,t[r]);if(zt)for(var r of zt(t))so.call(t,r)&&ao(e,r,t[r]);return e};var co=(e,t)=>{var r={};for(var o in e)Mr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&zt)for(var o of zt(e))t.indexOf(o)<0&&so.call(e,o)&&(r[o]=e[o]);return r};var Lr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Hi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ci(t))!Mr.call(e,n)&&n!==r&&Or(e,n,{get:()=>t[n],enumerable:!(o=Ai(t,n))||o.enumerable});return e};var Kt=(e,t,r)=>(r=e!=null?_i(ki(e)):{},Hi(t||!e||!e.__esModule?Or(r,"default",{value:e,enumerable:!0}):r,e));var lo=Lr((_r,po)=>{(function(e,t){typeof _r=="object"&&typeof po!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(_r,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(C){return!!(C&&C!==document&&C.nodeName!=="HTML"&&C.nodeName!=="BODY"&&"classList"in C&&"contains"in C.classList)}function p(C){var et=C.type,H=C.tagName;return!!(H==="INPUT"&&a[et]&&!C.readOnly||H==="TEXTAREA"&&!C.readOnly||C.isContentEditable)}function c(C){C.classList.contains("focus-visible")||(C.classList.add("focus-visible"),C.setAttribute("data-focus-visible-added",""))}function l(C){C.hasAttribute("data-focus-visible-added")&&(C.classList.remove("focus-visible"),C.removeAttribute("data-focus-visible-added"))}function f(C){C.metaKey||C.altKey||C.ctrlKey||(s(r.activeElement)&&c(r.activeElement),o=!0)}function u(C){o=!1}function d(C){s(C.target)&&(o||p(C.target))&&c(C.target)}function b(C){s(C.target)&&(C.target.classList.contains("focus-visible")||C.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(C.target))}function M(C){document.visibilityState==="hidden"&&(n&&(o=!0),ee())}function ee(){document.addEventListener("mousemove",B),document.addEventListener("mousedown",B),document.addEventListener("mouseup",B),document.addEventListener("pointermove",B),document.addEventListener("pointerdown",B),document.addEventListener("pointerup",B),document.addEventListener("touchmove",B),document.addEventListener("touchstart",B),document.addEventListener("touchend",B)}function re(){document.removeEventListener("mousemove",B),document.removeEventListener("mousedown",B),document.removeEventListener("mouseup",B),document.removeEventListener("pointermove",B),document.removeEventListener("pointerdown",B),document.removeEventListener("pointerup",B),document.removeEventListener("touchmove",B),document.removeEventListener("touchstart",B),document.removeEventListener("touchend",B)}function B(C){C.target.nodeName&&C.target.nodeName.toLowerCase()==="html"||(o=!1,re())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",M,!0),ee(),r.addEventListener("focus",d,!0),r.addEventListener("blur",b,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var Zr=Lr((jt,Xr)=>{(function(t,r){typeof jt=="object"&&typeof Xr=="object"?Xr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof jt=="object"?jt.ClipboardJS=r():t.ClipboardJS=r()})(jt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Li}});var a=i(279),s=i.n(a),p=i(370),c=i.n(p),l=i(817),f=i.n(l);function u(D){try{return document.execCommand(D)}catch(_){return!1}}var d=function(_){var L=f()(_);return u("cut"),L},b=d;function M(D){var _=document.documentElement.getAttribute("dir")==="rtl",L=document.createElement("textarea");L.style.fontSize="12pt",L.style.border="0",L.style.padding="0",L.style.margin="0",L.style.position="absolute",L.style[_?"right":"left"]="-9999px";var F=window.pageYOffset||document.documentElement.scrollTop;return L.style.top="".concat(F,"px"),L.setAttribute("readonly",""),L.value=D,L}var ee=function(_,L){var F=M(_);L.container.appendChild(F);var N=f()(F);return u("copy"),F.remove(),N},re=function(_){var L=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},F="";return typeof _=="string"?F=ee(_,L):_ instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(_==null?void 0:_.type)?F=ee(_.value,L):(F=f()(_),u("copy")),F},B=re;function C(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?C=function(L){return typeof L}:C=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},C(D)}var et=function(){var _=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},L=_.action,F=L===void 0?"copy":L,N=_.container,Y=_.target,Pe=_.text;if(F!=="copy"&&F!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Y!==void 0)if(Y&&C(Y)==="object"&&Y.nodeType===1){if(F==="copy"&&Y.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(F==="cut"&&(Y.hasAttribute("readonly")||Y.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Pe)return B(Pe,{container:N});if(Y)return F==="cut"?b(Y):B(Y,{container:N})},H=et;function Q(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Q=function(L){return typeof L}:Q=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},Q(D)}function se(D,_){if(!(D instanceof _))throw new TypeError("Cannot call a class as a function")}function ue(D,_){for(var L=0;L<_.length;L++){var F=_[L];F.enumerable=F.enumerable||!1,F.configurable=!0,"value"in F&&(F.writable=!0),Object.defineProperty(D,F.key,F)}}function we(D,_,L){return _&&ue(D.prototype,_),L&&ue(D,L),D}function Ye(D,_){if(typeof _!="function"&&_!==null)throw new TypeError("Super expression must either be null or a function");D.prototype=Object.create(_&&_.prototype,{constructor:{value:D,writable:!0,configurable:!0}}),_&&Sr(D,_)}function Sr(D,_){return Sr=Object.setPrototypeOf||function(F,N){return F.__proto__=N,F},Sr(D,_)}function wi(D){var _=Oi();return function(){var F=Dt(D),N;if(_){var Y=Dt(this).constructor;N=Reflect.construct(F,arguments,Y)}else N=F.apply(this,arguments);return Si(this,N)}}function Si(D,_){return _&&(Q(_)==="object"||typeof _=="function")?_:Ti(D)}function Ti(D){if(D===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return D}function Oi(){if(typeof Reflect=="undefined"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(D){return!1}}function Dt(D){return Dt=Object.setPrototypeOf?Object.getPrototypeOf:function(L){return L.__proto__||Object.getPrototypeOf(L)},Dt(D)}function Tr(D,_){var L="data-clipboard-".concat(D);if(_.hasAttribute(L))return _.getAttribute(L)}var Mi=function(D){Ye(L,D);var _=wi(L);function L(F,N){var Y;return se(this,L),Y=_.call(this),Y.resolveOptions(N),Y.listenClick(F),Y}return we(L,[{key:"resolveOptions",value:function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof N.action=="function"?N.action:this.defaultAction,this.target=typeof N.target=="function"?N.target:this.defaultTarget,this.text=typeof N.text=="function"?N.text:this.defaultText,this.container=Q(N.container)==="object"?N.container:document.body}},{key:"listenClick",value:function(N){var Y=this;this.listener=c()(N,"click",function(Pe){return Y.onClick(Pe)})}},{key:"onClick",value:function(N){var Y=N.delegateTarget||N.currentTarget,Pe=this.action(Y)||"copy",Vt=H({action:Pe,container:this.container,target:this.target(Y),text:this.text(Y)});this.emit(Vt?"success":"error",{action:Pe,text:Vt,trigger:Y,clearSelection:function(){Y&&Y.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(N){return Tr("action",N)}},{key:"defaultTarget",value:function(N){var Y=Tr("target",N);if(Y)return document.querySelector(Y)}},{key:"defaultText",value:function(N){return Tr("text",N)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(N){var Y=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return B(N,Y)}},{key:"cut",value:function(N){return b(N)}},{key:"isSupported",value:function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Y=typeof N=="string"?[N]:N,Pe=!!document.queryCommandSupported;return Y.forEach(function(Vt){Pe=Pe&&!!document.queryCommandSupported(Vt)}),Pe}}]),L}(s()),Li=Mi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,p){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(p))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,d,b){var M=c.apply(this,arguments);return l.addEventListener(u,M,b),{destroy:function(){l.removeEventListener(u,M,b)}}}function p(l,f,u,d,b){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(M){return s(M,f,u,d,b)}))}function c(l,f,u,d){return function(b){b.delegateTarget=a(b.target,f),b.delegateTarget&&d.call(l,b)}}o.exports=p},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function p(u,d,b){if(!u&&!d&&!b)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(b))throw new TypeError("Third argument must be a Function");if(a.node(u))return c(u,d,b);if(a.nodeList(u))return l(u,d,b);if(a.string(u))return f(u,d,b);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(u,d,b){return u.addEventListener(d,b),{destroy:function(){u.removeEventListener(d,b)}}}function l(u,d,b){return Array.prototype.forEach.call(u,function(M){M.addEventListener(d,b)}),{destroy:function(){Array.prototype.forEach.call(u,function(M){M.removeEventListener(d,b)})}}}function f(u,d,b){return s(document.body,u,d,b)}o.exports=p},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var p=window.getSelection(),c=document.createRange();c.selectNodeContents(i),p.removeAllRanges(),p.addRange(c),a=p.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var p=this.e||(this.e={});return(p[i]||(p[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var p=this;function c(){p.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),p=0,c=s.length;for(p;p{"use strict";var Ua=/["'&<>]/;Yn.exports=Na;function Na(e){var t=""+e,r=Ua.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function K(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function q(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||s(u,d)})})}function s(u,d){try{p(o[u](d))}catch(b){f(i[0][3],b)}}function p(u){u.value instanceof ct?Promise.resolve(u.value.v).then(c,l):f(i[0][2],u)}function c(u){s("next",u)}function l(u){s("throw",u)}function f(u,d){u(d),i.shift(),i.length&&s(i[0][0],i[0][1])}}function uo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Se=="function"?Se(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,p){a=e[i](a),n(s,p,a.done,a.value)})}}function n(i,a,s,p){Promise.resolve(p).then(function(c){i({value:c,done:s})},a)}}function k(e){return typeof e=="function"}function ut(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Qt=ut(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: -`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` - `):"",this.name="UnsubscriptionError",this.errors=r}});function Be(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var De=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=Se(a),p=s.next();!p.done;p=s.next()){var c=p.value;c.remove(this)}}catch(M){t={error:M}}finally{try{p&&!p.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(M){i=M instanceof Qt?M.errors:[M]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=Se(f),d=u.next();!d.done;d=u.next()){var b=d.value;try{ho(b)}catch(M){i=i!=null?i:[],M instanceof Qt?i=q(q([],K(i)),K(M.errors)):i.push(M)}}}catch(M){o={error:M}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Qt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)ho(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Be(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Be(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Cr=De.EMPTY;function Yt(e){return e instanceof De||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function ho(e){k(e)?e():e.unsubscribe()}var Ie={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var dt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Cr:(this.currentObservers=null,s.push(r),new De(function(){o.currentObservers=null,Be(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new V;return r.source=this,r},t.create=function(r,o){return new So(r,o)},t}(V);var So=function(e){me(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Cr},t}(T);var At={now:function(){return(At.delegate||Date).now()},delegate:void 0};var Ct=function(e){me(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=At);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,p=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+p)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),p=0;p0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=vt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(vt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(Jt);var Mo=function(e){me(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(Xt);var Oe=new Mo(Oo);var E=new V(function(e){return e.complete()});function Zt(e){return e&&k(e.schedule)}function Fr(e){return e[e.length-1]}function tt(e){return k(Fr(e))?e.pop():void 0}function Re(e){return Zt(Fr(e))?e.pop():void 0}function er(e,t){return typeof Fr(e)=="number"?e.pop():t}var gt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function tr(e){return k(e==null?void 0:e.then)}function rr(e){return k(e[bt])}function or(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function nr(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ni(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var ir=Ni();function ar(e){return k(e==null?void 0:e[ir])}function sr(e){return fo(this,arguments,function(){var r,o,n,i;return qt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,ct(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,ct(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,ct(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function cr(e){return k(e==null?void 0:e.getReader)}function I(e){if(e instanceof V)return e;if(e!=null){if(rr(e))return Di(e);if(gt(e))return Vi(e);if(tr(e))return zi(e);if(or(e))return Lo(e);if(ar(e))return Ki(e);if(cr(e))return qi(e)}throw nr(e)}function Di(e){return new V(function(t){var r=e[bt]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Vi(e){return new V(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?y(function(n,i){return e(n,i,o)}):de,he(1),r?je(t):zo(function(){return new lr}))}}function Dr(e){return e<=0?function(){return E}:g(function(t,r){var o=[];t.subscribe(x(r,function(n){o.push(n),e=2,!0))}function be(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new T}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,p=s===void 0?!0:s;return function(c){var l,f,u,d=0,b=!1,M=!1,ee=function(){f==null||f.unsubscribe(),f=void 0},re=function(){ee(),l=u=void 0,b=M=!1},B=function(){var C=l;re(),C==null||C.unsubscribe()};return g(function(C,et){d++,!M&&!b&&ee();var H=u=u!=null?u:r();et.add(function(){d--,d===0&&!M&&!b&&(f=Vr(B,p))}),H.subscribe(et),!l&&d>0&&(l=new lt({next:function(Q){return H.next(Q)},error:function(Q){M=!0,ee(),f=Vr(re,n,Q),H.error(Q)},complete:function(){b=!0,ee(),f=Vr(re,a),H.complete()}}),I(C).subscribe(l))})(c)}}function Vr(e,t){for(var r=[],o=2;oe.next(document)),e}function $(e,t=document){return Array.from(t.querySelectorAll(e))}function U(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Ne(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}var la=w(h(document.body,"focusin"),h(document.body,"focusout")).pipe(ye(1),z(void 0),m(()=>Ne()||document.body),J(1));function Et(e){return la.pipe(m(t=>e.contains(t)),Z())}function ur(e,t){return w(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?ye(t):de,z(!1))}function ze(e){return{x:e.offsetLeft,y:e.offsetTop}}function Bo(e){return w(h(window,"load"),h(window,"resize")).pipe(He(0,Oe),m(()=>ze(e)),z(ze(e)))}function dr(e){return{x:e.scrollLeft,y:e.scrollTop}}function it(e){return w(h(e,"scroll"),h(window,"resize")).pipe(He(0,Oe),m(()=>dr(e)),z(dr(e)))}function Go(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Go(e,r)}function O(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Go(o,n);return o}function hr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function wt(e){let t=O("script",{src:e});return P(()=>(document.head.appendChild(t),w(h(t,"load"),h(t,"error").pipe(v(()=>Ht(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),A(()=>document.head.removeChild(t)),he(1))))}var Jo=new T,ma=P(()=>typeof ResizeObserver=="undefined"?wt("https://unpkg.com/resize-observer-polyfill/dist/ResizeObserver.js"):R(void 0)).pipe(m(()=>new ResizeObserver(e=>{for(let t of e)Jo.next(t)})),v(e=>w(Je,R(e)).pipe(A(()=>e.disconnect()))),J(1));function ve(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Ae(e){return ma.pipe(S(t=>t.observe(e)),v(t=>Jo.pipe(y(({target:r})=>r===e),A(()=>t.unobserve(e)),m(()=>ve(e)))),z(ve(e)))}function St(e){return{width:e.scrollWidth,height:e.scrollHeight}}function Tt(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var Xo=new T,fa=P(()=>R(new IntersectionObserver(e=>{for(let t of e)Xo.next(t)},{threshold:0}))).pipe(v(e=>w(Je,R(e)).pipe(A(()=>e.disconnect()))),J(1));function Ot(e){return fa.pipe(S(t=>t.observe(e)),v(t=>Xo.pipe(y(({target:r})=>r===e),A(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Zo(e,t=16){return it(e).pipe(m(({y:r})=>{let o=ve(e),n=St(e);return r>=n.height-o.height-t}),Z())}var br={drawer:U("[data-md-toggle=drawer]"),search:U("[data-md-toggle=search]")};function en(e){return br[e].checked}function Ze(e,t){br[e].checked!==t&&br[e].click()}function Ke(e){let t=br[e];return h(t,"change").pipe(m(()=>t.checked),z(t.checked))}function ua(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function da(){return w(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(z(!1))}function tn(){let e=h(window,"keydown").pipe(y(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:en("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),y(({mode:t,type:r})=>{if(t==="global"){let o=Ne();if(typeof o!="undefined")return!ua(o,r)}return!0}),be());return da().pipe(v(t=>t?E:e))}function Ee(){return new URL(location.href)}function ft(e){location.href=e.href}function rn(){return new T}function on(){return location.hash.slice(1)}function Qr(e){let t=O("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Yr(e){return w(h(window,"hashchange"),e).pipe(m(on),z(on()),y(t=>t.length>0),J(1))}function nn(e){return Yr(e).pipe(m(t=>fe(`[id="${t}"]`)),y(t=>typeof t!="undefined"))}function It(e){let t=matchMedia(e);return mr(r=>t.addListener(()=>r(t.matches))).pipe(z(t.matches))}function an(){let e=matchMedia("print");return w(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(z(e.matches))}function Br(e,t){return e.pipe(v(r=>r?t():E))}function vr(e,t={credentials:"same-origin"}){return pe(fetch(`${e}`,t)).pipe(xe(()=>E),v(r=>r.status!==200?Ht(()=>new Error(r.statusText)):R(r)))}function qe(e,t){return vr(e,t).pipe(v(r=>r.json()),J(1))}function sn(e,t){let r=new DOMParser;return vr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),J(1))}function cn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function pn(){return w(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(cn),z(cn()))}function ln(){return{width:innerWidth,height:innerHeight}}function mn(){return h(window,"resize",{passive:!0}).pipe(m(ln),z(ln()))}function fn(){return G([pn(),mn()]).pipe(m(([e,t])=>({offset:e,size:t})),J(1))}function gr(e,{viewport$:t,header$:r}){let o=t.pipe(ne("size")),n=G([o,r]).pipe(m(()=>ze(e)));return G([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:p,y:c}])=>({offset:{x:a.x-p,y:a.y-c+i},size:s})))}function ha(e){return h(e,"message",t=>t.data)}function ba(e){let t=new T;return t.subscribe(r=>e.postMessage(r)),t}function un(e,t=new Worker(e)){let r=ha(t),o=ba(t),n=new T;n.subscribe(o);let i=o.pipe(oe(),ae(!0));return n.pipe(oe(),Ue(r.pipe(W(i))),be())}var va=U("#__config"),Mt=JSON.parse(va.textContent);Mt.base=`${new URL(Mt.base,Ee())}`;function ge(){return Mt}function X(e){return Mt.features.includes(e)}function Le(e,t){return typeof t!="undefined"?Mt.translations[e].replace("#",t.toString()):Mt.translations[e]}function Ce(e,t=document){return U(`[data-md-component=${e}]`,t)}function le(e,t=document){return $(`[data-md-component=${e}]`,t)}function ga(e){let t=U(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>U(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function dn(e){return!X("announce.dismiss")||!e.childElementCount?E:P(()=>{let t=new T;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),ga(e).pipe(S(r=>t.next(r)),A(()=>t.complete()),m(r=>j({ref:e},r)))})}function xa(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function hn(e,t){let r=new T;return r.subscribe(({hidden:o})=>{e.hidden=o}),xa(e,t).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))}function Ft(e,t){return t==="inline"?O("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},O("div",{class:"md-tooltip__inner md-typeset"})):O("div",{class:"md-tooltip",id:e,role:"tooltip"},O("div",{class:"md-tooltip__inner md-typeset"}))}function bn(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return O("aside",{class:"md-annotation",tabIndex:0},Ft(t),O("a",{href:r,class:"md-annotation__index",tabIndex:-1},O("span",{"data-md-annotation-id":e})))}else return O("aside",{class:"md-annotation",tabIndex:0},Ft(t),O("span",{class:"md-annotation__index",tabIndex:-1},O("span",{"data-md-annotation-id":e})))}function vn(e){return O("button",{class:"md-code__button",title:Le("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function gn(){return O("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function xn(){return O("nav",{class:"md-code__nav"})}function Gr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(p=>!e.terms[p]).reduce((p,c)=>[...p,O("del",null,c)," "],[]).slice(0,-1),i=ge(),a=new URL(e.location,i.base);X("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,p])=>p).reduce((p,[c])=>`${p} ${c}`.trim(),""));let{tags:s}=ge();return O("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},O("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&O("div",{class:"md-search-result__icon md-icon"}),r>0&&O("h1",null,e.title),r<=0&&O("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(p=>{let c=s?p in s?`md-tag-icon md-tag--${s[p]}`:"md-tag-icon":"";return O("span",{class:`md-tag ${c}`},p)}),o>0&&n.length>0&&O("p",{class:"md-search-result__terms"},Le("search.result.term.missing"),": ",...n)))}function yn(e){let t=e[0].score,r=[...e],o=ge(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreGr(l,1)),...p.length?[O("details",{class:"md-search-result__more"},O("summary",{tabIndex:-1},O("div",null,p.length>0&&p.length===1?Le("search.result.more.one"):Le("search.result.more.other",p.length))),...p.map(l=>Gr(l,1)))]:[]];return O("li",{class:"md-search-result__item"},c)}function En(e){return O("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>O("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?hr(r):r)))}function Jr(e){let t=`tabbed-control tabbed-control--${e}`;return O("div",{class:t,hidden:!0},O("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function wn(e){return O("div",{class:"md-typeset__scrollwrap"},O("div",{class:"md-typeset__table"},e))}function ya(e){let t=ge(),r=new URL(`../${e.version}/`,t.base);return O("li",{class:"md-version__item"},O("a",{href:`${r}`,class:"md-version__link"},e.title))}function Sn(e,t){return O("div",{class:"md-version"},O("button",{class:"md-version__current","aria-label":Le("select.version")},t.title),O("ul",{class:"md-version__list"},e.map(ya)))}var Ea=0;function wa(e,t){document.body.append(e);let{width:r}=ve(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=Tt(t),n=typeof o!="undefined"?it(o):R({x:0,y:0}),i=w(Et(t),ur(t)).pipe(Z());return G([i,n]).pipe(m(([a,s])=>{let{x:p,y:c}=ze(t),l=ve(t),f=t.closest("table");return f&&t.parentElement&&(p+=f.offsetLeft+t.parentElement.offsetLeft,c+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:p-s.x+l.width/2-r/2,y:c-s.y+l.height+8}}}))}function Qe(e){let t=e.title;if(!t.length)return E;let r=`__tooltip_${Ea++}`,o=Ft(r,"inline"),n=U(".md-typeset",o);return n.innerHTML=t,P(()=>{let i=new T;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),w(i.pipe(y(({active:a})=>a)),i.pipe(ye(250),y(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(He(16,Oe)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(Pt(125,Oe),y(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),wa(o,e).pipe(S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))}).pipe(Ge(ce))}function Sa(e,t){let r=P(()=>G([Bo(e),it(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=ve(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return Et(e).pipe(v(o=>r.pipe(m(n=>({active:o,offset:n})),he(+!o||1/0))))}function Tn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return P(()=>{let i=new T,a=i.pipe(oe(),ae(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),Ot(e).pipe(W(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),w(i.pipe(y(({active:s})=>s)),i.pipe(ye(250),y(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(He(16,Oe)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(Pt(125,Oe),y(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(W(a),y(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),h(n,"mousedown").pipe(W(a),ie(i)).subscribe(([s,{active:p}])=>{var c;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(p){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(c=Ne())==null||c.blur()}}),r.pipe(W(a),y(s=>s===o),Xe(125)).subscribe(()=>e.focus()),Sa(e,t).pipe(S(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))})}function Ta(e){let t=ge();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(typeof t.annotate!="undefined"){let o=e.closest("[class|=language]");if(o)for(let n of Array.from(o.classList)){if(!n.startsWith("language-"))continue;let[,i]=n.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return $(r.join(", "),e)}function Oa(e){let t=[];for(let r of Ta(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,p]=a;if(typeof p=="undefined"){let c=i.splitText(a.index);i=c.splitText(s.length),t.push(c)}else{i.textContent=s,t.push(i);break}}}}return t}function On(e,t){t.append(...Array.from(e.childNodes))}function xr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Oa(t)){let[,p]=s.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${p})`,e)&&(a.set(p,bn(p,i)),s.replaceWith(a.get(p)))}return a.size===0?E:P(()=>{let s=new T,p=s.pipe(oe(),ae(!0)),c=[];for(let[l,f]of a)c.push([U(".md-typeset",f),U(`:scope > li:nth-child(${l})`,e)]);return o.pipe(W(p)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of c)l?On(f,u):On(u,f)}),w(...[...a].map(([,l])=>Tn(l,t,{target$:r}))).pipe(A(()=>s.complete()),be())})}function Mn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Mn(t)}}function Ln(e,t){return P(()=>{let r=Mn(e);return typeof r!="undefined"?xr(r,e,t):E})}var An=Kt(Zr());var Ma=0,_n=w(h(window,"keydown").pipe(m(()=>!0)),w(h(window,"keyup"),h(window,"contextmenu")).pipe(m(()=>!1))).pipe(z(!1),J(1));function Cn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Cn(t)}}function La(e){return Ae(e).pipe(m(({width:t})=>({scrollable:St(e).width>t})),ne("scrollable"))}function kn(e,t){let{matches:r}=matchMedia("(hover)"),o=P(()=>{let n=new T,i=n.pipe(Dr(1));n.subscribe(({scrollable:u})=>{u&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=Ma++,s=[],p=e.closest("pre");p.id=`__code_${a}`;let c=[],l=e.closest(".highlight");if(l instanceof HTMLElement){let u=Cn(l);if(typeof u!="undefined"&&(l.classList.contains("annotate")||X("content.code.annotate"))){let d=xr(u,e,t);c.push(Ae(l).pipe(W(i),m(({width:b,height:M})=>b&&M),Z(),v(b=>b?d:E)))}}let f=$(":scope > span[id]",e);if(f.length&&(e.classList.add("md-code__content"),e.closest(".select")||X("content.code.select")&&!e.closest(".no-select"))){let u=+f[0].id.split("-").pop(),d=gn();s.push(d),X("content.tooltips")&&c.push(Qe(d));let b=h(d,"click").pipe(Rt(H=>!H,!1),S(()=>d.blur()),be());b.subscribe(H=>{d.classList.toggle("md-code__button--active",H)});let M=pe(f).pipe(te(H=>ur(H).pipe(m(Q=>[H,Q]))));b.pipe(v(H=>H?M:E)).subscribe(([H,Q])=>{let se=fe(".hll.select",H);if(se&&!Q)se.replaceWith(...Array.from(se.childNodes));else if(!se&&Q){let ue=document.createElement("span");ue.className="hll select",ue.append(...Array.from(H.childNodes).slice(1)),H.append(ue)}});let ee=pe(f).pipe(te(H=>h(H,"mousedown").pipe(S(Q=>Q.preventDefault()),m(()=>H)))),re=b.pipe(v(H=>H?ee:E),ie(_n),m(([H,Q])=>{var ue;let se=f.indexOf(H)+u;if(Q===!1)return[se,se];{let we=$(".hll",e).map(Ye=>f.indexOf(Ye.parentElement)+u);return(ue=window.getSelection())==null||ue.removeAllRanges(),[Math.min(se,...we),Math.max(se,...we)]}})),B=Yr(E).pipe(y(H=>H.startsWith(`__codelineno-${a}-`)));B.subscribe(H=>{let[,,Q]=H.split("-"),se=Q.split(":").map(we=>+we-u+1);se.length===1&&se.push(se[0]);for(let we of $(".hll:not(.select)",e))we.replaceWith(...Array.from(we.childNodes));let ue=f.slice(se[0]-1,se[1]);for(let we of ue){let Ye=document.createElement("span");Ye.className="hll",Ye.append(...Array.from(we.childNodes).slice(1)),we.append(Ye)}}),B.pipe(he(1),ke(ce)).subscribe(H=>{if(H.includes(":")){let Q=document.getElementById(H.split(":")[0]);Q&&setTimeout(()=>{let se=Q,ue=-(48+16);for(;se!==document.body;)ue+=se.offsetTop,se=se.offsetParent;window.scrollTo({top:ue})},1)}});let et=pe($('a[href^="#__codelineno"]',l)).pipe(te(H=>h(H,"click").pipe(S(Q=>Q.preventDefault()),m(()=>H)))).pipe(W(i),ie(_n),m(([H,Q])=>{let ue=+U(`[id="${H.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(Q===!1)return[ue,ue];{let we=$(".hll",e).map(Ye=>+Ye.parentElement.id.split("-").pop());return[Math.min(ue,...we),Math.max(ue,...we)]}}));w(re,et).subscribe(H=>{let Q=`#__codelineno-${a}-`;H[0]===H[1]?Q+=H[0]:Q+=`${H[0]}:${H[1]}`,history.replaceState({},"",Q),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+Q,oldURL:window.location.href}))})}if(An.default.isSupported()&&(e.closest(".copy")||X("content.code.copy")&&!e.closest(".no-copy"))){let u=vn(p.id);s.push(u),X("content.tooltips")&&c.push(Qe(u))}if(s.length){let u=xn();u.append(...s),p.insertBefore(u,e)}return La(e).pipe(S(u=>n.next(u)),A(()=>n.complete()),m(u=>j({ref:e},u)),Ue(...c))});return X("content.lazy")?Ot(e).pipe(y(n=>n),he(1),v(()=>o)):o}function _a(e,{target$:t,print$:r}){let o=!0;return w(t.pipe(m(n=>n.closest("details:not([open])")),y(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(y(n=>n||!o),S(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Hn(e,t){return P(()=>{let r=new T;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),_a(e,t).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}var $n=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}.actor,defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{stroke:var(--md-mermaid-node-fg-color)}text.actor>tspan{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-default-fg-color--lighter)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-edge-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{fill:var(--md-mermaid-edge-color);stroke:none;font-family:var(--md-mermaid-font-family)!important}.noteText>tspan{fill:#000}#arrowhead path{fill:var(--md-mermaid-edge-color);stroke:none}.loopLine{stroke:var(--md-mermaid-node-fg-color)}.labelBox,.loopLine{fill:var(--md-mermaid-node-bg-color)}.labelBox{stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-node-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-accent-bg-color)}rect.rect{fill:var(--md-mermaid-node-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-edge-color)}defs #sequencenumber{fill:var(--md-mermaid-node-fg-color)!important}";var eo,Ca=0;function ka(){return typeof mermaid=="undefined"||mermaid instanceof Element?wt("https://unpkg.com/mermaid@9.4.3/dist/mermaid.min.js"):R(void 0)}function Rn(e){return e.classList.remove("mermaid"),eo||(eo=ka().pipe(S(()=>mermaid.initialize({startOnLoad:!1,themeCSS:$n,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),J(1))),eo.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${Ca++}`,r=O("div",{class:"mermaid"}),o=e.textContent;mermaid.mermaidAPI.render(t,o,(n,i)=>{let a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})}),eo.pipe(m(()=>({ref:e})))}var Pn=O("table");function In(e){return e.replaceWith(Pn),Pn.replaceWith(wn(e)),R({ref:e})}function Ha(e){let t=e.find(r=>r.checked)||e[0];return w(...e.map(r=>h(r,"change").pipe(m(()=>U(`label[for="${r.id}"]`))))).pipe(z(U(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Fn(e,{viewport$:t,target$:r}){let o=U(".tabbed-labels",e),n=$(":scope > input",e),i=Jr("prev");e.append(i);let a=Jr("next");return e.append(a),P(()=>{let s=new T,p=s.pipe(oe(),ae(!0));G([s,Ae(e)]).pipe(W(p),He(1,Oe)).subscribe({next([{active:c},l]){let f=ze(c),{width:u}=ve(c);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=dr(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),G([it(o),Ae(o)]).pipe(W(p)).subscribe(([c,l])=>{let f=St(o);i.hidden=c.x<16,a.hidden=c.x>f.width-l.width-16}),w(h(i,"click").pipe(m(()=>-1)),h(a,"click").pipe(m(()=>1))).pipe(W(p)).subscribe(c=>{let{width:l}=ve(o);o.scrollBy({left:l*c,behavior:"smooth"})}),r.pipe(W(p),y(c=>n.includes(c))).subscribe(c=>c.click()),o.classList.add("tabbed-labels--linked");for(let c of n){let l=U(`label[for="${c.id}"]`);l.replaceChildren(O("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(W(p),y(f=>!(f.metaKey||f.ctrlKey)),S(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return X("content.tabs.link")&&s.pipe(Me(1),ie(t)).subscribe(([{active:c},{offset:l}])=>{let f=c.innerText.trim();if(c.hasAttribute("data-md-switching"))c.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let b of $("[data-tabs]"))for(let M of $(":scope > input",b)){let ee=U(`label[for="${M.id}"]`);if(ee!==c&&ee.innerText.trim()===f){ee.setAttribute("data-md-switching",""),M.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),s.pipe(W(p)).subscribe(()=>{for(let c of $("audio, video",e))c.pause()}),Ha(n).pipe(S(c=>s.next(c)),A(()=>s.complete()),m(c=>j({ref:e},c)))}).pipe(Ge(ce))}function jn(e,{viewport$:t,target$:r,print$:o}){return w(...$(".annotate:not(.highlight)",e).map(n=>Ln(n,{target$:r,print$:o})),...$("pre:not(.mermaid) > code",e).map(n=>kn(n,{target$:r,print$:o})),...$("pre.mermaid",e).map(n=>Rn(n)),...$("table:not([class])",e).map(n=>In(n)),...$("details",e).map(n=>Hn(n,{target$:r,print$:o})),...$("[data-tabs]",e).map(n=>Fn(n,{viewport$:t,target$:r})),...$("[title]",e).filter(()=>X("content.tooltips")).map(n=>Qe(n)))}function $a(e,{alert$:t}){return t.pipe(v(r=>w(R(!0),R(!1).pipe(Xe(2e3))).pipe(m(o=>({message:r,active:o})))))}function Wn(e,t){let r=U(".md-typeset",e);return P(()=>{let o=new T;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),$a(e,t).pipe(S(n=>o.next(n)),A(()=>o.complete()),m(n=>j({ref:e},n)))})}function Ra({viewport$:e}){if(!X("header.autohide"))return R(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Fe(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Z()),o=Ke("search");return G([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Z(),v(n=>n?r:R(!1)),z(!1))}function Un(e,t){return P(()=>G([Ae(e),Ra(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Z((r,o)=>r.height===o.height&&r.hidden===o.hidden),J(1))}function Nn(e,{header$:t,main$:r}){return P(()=>{let o=new T,n=o.pipe(oe(),ae(!0));o.pipe(ne("active"),nt(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=pe($("[title]",e)).pipe(y(()=>X("content.tooltips")),te(a=>Qe(a)));return r.subscribe(o),t.pipe(W(n),m(a=>j({ref:e},a)),Ue(i.pipe(W(n))))})}function Pa(e,{viewport$:t,header$:r}){return gr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ve(e);return{active:o>=n}}),ne("active"))}function Dn(e,t){return P(()=>{let r=new T;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?E:Pa(o,t).pipe(S(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))})}function Vn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Z()),n=o.pipe(v(()=>Ae(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),ne("bottom"))));return G([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:p},size:{height:c}}])=>(c=Math.max(0,c-Math.max(0,a-p,i)-Math.max(0,c+p-s)),{offset:a-i,height:c,active:a-i<=p})),Z((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Ia(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return R(...e).pipe(te(r=>h(r,"change").pipe(m(()=>r))),z(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{media:r.getAttribute("data-md-color-media"),scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),J(1))}function zn(e){let t=$("input",e),r=O("meta",{name:"theme-color"});document.head.appendChild(r);let o=O("meta",{name:"color-scheme"});document.head.appendChild(o);let n=It("(prefers-color-scheme: light)");return P(()=>{let i=new T;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),p=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=p.getAttribute("data-md-color-scheme"),a.color.primary=p.getAttribute("data-md-color-primary"),a.color.accent=p.getAttribute("data-md-color-accent")}for(let[s,p]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,p);for(let s=0;s{let a=Ce("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(p=>(+p).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(ke(ce)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Ia(t).pipe(W(n.pipe(Me(1))),mt(),S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))})}var to=Kt(Zr());function Fa(e){e.setAttribute("data-md-copying","");let t=e.innerText;return e.removeAttribute("data-md-copying"),t}function Kn({alert$:e}){to.default.isSupported()&&new V(t=>{new to.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Fa(U(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(S(t=>{t.trigger.focus()}),m(()=>Le("clipboard.copied"))).subscribe(e)}function ja(e){if(e.length<2)return[""];let[t,r]=[...e].sort((n,i)=>n.length-i.length).map(n=>n.replace(/[^/]+$/,"")),o=0;if(t===r)o=t.length;else for(;t.charCodeAt(o)===r.charCodeAt(o);)o++;return e.map(n=>n.replace(t.slice(0,o),""))}function yr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return R(t);{let r=ge();return sn(new URL("sitemap.xml",e||r.base)).pipe(m(o=>ja($("loc",o).map(n=>n.textContent))),xe(()=>E),je([]),S(o=>__md_set("__sitemap",o,sessionStorage,e)))}}function qn(e,t){if(!(e.target instanceof Element))return E;let r=e.target.closest("a");if(r===null)return E;if(r.target||e.metaKey||e.ctrlKey)return E;let o=new URL(r.href);return o.search=o.hash="",t.includes(`${o}`)?(e.preventDefault(),R(new URL(r.href))):E}function Qn({location$:e,viewport$:t}){let r=ge();if(location.protocol==="file:")return E;let o=yr().pipe(m(c=>c.map(l=>`${new URL(l,r.base)}`))),n=h(document.body,"click").pipe(ie(o),v(([c,l])=>qn(c,l)),be());X("navigation.instant.prefetch")&&w(h(document.body,"mousemove"),h(document.body,"focusin")).pipe(ie(o),v(([c,l])=>qn(c,l)),ye(25),Nr(({href:c})=>c),fr(c=>{let l=document.createElement("link");return l.rel="prefetch",l.href=c.toString(),document.head.appendChild(l),h(l,"load").pipe(m(()=>l),he(1))})).subscribe(c=>c.remove()),n.pipe(he(1)).subscribe(()=>{let c=fe("link[rel=icon]");typeof c!="undefined"&&(c.href=c.href)}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),n.pipe(ie(t)).subscribe(([c,{offset:l}])=>{history.scrollRestoration="manual",history.replaceState(l,""),history.pushState(null,"",c)}),n.subscribe(e);let i=e.pipe(z(Ee()),ne("pathname"),Me(1),v(c=>vr(c).pipe(xe(()=>(ft(c),E))))),a=new DOMParser,s=i.pipe(v(c=>c.text()),v(c=>{let l=a.parseFromString(c,"text/html");for(let u of["title","link[rel=canonical]","meta[name=author]","meta[name=description]","[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...X("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let d=fe(u),b=fe(u,l);typeof d!="undefined"&&typeof b!="undefined"&&d.replaceWith(b)}let f=Ce("container");return Ve($("script",f)).pipe(v(u=>{let d=l.createElement("script");if(u.src){for(let b of u.getAttributeNames())d.setAttribute(b,u.getAttribute(b));return u.replaceWith(d),new V(b=>{d.onload=()=>b.complete()})}else return d.textContent=u.textContent,u.replaceWith(d),E}),oe(),ae(l))}),be());return h(window,"popstate").pipe(m(Ee)).subscribe(e),e.pipe(z(Ee()),Fe(2,1),v(([c,l])=>c.pathname===l.pathname&&c.hash!==l.hash?R(l):E)).subscribe(c=>{var l,f;history.state!==null||!c.hash?window.scrollTo(0,(f=(l=history.state)==null?void 0:l.y)!=null?f:0):(history.scrollRestoration="auto",Qr(c.hash),history.scrollRestoration="manual")}),s.pipe(ie(e)).subscribe(([,c])=>{var l,f;history.state!==null||!c.hash?window.scrollTo(0,(f=(l=history.state)==null?void 0:l.y)!=null?f:0):Qr(c.hash)}),s.pipe(v(()=>t),ne("offset"),ye(100)).subscribe(({offset:c})=>{history.replaceState(c,"")}),s}var Gn=Kt(Bn());function Jn(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,Gn.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Wt(e){return e.type===1}function Er(e){return e.type===3}function Xn(e,t){let r=un(e);return w(R(location.protocol!=="file:"),Ke("search")).pipe(We(o=>o),v(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:X("search.suggest")}}})),r}function Zn({document$:e}){let t=ge(),r=qe(new URL("../versions.json",t.base)).pipe(xe(()=>E)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),v(n=>h(document.body,"click").pipe(y(i=>!i.metaKey&&!i.ctrlKey),ie(o),v(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let p=s.href;return!i.target.closest(".md-version")&&n.get(p)===a?E:(i.preventDefault(),R(p))}}return E}),v(i=>{let{version:a}=n.get(i);return yr(new URL(i)).pipe(m(s=>{let c=Ee().href.replace(t.base,"");return s.includes(c.split("#")[0])?new URL(`../${a}/${c}`,t.base):new URL(i)}))})))).subscribe(n=>ft(n)),G([r,o]).subscribe(([n,i])=>{U(".md-header__topic").appendChild(Sn(n,i))}),e.pipe(v(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let p of s)for(let c of n.aliases)if(new RegExp(p,"i").test(c)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of le("outdated"))s.hidden=!1})}function Va(e,{worker$:t}){let{searchParams:r}=Ee();r.has("q")&&(Ze("search",!0),e.value=r.get("q"),e.focus(),Ke("search").pipe(We(i=>!i)).subscribe(()=>{let i=new URL(location.href);i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Et(e),n=w(t.pipe(We(Wt)),h(e,"keyup"),o).pipe(m(()=>e.value),Z());return G([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),J(1))}function ei(e,{worker$:t}){let r=new T,o=r.pipe(oe(),ae(!0));G([t.pipe(We(Wt)),r],(i,a)=>a).pipe(ne("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(ne("focus")).subscribe(({focus:i})=>{i&&Ze("search",i)}),h(e.form,"reset").pipe(W(o)).subscribe(()=>e.focus());let n=U("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),Va(e,{worker$:t}).pipe(S(i=>r.next(i)),A(()=>r.complete()),m(i=>j({ref:e},i)),J(1))}function ti(e,{worker$:t,query$:r}){let o=new T,n=Zo(e.parentElement).pipe(y(Boolean)),i=e.parentElement,a=U(":scope > :first-child",e),s=U(":scope > :last-child",e);Ke("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(ie(r),zr(t.pipe(We(Wt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?Le("search.result.none"):Le("search.result.placeholder");break;case 1:a.textContent=Le("search.result.one");break;default:let u=hr(l.length);a.textContent=Le("search.result.other",u)}});let p=o.pipe(S(()=>s.innerHTML=""),v(({items:l})=>w(R(...l.slice(0,10)),R(...l.slice(10)).pipe(Fe(4),qr(n),v(([f])=>f)))),m(yn),be());return p.subscribe(l=>s.appendChild(l)),p.pipe(te(l=>{let f=fe("details",l);return typeof f=="undefined"?E:h(f,"toggle").pipe(W(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(y(Er),m(({data:l})=>l)).pipe(S(l=>o.next(l)),A(()=>o.complete()),m(l=>j({ref:e},l)))}function za(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=Ee();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function ri(e,t){let r=new T,o=r.pipe(oe(),ae(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(W(o)).subscribe(n=>n.preventDefault()),za(e,t).pipe(S(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))}function oi(e,{worker$:t,keyboard$:r}){let o=new T,n=Ce("search-query"),i=w(h(n,"keydown"),h(n,"focus")).pipe(ke(ce),m(()=>n.value),Z());return o.pipe(nt(i),m(([{suggest:s},p])=>{let c=p.split(/([\s-]+)/);if(s!=null&&s.length&&c[c.length-1]){let l=s[s.length-1];l.startsWith(c[c.length-1])&&(c[c.length-1]=l)}else c.length=0;return c})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(y(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(y(Er),m(({data:s})=>s)).pipe(S(s=>o.next(s)),A(()=>o.complete()),m(()=>({ref:e})))}function ni(e,{index$:t,keyboard$:r}){let o=ge();try{let n=Xn(o.search,t),i=Ce("search-query",e),a=Ce("search-result",e);h(e,"click").pipe(y(({target:p})=>p instanceof Element&&!!p.closest("a"))).subscribe(()=>Ze("search",!1)),r.pipe(y(({mode:p})=>p==="search")).subscribe(p=>{let c=Ne();switch(p.type){case"Enter":if(c===i){let l=new Map;for(let f of $(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}p.claim()}break;case"Escape":case"Tab":Ze("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof c=="undefined")i.focus();else{let l=[i,...$(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(c))+l.length+(p.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}p.claim();break;default:i!==Ne()&&i.focus()}}),r.pipe(y(({mode:p})=>p==="global")).subscribe(p=>{switch(p.type){case"f":case"s":case"/":i.focus(),i.select(),p.claim();break}});let s=ei(i,{worker$:n});return w(s,ti(a,{worker$:n,query$:s})).pipe(Ue(...le("search-share",e).map(p=>ri(p,{query$:s})),...le("search-suggest",e).map(p=>oi(p,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Je}}function ii(e,{index$:t,location$:r}){return G([t,r.pipe(z(Ee()),y(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>Jn(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let p=s.textContent,c=o(p);c.length>p.length&&n.set(s,c)}for(let[s,p]of n){let{childNodes:c}=O("span",null,p);s.replaceWith(...Array.from(c))}return{ref:e,nodes:n}}))}function Ka(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return G([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),Z((i,a)=>i.height===a.height&&i.locked===a.locked))}function ro(e,o){var n=o,{header$:t}=n,r=co(n,["header$"]);let i=U(".md-sidebar__scrollwrap",e),{y:a}=ze(i);return P(()=>{let s=new T,p=s.pipe(oe(),ae(!0)),c=s.pipe(He(0,Oe));return c.pipe(ie(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),c.pipe(We()).subscribe(()=>{for(let l of $(".md-nav__link--active[href]",e)){let f=Tt(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ve(f);f.scrollTo({top:u-d/2})}}}),pe($("label[tabindex]",e)).pipe(te(l=>h(l,"click").pipe(m(()=>l),W(p)))).subscribe(l=>{let f=U(`[id="${l.htmlFor}"]`);U(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Ka(e,r).pipe(S(l=>s.next(l)),A(()=>s.complete()),m(l=>j({ref:e},l)))})}function ai(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return $t(qe(`${r}/releases/latest`).pipe(xe(()=>E),m(o=>({version:o.tag_name})),je({})),qe(r).pipe(xe(()=>E),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),je({}))).pipe(m(([o,n])=>j(j({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return qe(r).pipe(m(o=>({repositories:o.public_repos})),je({}))}}function si(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return qe(r).pipe(xe(()=>E),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),je({}))}function ci(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return ai(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return si(r,o)}return E}var qa;function Qa(e){return qa||(qa=P(()=>{let t=__md_get("__source",sessionStorage);if(t)return R(t);if(le("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return E}return ci(e.href).pipe(S(o=>__md_set("__source",o,sessionStorage)))}).pipe(xe(()=>E),y(t=>Object.keys(t).length>0),m(t=>({facts:t})),J(1)))}function pi(e){let t=U(":scope > :last-child",e);return P(()=>{let r=new T;return r.subscribe(({facts:o})=>{t.appendChild(En(o)),t.classList.add("md-source__repository--active")}),Qa(e).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Ya(e,{viewport$:t,header$:r}){return Ae(document.body).pipe(v(()=>gr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),ne("hidden"))}function li(e,t){return P(()=>{let r=new T;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(X("navigation.tabs.sticky")?R({hidden:!1}):Ya(e,t)).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Ba(e,{viewport$:t,header$:r}){let o=new Map,n=$("[href^=\\#]",e);for(let s of n){let p=decodeURIComponent(s.hash.substring(1)),c=fe(`[id="${p}"]`);typeof c!="undefined"&&o.set(s,c)}let i=r.pipe(ne("height"),m(({height:s})=>{let p=Ce("main"),c=U(":scope > :first-child",p);return s+.8*(c.offsetTop-p.offsetTop)}),be());return Ae(document.body).pipe(ne("height"),v(s=>P(()=>{let p=[];return R([...o].reduce((c,[l,f])=>{for(;p.length&&o.get(p[p.length-1]).tagName>=f.tagName;)p.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return c.set([...p=[...p,l]].reverse(),u)},new Map))}).pipe(m(p=>new Map([...p].sort(([,c],[,l])=>c-l))),nt(i),v(([p,c])=>t.pipe(Rt(([l,f],{offset:{y:u},size:d})=>{let b=u+d.height>=Math.floor(s.height);for(;f.length;){let[,M]=f[0];if(M-c=u&&!b)f=[l.pop(),...f];else break}return[l,f]},[[],[...p]]),Z((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,p])=>({prev:s.map(([c])=>c),next:p.map(([c])=>c)})),z({prev:[],next:[]}),Fe(2,1),m(([s,p])=>s.prev.length{let i=new T,a=i.pipe(oe(),ae(!0));if(i.subscribe(({prev:s,next:p})=>{for(let[c]of p)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",c===s.length-1)}),X("toc.follow")){let s=w(t.pipe(ye(1),m(()=>{})),t.pipe(ye(250),m(()=>"smooth")));i.pipe(y(({prev:p})=>p.length>0),nt(o.pipe(ke(ce))),ie(s)).subscribe(([[{prev:p}],c])=>{let[l]=p[p.length-1];if(l.offsetHeight){let f=Tt(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ve(f);f.scrollTo({top:u-d/2,behavior:c})}}})}return X("navigation.tracking")&&t.pipe(W(a),ne("offset"),ye(250),Me(1),W(n.pipe(Me(1))),mt({delay:250}),ie(i)).subscribe(([,{prev:s}])=>{let p=Ee(),c=s[s.length-1];if(c&&c.length){let[l]=c,{hash:f}=new URL(l.href);p.hash!==f&&(p.hash=f,history.replaceState({},"",`${p}`))}else p.hash="",history.replaceState({},"",`${p}`)}),Ba(e,{viewport$:t,header$:r}).pipe(S(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))})}function Ga(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Fe(2,1),m(([a,s])=>a>s&&s>0),Z()),i=r.pipe(m(({active:a})=>a));return G([i,n]).pipe(m(([a,s])=>!(a&&s)),Z(),W(o.pipe(Me(1))),ae(!0),mt({delay:250}),m(a=>({hidden:a})))}function fi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new T,a=i.pipe(oe(),ae(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(W(a),ne("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),h(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),Ga(e,{viewport$:t,main$:o,target$:n}).pipe(S(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))}function ui({document$:e}){e.pipe(v(()=>$(".md-ellipsis")),te(t=>Ot(t).pipe(W(e.pipe(Me(1))),y(r=>r),m(()=>t),he(1))),y(t=>t.offsetWidth{let r=t.innerText,o=t.closest("a")||t;return o.title=r,Qe(o).pipe(W(e.pipe(Me(1))),A(()=>o.removeAttribute("title")))})).subscribe(),e.pipe(v(()=>$(".md-status")),te(t=>Qe(t))).subscribe()}function di({document$:e,tablet$:t}){e.pipe(v(()=>$(".md-toggle--indeterminate")),S(r=>{r.indeterminate=!0,r.checked=!1}),te(r=>h(r,"change").pipe(Kr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ie(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function Ja(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function hi({document$:e}){e.pipe(v(()=>$("[data-md-scrollfix]")),S(t=>t.removeAttribute("data-md-scrollfix")),y(Ja),te(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function bi({viewport$:e,tablet$:t}){G([Ke("search"),t]).pipe(m(([r,o])=>r&&!o),v(r=>R(r).pipe(Xe(r?400:100))),ie(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function Xa(){return location.protocol==="file:"?wt(`${new URL("search/search_index.js",oo.base)}`).pipe(m(()=>__index),J(1)):qe(new URL("search/search_index.json",oo.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var st=Yo(),Nt=rn(),Lt=nn(Nt),no=tn(),$e=fn(),wr=It("(min-width: 960px)"),gi=It("(min-width: 1220px)"),xi=an(),oo=ge(),yi=document.forms.namedItem("search")?Xa():Je,io=new T;Kn({alert$:io});X("navigation.instant")&&Qn({location$:Nt,viewport$:$e}).subscribe(st);var vi;((vi=oo.version)==null?void 0:vi.provider)==="mike"&&Zn({document$:st});w(Nt,Lt).pipe(Xe(125)).subscribe(()=>{Ze("drawer",!1),Ze("search",!1)});no.pipe(y(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&&ft(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&&ft(r);break;case"Enter":let o=Ne();o instanceof HTMLLabelElement&&o.click()}});ui({document$:st});di({document$:st,tablet$:wr});hi({document$:st});bi({viewport$:$e,tablet$:wr});var at=Un(Ce("header"),{viewport$:$e}),Ut=st.pipe(m(()=>Ce("main")),v(e=>Vn(e,{viewport$:$e,header$:at})),J(1)),Za=w(...le("consent").map(e=>hn(e,{target$:Lt})),...le("dialog").map(e=>Wn(e,{alert$:io})),...le("header").map(e=>Nn(e,{viewport$:$e,header$:at,main$:Ut})),...le("palette").map(e=>zn(e)),...le("search").map(e=>ni(e,{index$:yi,keyboard$:no})),...le("source").map(e=>pi(e))),es=P(()=>w(...le("announce").map(e=>dn(e)),...le("content").map(e=>jn(e,{viewport$:$e,target$:Lt,print$:xi})),...le("content").map(e=>X("search.highlight")?ii(e,{index$:yi,location$:Nt}):E),...le("header-title").map(e=>Dn(e,{viewport$:$e,header$:at})),...le("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Br(gi,()=>ro(e,{viewport$:$e,header$:at,main$:Ut})):Br(wr,()=>ro(e,{viewport$:$e,header$:at,main$:Ut}))),...le("tabs").map(e=>li(e,{viewport$:$e,header$:at})),...le("toc").map(e=>mi(e,{viewport$:$e,header$:at,main$:Ut,target$:Lt})),...le("top").map(e=>fi(e,{viewport$:$e,header$:at,main$:Ut,target$:Lt})))),Ei=st.pipe(v(()=>es),Ue(Za),J(1));Ei.subscribe();window.document$=st;window.location$=Nt;window.target$=Lt;window.keyboard$=no;window.viewport$=$e;window.tablet$=wr;window.screen$=gi;window.print$=xi;window.alert$=io;window.component$=Ei;})(); diff --git a/assets/javascripts/bundle.a961bebd.min.js b/assets/javascripts/bundle.a961bebd.min.js new file mode 100644 index 0000000..9a234d6 --- /dev/null +++ b/assets/javascripts/bundle.a961bebd.min.js @@ -0,0 +1,3 @@ +"use strict";(()=>{var Hi=Object.create;var Or=Object.defineProperty;var $i=Object.getOwnPropertyDescriptor;var Ri=Object.getOwnPropertyNames,Vt=Object.getOwnPropertySymbols,Pi=Object.getPrototypeOf,Mr=Object.prototype.hasOwnProperty,po=Object.prototype.propertyIsEnumerable;var co=(e,t,r)=>t in e?Or(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,j=(e,t)=>{for(var r in t||(t={}))Mr.call(t,r)&&co(e,r,t[r]);if(Vt)for(var r of Vt(t))po.call(t,r)&&co(e,r,t[r]);return e};var lo=(e,t)=>{var r={};for(var o in e)Mr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Vt)for(var o of Vt(e))t.indexOf(o)<0&&po.call(e,o)&&(r[o]=e[o]);return r};var Lr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Ii=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ri(t))!Mr.call(e,n)&&n!==r&&Or(e,n,{get:()=>t[n],enumerable:!(o=$i(t,n))||o.enumerable});return e};var zt=(e,t,r)=>(r=e!=null?Hi(Pi(e)):{},Ii(t||!e||!e.__esModule?Or(r,"default",{value:e,enumerable:!0}):r,e));var fo=Lr((_r,mo)=>{(function(e,t){typeof _r=="object"&&typeof mo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(_r,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(C){return!!(C&&C!==document&&C.nodeName!=="HTML"&&C.nodeName!=="BODY"&&"classList"in C&&"contains"in C.classList)}function c(C){var et=C.type,H=C.tagName;return!!(H==="INPUT"&&a[et]&&!C.readOnly||H==="TEXTAREA"&&!C.readOnly||C.isContentEditable)}function p(C){C.classList.contains("focus-visible")||(C.classList.add("focus-visible"),C.setAttribute("data-focus-visible-added",""))}function l(C){C.hasAttribute("data-focus-visible-added")&&(C.classList.remove("focus-visible"),C.removeAttribute("data-focus-visible-added"))}function f(C){C.metaKey||C.altKey||C.ctrlKey||(s(r.activeElement)&&p(r.activeElement),o=!0)}function u(C){o=!1}function h(C){s(C.target)&&(o||c(C.target))&&p(C.target)}function v(C){s(C.target)&&(C.target.classList.contains("focus-visible")||C.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(C.target))}function b(C){document.visibilityState==="hidden"&&(n&&(o=!0),U())}function U(){document.addEventListener("mousemove",X),document.addEventListener("mousedown",X),document.addEventListener("mouseup",X),document.addEventListener("pointermove",X),document.addEventListener("pointerdown",X),document.addEventListener("pointerup",X),document.addEventListener("touchmove",X),document.addEventListener("touchstart",X),document.addEventListener("touchend",X)}function Y(){document.removeEventListener("mousemove",X),document.removeEventListener("mousedown",X),document.removeEventListener("mouseup",X),document.removeEventListener("pointermove",X),document.removeEventListener("pointerdown",X),document.removeEventListener("pointerup",X),document.removeEventListener("touchmove",X),document.removeEventListener("touchstart",X),document.removeEventListener("touchend",X)}function X(C){C.target.nodeName&&C.target.nodeName.toLowerCase()==="html"||(o=!1,Y())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",b,!0),U(),r.addEventListener("focus",h,!0),r.addEventListener("blur",v,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var eo=Lr((Ft,Zr)=>{(function(t,r){typeof Ft=="object"&&typeof Zr=="object"?Zr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Ft=="object"?Ft.ClipboardJS=r():t.ClipboardJS=r()})(Ft,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return ki}});var a=i(279),s=i.n(a),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(q){try{return document.execCommand(q)}catch(_){return!1}}var h=function(_){var L=f()(_);return u("cut"),L},v=h;function b(q){var _=document.documentElement.getAttribute("dir")==="rtl",L=document.createElement("textarea");L.style.fontSize="12pt",L.style.border="0",L.style.padding="0",L.style.margin="0",L.style.position="absolute",L.style[_?"right":"left"]="-9999px";var F=window.pageYOffset||document.documentElement.scrollTop;return L.style.top="".concat(F,"px"),L.setAttribute("readonly",""),L.value=q,L}var U=function(_,L){var F=b(_);L.container.appendChild(F);var V=f()(F);return u("copy"),F.remove(),V},Y=function(_){var L=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},F="";return typeof _=="string"?F=U(_,L):_ instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(_==null?void 0:_.type)?F=U(_.value,L):(F=f()(_),u("copy")),F},X=Y;function C(q){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?C=function(L){return typeof L}:C=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},C(q)}var et=function(){var _=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},L=_.action,F=L===void 0?"copy":L,V=_.container,G=_.target,Ie=_.text;if(F!=="copy"&&F!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(G!==void 0)if(G&&C(G)==="object"&&G.nodeType===1){if(F==="copy"&&G.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(F==="cut"&&(G.hasAttribute("readonly")||G.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ie)return X(Ie,{container:V});if(G)return F==="cut"?v(G):X(G,{container:V})},H=et;function B(q){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?B=function(L){return typeof L}:B=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},B(q)}function ce(q,_){if(!(q instanceof _))throw new TypeError("Cannot call a class as a function")}function ue(q,_){for(var L=0;L<_.length;L++){var F=_[L];F.enumerable=F.enumerable||!1,F.configurable=!0,"value"in F&&(F.writable=!0),Object.defineProperty(q,F.key,F)}}function we(q,_,L){return _&&ue(q.prototype,_),L&&ue(q,L),q}function Ye(q,_){if(typeof _!="function"&&_!==null)throw new TypeError("Super expression must either be null or a function");q.prototype=Object.create(_&&_.prototype,{constructor:{value:q,writable:!0,configurable:!0}}),_&&Tr(q,_)}function Tr(q,_){return Tr=Object.setPrototypeOf||function(F,V){return F.__proto__=V,F},Tr(q,_)}function Mi(q){var _=Ai();return function(){var F=Ut(q),V;if(_){var G=Ut(this).constructor;V=Reflect.construct(F,arguments,G)}else V=F.apply(this,arguments);return Li(this,V)}}function Li(q,_){return _&&(B(_)==="object"||typeof _=="function")?_:_i(q)}function _i(q){if(q===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return q}function Ai(){if(typeof Reflect=="undefined"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(q){return!1}}function Ut(q){return Ut=Object.setPrototypeOf?Object.getPrototypeOf:function(L){return L.__proto__||Object.getPrototypeOf(L)},Ut(q)}function Sr(q,_){var L="data-clipboard-".concat(q);if(_.hasAttribute(L))return _.getAttribute(L)}var Ci=function(q){Ye(L,q);var _=Mi(L);function L(F,V){var G;return ce(this,L),G=_.call(this),G.resolveOptions(V),G.listenClick(F),G}return we(L,[{key:"resolveOptions",value:function(){var V=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof V.action=="function"?V.action:this.defaultAction,this.target=typeof V.target=="function"?V.target:this.defaultTarget,this.text=typeof V.text=="function"?V.text:this.defaultText,this.container=B(V.container)==="object"?V.container:document.body}},{key:"listenClick",value:function(V){var G=this;this.listener=p()(V,"click",function(Ie){return G.onClick(Ie)})}},{key:"onClick",value:function(V){var G=V.delegateTarget||V.currentTarget,Ie=this.action(G)||"copy",Dt=H({action:Ie,container:this.container,target:this.target(G),text:this.text(G)});this.emit(Dt?"success":"error",{action:Ie,text:Dt,trigger:G,clearSelection:function(){G&&G.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(V){return Sr("action",V)}},{key:"defaultTarget",value:function(V){var G=Sr("target",V);if(G)return document.querySelector(G)}},{key:"defaultText",value:function(V){return Sr("text",V)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(V){var G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return X(V,G)}},{key:"cut",value:function(V){return v(V)}},{key:"isSupported",value:function(){var V=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],G=typeof V=="string"?[V]:V,Ie=!!document.queryCommandSupported;return G.forEach(function(Dt){Ie=Ie&&!!document.queryCommandSupported(Dt)}),Ie}}]),L}(s()),ki=Ci},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,c){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(c))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,h,v){var b=p.apply(this,arguments);return l.addEventListener(u,b,v),{destroy:function(){l.removeEventListener(u,b,v)}}}function c(l,f,u,h,v){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(b){return s(b,f,u,h,v)}))}function p(l,f,u,h){return function(v){v.delegateTarget=a(v.target,f),v.delegateTarget&&h.call(l,v)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function c(u,h,v){if(!u&&!h&&!v)throw new Error("Missing required arguments");if(!a.string(h))throw new TypeError("Second argument must be a String");if(!a.fn(v))throw new TypeError("Third argument must be a Function");if(a.node(u))return p(u,h,v);if(a.nodeList(u))return l(u,h,v);if(a.string(u))return f(u,h,v);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,h,v){return u.addEventListener(h,v),{destroy:function(){u.removeEventListener(h,v)}}}function l(u,h,v){return Array.prototype.forEach.call(u,function(b){b.addEventListener(h,v)}),{destroy:function(){Array.prototype.forEach.call(u,function(b){b.removeEventListener(h,v)})}}}function f(u,h,v){return s(document.body,u,h,v)}o.exports=c},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),a=c.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var c=this;function p(){c.off(i,p),a.apply(s,arguments)}return p._=a,this.on(i,p,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=s.length;for(c;c{"use strict";var za=/["'&<>]/;Xn.exports=qa;function qa(e){var t=""+e,r=za.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function K(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function Q(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||s(u,h)})})}function s(u,h){try{c(o[u](h))}catch(v){f(i[0][3],v)}}function c(u){u.value instanceof ct?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){s("next",u)}function l(u){s("throw",u)}function f(u,h){u(h),i.shift(),i.length&&s(i[0][0],i[0][1])}}function bo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Te=="function"?Te(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,c){a=e[i](a),n(s,c,a.done,a.value)})}}function n(i,a,s,c){Promise.resolve(c).then(function(p){i({value:p,done:s})},a)}}function k(e){return typeof e=="function"}function ut(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Kt=ut(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Be(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var De=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=Te(a),c=s.next();!c.done;c=s.next()){var p=c.value;p.remove(this)}}catch(b){t={error:b}}finally{try{c&&!c.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(b){i=b instanceof Kt?b.errors:[b]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=Te(f),h=u.next();!h.done;h=u.next()){var v=h.value;try{vo(v)}catch(b){i=i!=null?i:[],b instanceof Kt?i=Q(Q([],K(i)),K(b.errors)):i.push(b)}}}catch(b){o={error:b}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Kt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)vo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Be(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Be(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Cr=De.EMPTY;function Qt(e){return e instanceof De||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function vo(e){k(e)?e():e.unsubscribe()}var Fe={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var dt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Cr:(this.currentObservers=null,s.push(r),new De(function(){o.currentObservers=null,Be(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new D;return r.source=this,r},t.create=function(r,o){return new Oo(r,o)},t}(D);var Oo=function(e){le(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Cr},t}(w);var At={now:function(){return(At.delegate||Date).now()},delegate:void 0};var Ct=function(e){le(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=At);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,c=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=vt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(vt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(Gt);var _o=function(e){le(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(Jt);var Se=new _o(Lo);var M=new D(function(e){return e.complete()});function Xt(e){return e&&k(e.schedule)}function Fr(e){return e[e.length-1]}function tt(e){return k(Fr(e))?e.pop():void 0}function Re(e){return Xt(Fr(e))?e.pop():void 0}function Zt(e,t){return typeof Fr(e)=="number"?e.pop():t}var gt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function er(e){return k(e==null?void 0:e.then)}function tr(e){return k(e[bt])}function rr(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function or(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function qi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var nr=qi();function ir(e){return k(e==null?void 0:e[nr])}function ar(e){return ho(this,arguments,function(){var r,o,n,i;return qt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,ct(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,ct(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,ct(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function sr(e){return k(e==null?void 0:e.getReader)}function P(e){if(e instanceof D)return e;if(e!=null){if(tr(e))return Ki(e);if(gt(e))return Qi(e);if(er(e))return Yi(e);if(rr(e))return Ao(e);if(ir(e))return Bi(e);if(sr(e))return Gi(e)}throw or(e)}function Ki(e){return new D(function(t){var r=e[bt]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Qi(e){return new D(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?y(function(n,i){return e(n,i,o)}):de,he(1),r?je(t):Ko(function(){return new pr}))}}function Vr(e){return e<=0?function(){return M}:g(function(t,r){var o=[];t.subscribe(x(r,function(n){o.push(n),e=2,!0))}function be(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new w}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,c=s===void 0?!0:s;return function(p){var l,f,u,h=0,v=!1,b=!1,U=function(){f==null||f.unsubscribe(),f=void 0},Y=function(){U(),l=u=void 0,v=b=!1},X=function(){var C=l;Y(),C==null||C.unsubscribe()};return g(function(C,et){h++,!b&&!v&&U();var H=u=u!=null?u:r();et.add(function(){h--,h===0&&!b&&!v&&(f=qr(X,c))}),H.subscribe(et),!l&&h>0&&(l=new lt({next:function(B){return H.next(B)},error:function(B){b=!0,U(),f=qr(Y,n,B),H.error(B)},complete:function(){v=!0,U(),f=qr(Y,a),H.complete()}}),P(C).subscribe(l))})(p)}}function qr(e,t){for(var r=[],o=2;oe.next(document)),e}function R(e,t=document){return Array.from(t.querySelectorAll(e))}function I(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Ue(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}var da=S(d(document.body,"focusin"),d(document.body,"focusout")).pipe(Ee(1),z(void 0),m(()=>Ue()||document.body),ee(1));function Et(e){return da.pipe(m(t=>e.contains(t)),te())}function fr(e,t){return S(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?Ee(t):de,z(!1))}function ze(e){return{x:e.offsetLeft,y:e.offsetTop}}function Jo(e){return S(d(window,"load"),d(window,"resize")).pipe(He(0,Se),m(()=>ze(e)),z(ze(e)))}function ur(e){return{x:e.scrollLeft,y:e.scrollTop}}function it(e){return S(d(e,"scroll"),d(window,"resize")).pipe(He(0,Se),m(()=>ur(e)),z(ur(e)))}function Xo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Xo(e,r)}function O(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Xo(o,n);return o}function dr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function wt(e){let t=O("script",{src:e});return $(()=>(document.head.appendChild(t),S(d(t,"load"),d(t,"error").pipe(E(()=>jr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),A(()=>document.head.removeChild(t)),he(1))))}var Zo=new w,ha=$(()=>typeof ResizeObserver=="undefined"?wt("https://unpkg.com/resize-observer-polyfill/dist/ResizeObserver.js"):W(void 0)).pipe(m(()=>new ResizeObserver(e=>{for(let t of e)Zo.next(t)})),E(e=>S(Je,W(e)).pipe(A(()=>e.disconnect()))),ee(1));function ve(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Ce(e){return ha.pipe(T(t=>t.observe(e)),E(t=>Zo.pipe(y(({target:r})=>r===e),A(()=>t.unobserve(e)),m(()=>ve(e)))),z(ve(e)))}function Tt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function St(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var en=new w,ba=$(()=>W(new IntersectionObserver(e=>{for(let t of e)en.next(t)},{threshold:0}))).pipe(E(e=>S(Je,W(e)).pipe(A(()=>e.disconnect()))),ee(1));function Ot(e){return ba.pipe(T(t=>t.observe(e)),E(t=>en.pipe(y(({target:r})=>r===e),A(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function tn(e,t=16){return it(e).pipe(m(({y:r})=>{let o=ve(e),n=Tt(e);return r>=n.height-o.height-t}),te())}var hr={drawer:I("[data-md-toggle=drawer]"),search:I("[data-md-toggle=search]")};function rn(e){return hr[e].checked}function Ze(e,t){hr[e].checked!==t&&hr[e].click()}function qe(e){let t=hr[e];return d(t,"change").pipe(m(()=>t.checked),z(t.checked))}function va(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function ga(){return S(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(z(!1))}function on(){let e=d(window,"keydown").pipe(y(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:rn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),y(({mode:t,type:r})=>{if(t==="global"){let o=Ue();if(typeof o!="undefined")return!va(o,r)}return!0}),be());return ga().pipe(E(t=>t?M:e))}function ge(){return new URL(location.href)}function ft(e,t=!1){if(J("navigation.instant")&&!t){let r=O("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function nn(){return new w}function an(){return location.hash.slice(1)}function br(e){let t=O("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Br(e){return S(d(window,"hashchange"),e).pipe(m(an),z(an()),y(t=>t.length>0),ee(1))}function sn(e){return Br(e).pipe(m(t=>fe(`[id="${t}"]`)),y(t=>typeof t!="undefined"))}function Pt(e){let t=matchMedia(e);return lr(r=>t.addListener(()=>r(t.matches))).pipe(z(t.matches))}function cn(){let e=matchMedia("print");return S(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(z(e.matches))}function Gr(e,t){return e.pipe(E(r=>r?t():M))}function vr(e,t){return new D(r=>{let o=new XMLHttpRequest;o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network Error"))}),o.addEventListener("abort",()=>{r.error(new Error("Request aborted"))}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{t.progress$.next(n.loaded/n.total*100)}),t.progress$.next(5)),o.send()})}function Ke(e,t){return vr(e,t).pipe(E(r=>r.text()),m(r=>JSON.parse(r)),ee(1))}function pn(e,t){let r=new DOMParser;return vr(e,t).pipe(E(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),ee(1))}function ln(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function mn(){return S(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(ln),z(ln()))}function fn(){return{width:innerWidth,height:innerHeight}}function un(){return d(window,"resize",{passive:!0}).pipe(m(fn),z(fn()))}function dn(){return Z([mn(),un()]).pipe(m(([e,t])=>({offset:e,size:t})),ee(1))}function gr(e,{viewport$:t,header$:r}){let o=t.pipe(ne("size")),n=Z([o,r]).pipe(m(()=>ze(e)));return Z([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:c,y:p}])=>({offset:{x:a.x-c,y:a.y-p+i},size:s})))}function xa(e){return d(e,"message",t=>t.data)}function ya(e){let t=new w;return t.subscribe(r=>e.postMessage(r)),t}function hn(e,t=new Worker(e)){let r=xa(t),o=ya(t),n=new w;n.subscribe(o);let i=o.pipe(oe(),se(!0));return n.pipe(oe(),Ne(r.pipe(N(i))),be())}var Ea=I("#__config"),Mt=JSON.parse(Ea.textContent);Mt.base=`${new URL(Mt.base,ge())}`;function xe(){return Mt}function J(e){return Mt.features.includes(e)}function _e(e,t){return typeof t!="undefined"?Mt.translations[e].replace("#",t.toString()):Mt.translations[e]}function ke(e,t=document){return I(`[data-md-component=${e}]`,t)}function pe(e,t=document){return R(`[data-md-component=${e}]`,t)}function wa(e){let t=I(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>I(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function bn(e){if(!J("announce.dismiss")||!e.childElementCount)return M;if(!e.hidden){let t=I(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return $(()=>{let t=new w;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),wa(e).pipe(T(r=>t.next(r)),A(()=>t.complete()),m(r=>j({ref:e},r)))})}function Ta(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function vn(e,t){let r=new w;return r.subscribe(({hidden:o})=>{e.hidden=o}),Ta(e,t).pipe(T(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))}function It(e,t){return t==="inline"?O("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},O("div",{class:"md-tooltip__inner md-typeset"})):O("div",{class:"md-tooltip",id:e,role:"tooltip"},O("div",{class:"md-tooltip__inner md-typeset"}))}function gn(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return O("aside",{class:"md-annotation",tabIndex:0},It(t),O("a",{href:r,class:"md-annotation__index",tabIndex:-1},O("span",{"data-md-annotation-id":e})))}else return O("aside",{class:"md-annotation",tabIndex:0},It(t),O("span",{class:"md-annotation__index",tabIndex:-1},O("span",{"data-md-annotation-id":e})))}function xn(e){return O("button",{class:"md-code__button",title:_e("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function yn(){return O("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function En(){return O("nav",{class:"md-code__nav"})}function Jr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,O("del",null,p)," "],[]).slice(0,-1),i=xe(),a=new URL(e.location,i.base);J("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:s}=xe();return O("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},O("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&O("div",{class:"md-search-result__icon md-icon"}),r>0&&O("h1",null,e.title),r<=0&&O("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=s?c in s?`md-tag-icon md-tag--${s[c]}`:"md-tag-icon":"";return O("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&O("p",{class:"md-search-result__terms"},_e("search.result.term.missing"),": ",...n)))}function wn(e){let t=e[0].score,r=[...e],o=xe(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreJr(l,1)),...c.length?[O("details",{class:"md-search-result__more"},O("summary",{tabIndex:-1},O("div",null,c.length>0&&c.length===1?_e("search.result.more.one"):_e("search.result.more.other",c.length))),...c.map(l=>Jr(l,1)))]:[]];return O("li",{class:"md-search-result__item"},p)}function Tn(e){return O("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>O("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?dr(r):r)))}function Xr(e){let t=`tabbed-control tabbed-control--${e}`;return O("div",{class:t,hidden:!0},O("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function Sn(e){return O("div",{class:"md-typeset__scrollwrap"},O("div",{class:"md-typeset__table"},e))}function Sa(e){let t=xe(),r=new URL(`../${e.version}/`,t.base);return O("li",{class:"md-version__item"},O("a",{href:`${r}`,class:"md-version__link"},e.title))}function On(e,t){return O("div",{class:"md-version"},O("button",{class:"md-version__current","aria-label":_e("select.version")},t.title),O("ul",{class:"md-version__list"},e.map(Sa)))}var Oa=0;function Ma(e,t){document.body.append(e);let{width:r}=ve(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=St(t),n=typeof o!="undefined"?it(o):W({x:0,y:0}),i=S(Et(t),fr(t)).pipe(te());return Z([i,n]).pipe(m(([a,s])=>{let{x:c,y:p}=ze(t),l=ve(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:c-s.x+l.width/2-r/2,y:p-s.y+l.height+8}}}))}function Qe(e){let t=e.title;if(!t.length)return M;let r=`__tooltip_${Oa++}`,o=It(r,"inline"),n=I(".md-typeset",o);return n.innerHTML=t,$(()=>{let i=new w;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),S(i.pipe(y(({active:a})=>a)),i.pipe(Ee(250),y(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(He(16,Se)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(Rt(125,Se),y(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Ma(o,e).pipe(T(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))}).pipe(Ge(ae))}function La(e,t){let r=$(()=>Z([Jo(e),it(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=ve(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return Et(e).pipe(E(o=>r.pipe(m(n=>({active:o,offset:n})),he(+!o||1/0))))}function Mn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return $(()=>{let i=new w,a=i.pipe(oe(),se(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),Ot(e).pipe(N(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),S(i.pipe(y(({active:s})=>s)),i.pipe(Ee(250),y(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(He(16,Se)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(Rt(125,Se),y(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(N(a),y(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),d(n,"mousedown").pipe(N(a),ie(i)).subscribe(([s,{active:c}])=>{var p;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(c){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Ue())==null||p.blur()}}),r.pipe(N(a),y(s=>s===o),Xe(125)).subscribe(()=>e.focus()),La(e,t).pipe(T(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))})}function _a(e){let t=xe();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(typeof t.annotate!="undefined"){let o=e.closest("[class|=language]");if(o)for(let n of Array.from(o.classList)){if(!n.startsWith("language-"))continue;let[,i]=n.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return R(r.join(", "),e)}function Aa(e){let t=[];for(let r of _a(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,c]=a;if(typeof c=="undefined"){let p=i.splitText(a.index);i=p.splitText(s.length),t.push(p)}else{i.textContent=s,t.push(i);break}}}}return t}function Ln(e,t){t.append(...Array.from(e.childNodes))}function xr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Aa(t)){let[,c]=s.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${c})`,e)&&(a.set(c,gn(c,i)),s.replaceWith(a.get(c)))}return a.size===0?M:$(()=>{let s=new w,c=s.pipe(oe(),se(!0)),p=[];for(let[l,f]of a)p.push([I(".md-typeset",f),I(`:scope > li:nth-child(${l})`,e)]);return o.pipe(N(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?Ln(f,u):Ln(u,f)}),S(...[...a].map(([,l])=>Mn(l,t,{target$:r}))).pipe(A(()=>s.complete()),be())})}function _n(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return _n(t)}}function An(e,t){return $(()=>{let r=_n(e);return typeof r!="undefined"?xr(r,e,t):M})}var kn=zt(eo());var Ca=0,Cn=S(d(window,"keydown").pipe(m(()=>!0)),S(d(window,"keyup"),d(window,"contextmenu")).pipe(m(()=>!1))).pipe(z(!1),ee(1));function Hn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Hn(t)}}function ka(e){return Ce(e).pipe(m(({width:t})=>({scrollable:Tt(e).width>t})),ne("scrollable"))}function $n(e,t){let{matches:r}=matchMedia("(hover)"),o=$(()=>{let n=new w,i=n.pipe(Vr(1));n.subscribe(({scrollable:u})=>{u&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=Ca++,s=[],c=e.closest("pre");c.id=`__code_${a}`;let p=[],l=e.closest(".highlight");if(l instanceof HTMLElement){let u=Hn(l);if(typeof u!="undefined"&&(l.classList.contains("annotate")||J("content.code.annotate"))){let h=xr(u,e,t);p.push(Ce(l).pipe(N(i),m(({width:v,height:b})=>v&&b),te(),E(v=>v?h:M)))}}let f=R(":scope > span[id]",e);if(f.length&&(e.classList.add("md-code__content"),e.closest(".select")||J("content.code.select")&&!e.closest(".no-select"))){let u=+f[0].id.split("-").pop(),h=yn();s.push(h),J("content.tooltips")&&p.push(Qe(h));let v=d(h,"click").pipe($t(H=>!H,!1),T(()=>h.blur()),be());v.subscribe(H=>{h.classList.toggle("md-code__button--active",H)});let b=me(f).pipe(re(H=>fr(H).pipe(m(B=>[H,B]))));v.pipe(E(H=>H?b:M)).subscribe(([H,B])=>{let ce=fe(".hll.select",H);if(ce&&!B)ce.replaceWith(...Array.from(ce.childNodes));else if(!ce&&B){let ue=document.createElement("span");ue.className="hll select",ue.append(...Array.from(H.childNodes).slice(1)),H.append(ue)}});let U=me(f).pipe(re(H=>d(H,"mousedown").pipe(T(B=>B.preventDefault()),m(()=>H)))),Y=v.pipe(E(H=>H?U:M),ie(Cn),m(([H,B])=>{var ue;let ce=f.indexOf(H)+u;if(B===!1)return[ce,ce];{let we=R(".hll",e).map(Ye=>f.indexOf(Ye.parentElement)+u);return(ue=window.getSelection())==null||ue.removeAllRanges(),[Math.min(ce,...we),Math.max(ce,...we)]}})),X=Br(M).pipe(y(H=>H.startsWith(`__codelineno-${a}-`)));X.subscribe(H=>{let[,,B]=H.split("-"),ce=B.split(":").map(we=>+we-u+1);ce.length===1&&ce.push(ce[0]);for(let we of R(".hll:not(.select)",e))we.replaceWith(...Array.from(we.childNodes));let ue=f.slice(ce[0]-1,ce[1]);for(let we of ue){let Ye=document.createElement("span");Ye.className="hll",Ye.append(...Array.from(we.childNodes).slice(1)),we.append(Ye)}}),X.pipe(he(1),Oe(ae)).subscribe(H=>{if(H.includes(":")){let B=document.getElementById(H.split(":")[0]);B&&setTimeout(()=>{let ce=B,ue=-(48+16);for(;ce!==document.body;)ue+=ce.offsetTop,ce=ce.offsetParent;window.scrollTo({top:ue})},1)}});let et=me(R('a[href^="#__codelineno"]',l)).pipe(re(H=>d(H,"click").pipe(T(B=>B.preventDefault()),m(()=>H)))).pipe(N(i),ie(Cn),m(([H,B])=>{let ue=+I(`[id="${H.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(B===!1)return[ue,ue];{let we=R(".hll",e).map(Ye=>+Ye.parentElement.id.split("-").pop());return[Math.min(ue,...we),Math.max(ue,...we)]}}));S(Y,et).subscribe(H=>{let B=`#__codelineno-${a}-`;H[0]===H[1]?B+=H[0]:B+=`${H[0]}:${H[1]}`,history.replaceState({},"",B),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+B,oldURL:window.location.href}))})}if(kn.default.isSupported()&&(e.closest(".copy")||J("content.code.copy")&&!e.closest(".no-copy"))){let u=xn(c.id);s.push(u),J("content.tooltips")&&p.push(Qe(u))}if(s.length){let u=En();u.append(...s),c.insertBefore(u,e)}return ka(e).pipe(T(u=>n.next(u)),A(()=>n.complete()),m(u=>j({ref:e},u)),Ne(...p))});return J("content.lazy")?Ot(e).pipe(y(n=>n),he(1),E(()=>o)):o}function Ha(e,{target$:t,print$:r}){let o=!0;return S(t.pipe(m(n=>n.closest("details:not([open])")),y(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(y(n=>n||!o),T(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Rn(e,t){return $(()=>{let r=new w;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Ha(e,t).pipe(T(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}var Pn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var to,Ra=0;function Pa(){return typeof mermaid=="undefined"||mermaid instanceof Element?wt("https://unpkg.com/mermaid@9.4.3/dist/mermaid.min.js"):W(void 0)}function In(e){return e.classList.remove("mermaid"),to||(to=Pa().pipe(T(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Pn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),ee(1))),to.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${Ra++}`,r=O("div",{class:"mermaid"}),o=e.textContent;mermaid.mermaidAPI.render(t,o,(n,i)=>{let a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})}),to.pipe(m(()=>({ref:e})))}var Fn=O("table");function jn(e){return e.replaceWith(Fn),Fn.replaceWith(Sn(e)),W({ref:e})}function Ia(e){let t=e.find(r=>r.checked)||e[0];return S(...e.map(r=>d(r,"change").pipe(m(()=>I(`label[for="${r.id}"]`))))).pipe(z(I(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Wn(e,{viewport$:t,target$:r}){let o=I(".tabbed-labels",e),n=R(":scope > input",e),i=Xr("prev");e.append(i);let a=Xr("next");return e.append(a),$(()=>{let s=new w,c=s.pipe(oe(),se(!0));Z([s,Ce(e)]).pipe(N(c),He(1,Se)).subscribe({next([{active:p},l]){let f=ze(p),{width:u}=ve(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=ur(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),Z([it(o),Ce(o)]).pipe(N(c)).subscribe(([p,l])=>{let f=Tt(o);i.hidden=p.x<16,a.hidden=p.x>f.width-l.width-16}),S(d(i,"click").pipe(m(()=>-1)),d(a,"click").pipe(m(()=>1))).pipe(N(c)).subscribe(p=>{let{width:l}=ve(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(N(c),y(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=I(`label[for="${p.id}"]`);l.replaceChildren(O("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(N(c),y(f=>!(f.metaKey||f.ctrlKey)),T(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return J("content.tabs.link")&&s.pipe(Le(1),ie(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let v of R("[data-tabs]"))for(let b of R(":scope > input",v)){let U=I(`label[for="${b.id}"]`);if(U!==p&&U.innerText.trim()===f){U.setAttribute("data-md-switching",""),b.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),s.pipe(N(c)).subscribe(()=>{for(let p of R("audio, video",e))p.pause()}),Ia(n).pipe(T(p=>s.next(p)),A(()=>s.complete()),m(p=>j({ref:e},p)))}).pipe(Ge(ae))}function Nn(e,{viewport$:t,target$:r,print$:o}){return S(...R(".annotate:not(.highlight)",e).map(n=>An(n,{target$:r,print$:o})),...R("pre:not(.mermaid) > code",e).map(n=>$n(n,{target$:r,print$:o})),...R("pre.mermaid",e).map(n=>In(n)),...R("table:not([class])",e).map(n=>jn(n)),...R("details",e).map(n=>Rn(n,{target$:r,print$:o})),...R("[data-tabs]",e).map(n=>Wn(n,{viewport$:t,target$:r})),...R("[title]",e).filter(()=>J("content.tooltips")).map(n=>Qe(n)))}function Fa(e,{alert$:t}){return t.pipe(E(r=>S(W(!0),W(!1).pipe(Xe(2e3))).pipe(m(o=>({message:r,active:o})))))}function Un(e,t){let r=I(".md-typeset",e);return $(()=>{let o=new w;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Fa(e,t).pipe(T(n=>o.next(n)),A(()=>o.complete()),m(n=>j({ref:e},n)))})}function ja({viewport$:e}){if(!J("header.autohide"))return W(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Pe(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),te()),o=qe("search");return Z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),te(),E(n=>n?r:W(!1)),z(!1))}function Dn(e,t){return $(()=>Z([Ce(e),ja(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),te((r,o)=>r.height===o.height&&r.hidden===o.hidden),ee(1))}function Vn(e,{header$:t,main$:r}){return $(()=>{let o=new w,n=o.pipe(oe(),se(!0));o.pipe(ne("active"),nt(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=me(R("[title]",e)).pipe(y(()=>J("content.tooltips")),re(a=>Qe(a)));return r.subscribe(o),t.pipe(N(n),m(a=>j({ref:e},a)),Ne(i.pipe(N(n))))})}function Wa(e,{viewport$:t,header$:r}){return gr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ve(e);return{active:o>=n}}),ne("active"))}function zn(e,t){return $(()=>{let r=new w;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?M:Wa(o,t).pipe(T(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))})}function qn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),te()),n=o.pipe(E(()=>Ce(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),ne("bottom"))));return Z([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,a-c,i)-Math.max(0,p+c-s)),{offset:a-i,height:p,active:a-i<=c})),te((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Na(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return W(...e).pipe(re(r=>d(r,"change").pipe(m(()=>r))),z(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{media:r.getAttribute("data-md-color-media"),scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),ee(1))}function Kn(e){let t=R("input",e),r=O("meta",{name:"theme-color"});document.head.appendChild(r);let o=O("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Pt("(prefers-color-scheme: light)");return $(()=>{let i=new w;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=c.getAttribute("data-md-color-scheme"),a.color.primary=c.getAttribute("data-md-color-primary"),a.color.accent=c.getAttribute("data-md-color-accent")}for(let[s,c]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,c);for(let s=0;s{let a=ke("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(Oe(ae)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Na(t).pipe(N(n.pipe(Le(1))),mt(),T(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))})}function Qn(e,{progress$:t}){return $(()=>{let r=new w;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(T(o=>r.next({value:o})),A(()=>r.complete()),m(o=>({ref:e,value:o})))})}var ro=zt(eo());function Ua(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r}function Yn({alert$:e}){ro.default.isSupported()&&new D(t=>{new ro.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Ua(I(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(T(t=>{t.trigger.focus()}),m(()=>_e("clipboard.copied"))).subscribe(e)}function Da(e){if(e.length<2)return[""];let[t,r]=[...e].sort((n,i)=>n.length-i.length).map(n=>n.replace(/[^/]+$/,"")),o=0;if(t===r)o=t.length;else for(;t.charCodeAt(o)===r.charCodeAt(o);)o++;return e.map(n=>n.replace(t.slice(0,o),""))}function yr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return W(t);{let r=xe();return pn(new URL("sitemap.xml",e||r.base)).pipe(m(o=>Da(R("loc",o).map(n=>n.textContent))),Me(()=>M),je([]),T(o=>__md_set("__sitemap",o,sessionStorage,e)))}}function Bn(e,t){if(!(e.target instanceof Element))return M;let r=e.target.closest("a");if(r===null)return M;if(r.target||e.metaKey||e.ctrlKey)return M;let o=new URL(r.href);return o.search=o.hash="",t.includes(`${o}`)?(e.preventDefault(),W(new URL(r.href))):M}function Gn(e){let t=I("[rel=canonical]",e);t.href=t.href.replace("//localhost:","//127.0.0.1");let r=new Map;for(let o of R(":scope > *",e)){let n=o.outerHTML;for(let i of["href","src"]){let a=o.getAttribute(i);if(a===null)continue;let s=new URL(a,t.href),c=o.cloneNode();c.setAttribute(i,`${s}`),n=c.outerHTML;break}r.set(n,o)}return r}function Jn({location$:e,viewport$:t,progress$:r}){let o=xe();if(location.protocol==="file:")return M;let n=yr().pipe(m(l=>l.map(f=>`${new URL(f,o.base)}`))),i=d(document.body,"click").pipe(ie(n),E(([l,f])=>Bn(l,f)),be());J("navigation.instant.prefetch")&&S(d(document.body,"mousemove"),d(document.body,"focusin")).pipe(ie(n),E(([l,f])=>Bn(l,f)),Ee(25),Dr(({href:l})=>l),mr(l=>{let f=document.createElement("link");return f.rel="prefetch",f.href=l.toString(),document.head.appendChild(f),d(f,"load").pipe(m(()=>f),he(1))})).subscribe(l=>l.remove()),i.pipe(he(1)).subscribe(()=>{let l=fe("link[rel=icon]");typeof l!="undefined"&&(l.href=l.href)}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),i.pipe(ie(t)).subscribe(([l,{offset:f}])=>{history.scrollRestoration="manual",history.replaceState(f,""),history.pushState(null,"",l)}),i.subscribe(e);let a=e.pipe(z(ge()),ne("pathname"),Le(1),E(l=>vr(l,{progress$:r}).pipe(Me(()=>(ft(l,!0),M))))),s=new DOMParser,c=a.pipe(E(l=>l.text()),E(l=>{let f=s.parseFromString(l,"text/html");for(let b of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...J("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let U=fe(b),Y=fe(b,f);typeof U!="undefined"&&typeof Y!="undefined"&&U.replaceWith(Y)}let u=Gn(document.head),h=Gn(f.head);for(let[b,U]of h)U.getAttribute("rel")==="stylesheet"||U.hasAttribute("src")||(u.has(b)?u.delete(b):document.head.appendChild(U));for(let b of u.values())b.getAttribute("rel")==="stylesheet"||b.hasAttribute("src")||b.remove();let v=ke("container");return Ve(R("script",v)).pipe(E(b=>{let U=f.createElement("script");if(b.src){for(let Y of b.getAttributeNames())U.setAttribute(Y,b.getAttribute(Y));return b.replaceWith(U),new D(Y=>{U.onload=()=>Y.complete()})}else return U.textContent=b.textContent,b.replaceWith(U),M}),oe(),se(f))}),be());return d(window,"popstate").pipe(m(ge)).subscribe(e),e.pipe(z(ge()),Pe(2,1),y(([l,f])=>l.pathname===f.pathname&&l.hash!==f.hash),m(([,l])=>l)).subscribe(l=>{var f,u;history.state!==null||!l.hash?window.scrollTo(0,(u=(f=history.state)==null?void 0:f.y)!=null?u:0):(history.scrollRestoration="auto",br(l.hash),history.scrollRestoration="manual")}),e.pipe(zr(i),z(ge()),Pe(2,1),y(([l,f])=>l.pathname===f.pathname&&l.hash===f.hash),m(([,l])=>l)).subscribe(l=>{history.scrollRestoration="auto",br(l.hash),history.scrollRestoration="manual",history.back()}),c.pipe(ie(e)).subscribe(([,l])=>{var f,u;history.state!==null||!l.hash?window.scrollTo(0,(u=(f=history.state)==null?void 0:f.y)!=null?u:0):br(l.hash)}),t.pipe(ne("offset"),Ee(100)).subscribe(({offset:l})=>{history.replaceState(l,"")}),c}var ei=zt(Zn());function ti(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,ei.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function jt(e){return e.type===1}function Er(e){return e.type===3}function ri(e,t){let r=hn(e);return S(W(location.protocol!=="file:"),qe("search")).pipe(We(o=>o),E(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:J("search.suggest")}}})),r}function oi({document$:e}){let t=xe(),r=Ke(new URL("../versions.json",t.base)).pipe(Me(()=>M)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),E(n=>d(document.body,"click").pipe(y(i=>!i.metaKey&&!i.ctrlKey),ie(o),E(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let c=s.href;return!i.target.closest(".md-version")&&n.get(c)===a?M:(i.preventDefault(),W(c))}}return M}),E(i=>{let{version:a}=n.get(i);return yr(new URL(i)).pipe(m(s=>{let p=ge().href.replace(t.base,"");return s.includes(p.split("#")[0])?new URL(`../${a}/${p}`,t.base):new URL(i)}))})))).subscribe(n=>ft(n,!0)),Z([r,o]).subscribe(([n,i])=>{I(".md-header__topic").appendChild(On(n,i))}),e.pipe(E(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let c of s)for(let p of n.aliases)if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of pe("outdated"))s.hidden=!1})}function Qa(e,{worker$:t}){let{searchParams:r}=ge();r.has("q")&&(Ze("search",!0),e.value=r.get("q"),e.focus(),qe("search").pipe(We(i=>!i)).subscribe(()=>{let i=ge();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Et(e),n=S(t.pipe(We(jt)),d(e,"keyup"),o).pipe(m(()=>e.value),te());return Z([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),ee(1))}function ni(e,{worker$:t}){let r=new w,o=r.pipe(oe(),se(!0));Z([t.pipe(We(jt)),r],(i,a)=>a).pipe(ne("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(ne("focus")).subscribe(({focus:i})=>{i&&Ze("search",i)}),d(e.form,"reset").pipe(N(o)).subscribe(()=>e.focus());let n=I("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),Qa(e,{worker$:t}).pipe(T(i=>r.next(i)),A(()=>r.complete()),m(i=>j({ref:e},i)),ee(1))}function ii(e,{worker$:t,query$:r}){let o=new w,n=tn(e.parentElement).pipe(y(Boolean)),i=e.parentElement,a=I(":scope > :first-child",e),s=I(":scope > :last-child",e);qe("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(ie(r),Kr(t.pipe(We(jt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?_e("search.result.none"):_e("search.result.placeholder");break;case 1:a.textContent=_e("search.result.one");break;default:let u=dr(l.length);a.textContent=_e("search.result.other",u)}});let c=o.pipe(T(()=>s.innerHTML=""),E(({items:l})=>S(W(...l.slice(0,10)),W(...l.slice(10)).pipe(Pe(4),Yr(n),E(([f])=>f)))),m(wn),be());return c.subscribe(l=>s.appendChild(l)),c.pipe(re(l=>{let f=fe("details",l);return typeof f=="undefined"?M:d(f,"toggle").pipe(N(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(y(Er),m(({data:l})=>l)).pipe(T(l=>o.next(l)),A(()=>o.complete()),m(l=>j({ref:e},l)))}function Ya(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=ge();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function ai(e,t){let r=new w,o=r.pipe(oe(),se(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(N(o)).subscribe(n=>n.preventDefault()),Ya(e,t).pipe(T(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))}function si(e,{worker$:t,keyboard$:r}){let o=new w,n=ke("search-query"),i=S(d(n,"keydown"),d(n,"focus")).pipe(Oe(ae),m(()=>n.value),te());return o.pipe(nt(i),m(([{suggest:s},c])=>{let p=c.split(/([\s-]+)/);if(s!=null&&s.length&&p[p.length-1]){let l=s[s.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(y(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(y(Er),m(({data:s})=>s)).pipe(T(s=>o.next(s)),A(()=>o.complete()),m(()=>({ref:e})))}function ci(e,{index$:t,keyboard$:r}){let o=xe();try{let n=ri(o.search,t),i=ke("search-query",e),a=ke("search-result",e);d(e,"click").pipe(y(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>Ze("search",!1)),r.pipe(y(({mode:c})=>c==="search")).subscribe(c=>{let p=Ue();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of R(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}c.claim()}break;case"Escape":case"Tab":Ze("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...R(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Ue()&&i.focus()}}),r.pipe(y(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let s=ni(i,{worker$:n});return S(s,ii(a,{worker$:n,query$:s})).pipe(Ne(...pe("search-share",e).map(c=>ai(c,{query$:s})),...pe("search-suggest",e).map(c=>si(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Je}}function pi(e,{index$:t,location$:r}){return Z([t,r.pipe(z(ge()),y(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>ti(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let c=s.textContent,p=o(c);p.length>c.length&&n.set(s,p)}for(let[s,c]of n){let{childNodes:p}=O("span",null,c);s.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Ba(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return Z([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),te((i,a)=>i.height===a.height&&i.locked===a.locked))}function oo(e,o){var n=o,{header$:t}=n,r=lo(n,["header$"]);let i=I(".md-sidebar__scrollwrap",e),{y:a}=ze(i);return $(()=>{let s=new w,c=s.pipe(oe(),se(!0)),p=s.pipe(He(0,Se));return p.pipe(ie(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(We()).subscribe(()=>{for(let l of R(".md-nav__link--active[href]",e)){let f=St(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ve(f);f.scrollTo({top:u-h/2})}}}),me(R("label[tabindex]",e)).pipe(re(l=>d(l,"click").pipe(Oe(ae),m(()=>l),N(c)))).subscribe(l=>{let f=I(`[id="${l.htmlFor}"]`);I(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Ba(e,r).pipe(T(l=>s.next(l)),A(()=>s.complete()),m(l=>j({ref:e},l)))})}function li(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Ht(Ke(`${r}/releases/latest`).pipe(Me(()=>M),m(o=>({version:o.tag_name})),je({})),Ke(r).pipe(Me(()=>M),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),je({}))).pipe(m(([o,n])=>j(j({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ke(r).pipe(m(o=>({repositories:o.public_repos})),je({}))}}function mi(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ke(r).pipe(Me(()=>M),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),je({}))}function fi(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return li(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return mi(r,o)}return M}var Ga;function Ja(e){return Ga||(Ga=$(()=>{let t=__md_get("__source",sessionStorage);if(t)return W(t);if(pe("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return M}return fi(e.href).pipe(T(o=>__md_set("__source",o,sessionStorage)))}).pipe(Me(()=>M),y(t=>Object.keys(t).length>0),m(t=>({facts:t})),ee(1)))}function ui(e){let t=I(":scope > :last-child",e);return $(()=>{let r=new w;return r.subscribe(({facts:o})=>{t.appendChild(Tn(o)),t.classList.add("md-source__repository--active")}),Ja(e).pipe(T(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Xa(e,{viewport$:t,header$:r}){return Ce(document.body).pipe(E(()=>gr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),ne("hidden"))}function di(e,t){return $(()=>{let r=new w;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(J("navigation.tabs.sticky")?W({hidden:!1}):Xa(e,t)).pipe(T(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Za(e,{viewport$:t,header$:r}){let o=new Map,n=R("[href^=\\#]",e);for(let s of n){let c=decodeURIComponent(s.hash.substring(1)),p=fe(`[id="${c}"]`);typeof p!="undefined"&&o.set(s,p)}let i=r.pipe(ne("height"),m(({height:s})=>{let c=ke("main"),p=I(":scope > :first-child",c);return s+.8*(p.offsetTop-c.offsetTop)}),be());return Ce(document.body).pipe(ne("height"),E(s=>$(()=>{let c=[];return W([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),nt(i),E(([c,p])=>t.pipe($t(([l,f],{offset:{y:u},size:h})=>{let v=u+h.height>=Math.floor(s.height);for(;f.length;){let[,b]=f[0];if(b-p=u&&!v)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),te((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,c])=>({prev:s.map(([p])=>p),next:c.map(([p])=>p)})),z({prev:[],next:[]}),Pe(2,1),m(([s,c])=>s.prev.length{let i=new w,a=i.pipe(oe(),se(!0));if(i.subscribe(({prev:s,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===s.length-1)}),J("toc.follow")){let s=S(t.pipe(Ee(1),m(()=>{})),t.pipe(Ee(250),m(()=>"smooth")));i.pipe(y(({prev:c})=>c.length>0),nt(o.pipe(Oe(ae))),ie(s)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=St(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ve(f);f.scrollTo({top:u-h/2,behavior:p})}}})}return J("navigation.tracking")&&t.pipe(N(a),ne("offset"),Ee(250),Le(1),N(n.pipe(Le(1))),mt({delay:250}),ie(i)).subscribe(([,{prev:s}])=>{let c=ge(),p=s[s.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Za(e,{viewport$:t,header$:r}).pipe(T(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))})}function es(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Pe(2,1),m(([a,s])=>a>s&&s>0),te()),i=r.pipe(m(({active:a})=>a));return Z([i,n]).pipe(m(([a,s])=>!(a&&s)),te(),N(o.pipe(Le(1))),se(!0),mt({delay:250}),m(a=>({hidden:a})))}function bi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new w,a=i.pipe(oe(),se(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(N(a),ne("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),d(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),es(e,{viewport$:t,main$:o,target$:n}).pipe(T(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))}function vi({document$:e}){e.pipe(E(()=>R(".md-ellipsis")),re(t=>Ot(t).pipe(N(e.pipe(Le(1))),y(r=>r),m(()=>t),he(1))),y(t=>t.offsetWidth{let r=t.innerText,o=t.closest("a")||t;return o.title=r,Qe(o).pipe(N(e.pipe(Le(1))),A(()=>o.removeAttribute("title")))})).subscribe(),e.pipe(E(()=>R(".md-status")),re(t=>Qe(t))).subscribe()}function gi({document$:e,tablet$:t}){e.pipe(E(()=>R(".md-toggle--indeterminate")),T(r=>{r.indeterminate=!0,r.checked=!1}),re(r=>d(r,"change").pipe(Qr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ie(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function ts(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function xi({document$:e}){e.pipe(E(()=>R("[data-md-scrollfix]")),T(t=>t.removeAttribute("data-md-scrollfix")),y(ts),re(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function yi({viewport$:e,tablet$:t}){Z([qe("search"),t]).pipe(m(([r,o])=>r&&!o),E(r=>W(r).pipe(Xe(r?400:100))),ie(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function rs(){return location.protocol==="file:"?wt(`${new URL("search/search_index.js",no.base)}`).pipe(m(()=>__index),ee(1)):Ke(new URL("search/search_index.json",no.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var st=Go(),Nt=nn(),Lt=sn(Nt),io=on(),$e=dn(),wr=Pt("(min-width: 960px)"),wi=Pt("(min-width: 1220px)"),Ti=cn(),no=xe(),Si=document.forms.namedItem("search")?rs():Je,ao=new w;Yn({alert$:ao});var so=new w;J("navigation.instant")&&Jn({location$:Nt,viewport$:$e,progress$:so}).subscribe(st);var Ei;((Ei=no.version)==null?void 0:Ei.provider)==="mike"&&oi({document$:st});S(Nt,Lt).pipe(Xe(125)).subscribe(()=>{Ze("drawer",!1),Ze("search",!1)});io.pipe(y(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&&ft(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&&ft(r);break;case"Enter":let o=Ue();o instanceof HTMLLabelElement&&o.click()}});vi({document$:st});gi({document$:st,tablet$:wr});xi({document$:st});yi({viewport$:$e,tablet$:wr});var at=Dn(ke("header"),{viewport$:$e}),Wt=st.pipe(m(()=>ke("main")),E(e=>qn(e,{viewport$:$e,header$:at})),ee(1)),os=S(...pe("consent").map(e=>vn(e,{target$:Lt})),...pe("dialog").map(e=>Un(e,{alert$:ao})),...pe("header").map(e=>Vn(e,{viewport$:$e,header$:at,main$:Wt})),...pe("palette").map(e=>Kn(e)),...pe("progress").map(e=>Qn(e,{progress$:so})),...pe("search").map(e=>ci(e,{index$:Si,keyboard$:io})),...pe("source").map(e=>ui(e))),ns=$(()=>S(...pe("announce").map(e=>bn(e)),...pe("content").map(e=>Nn(e,{viewport$:$e,target$:Lt,print$:Ti})),...pe("content").map(e=>J("search.highlight")?pi(e,{index$:Si,location$:Nt}):M),...pe("header-title").map(e=>zn(e,{viewport$:$e,header$:at})),...pe("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Gr(wi,()=>oo(e,{viewport$:$e,header$:at,main$:Wt})):Gr(wr,()=>oo(e,{viewport$:$e,header$:at,main$:Wt}))),...pe("tabs").map(e=>di(e,{viewport$:$e,header$:at})),...pe("toc").map(e=>hi(e,{viewport$:$e,header$:at,main$:Wt,target$:Lt})),...pe("top").map(e=>bi(e,{viewport$:$e,header$:at,main$:Wt,target$:Lt})))),Oi=st.pipe(E(()=>ns),Ne(os),ee(1));Oi.subscribe();window.document$=st;window.location$=Nt;window.target$=Lt;window.keyboard$=io;window.viewport$=$e;window.tablet$=wr;window.screen$=wi;window.print$=Ti;window.alert$=ao;window.progress$=so;window.component$=Oi;})(); diff --git a/assets/javascripts/workers/search.f2da59ea.min.js b/assets/javascripts/workers/search.1e90e0fb.min.js similarity index 75% rename from assets/javascripts/workers/search.f2da59ea.min.js rename to assets/javascripts/workers/search.1e90e0fb.min.js index b53ca59..ff43aed 100644 --- a/assets/javascripts/workers/search.f2da59ea.min.js +++ b/assets/javascripts/workers/search.1e90e0fb.min.js @@ -1,2 +1,2 @@ -"use strict";(()=>{var xe=Object.create;var G=Object.defineProperty,ve=Object.defineProperties,Se=Object.getOwnPropertyDescriptor,Te=Object.getOwnPropertyDescriptors,Qe=Object.getOwnPropertyNames,Y=Object.getOwnPropertySymbols,Ee=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Z=Math.pow,J=(t,e,r)=>e in t?G(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,_=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(Y)for(var r of Y(e))be.call(e,r)&&J(t,r,e[r]);return t},B=(t,e)=>ve(t,Te(e));var Le=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var we=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Qe(e))!X.call(t,i)&&i!==r&&G(t,i,{get:()=>e[i],enumerable:!(n=Se(e,i))||n.enumerable});return t};var Pe=(t,e,r)=>(r=t!=null?xe(Ee(t)):{},we(e||!t||!t.__esModule?G(r,"default",{value:t,enumerable:!0}):r,t));var W=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var te=Le((K,ee)=>{(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var l=t.utils.clone(r)||{};l.position=[a,c],l.index=s.length,s.push(new t.Token(n.slice(a,o),l))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?l+=2:a==u&&(r+=n[c+1]*i[l+1],c+=2,l+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.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 c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var l=s.str.charAt(0),g=s.str.charAt(1),f;g in s.node.edges?f=s.node.edges[g]:(f=new t.TokenSet,s.node.edges[g]=f),s.str.length==1&&(f.final=!0),i.push({node:f,editsRemaining:s.editsRemaining-1,str:l+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof K=="object"?ee.exports=r():e.lunr=r()}(this,function(){return t})})()});var de=Pe(te());function re(t,e=document){let r=ke(t,e);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${t}" to be present`);return r}function ke(t,e=document){return e.querySelector(t)||void 0}Object.entries||(Object.entries=function(t){let e=[];for(let r of Object.keys(t))e.push([r,t[r]]);return e});Object.values||(Object.values=function(t){let e=[];for(let r of Object.keys(t))e.push(t[r]);return e});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(t,e){typeof t=="object"?(this.scrollLeft=t.left,this.scrollTop=t.top):(this.scrollLeft=t,this.scrollTop=e)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...t){let e=this.parentNode;if(e){t.length===0&&e.removeChild(this);for(let r=t.length-1;r>=0;r--){let n=t[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));function ne(t){let e=new Map;for(let r of t){let[n]=r.location.split("#"),i=e.get(n);typeof i=="undefined"?e.set(n,r):(e.set(r.location,r),r.parent=i)}return e}function H(t,e,r){var s;e=new RegExp(e,"g");let n,i=0;do{n=e.exec(t);let o=(s=n==null?void 0:n.index)!=null?s:t.length;if(in?e(r,1,n,n=i):t.charAt(i)===">"&&(t.charAt(n+1)==="/"?--s===0&&e(r++,2,n,i+1):t.charAt(i-1)!=="/"&&s++===0&&e(r,0,n,i+1),n=i+1);i>n&&e(r,1,n,i)}function se(t,e,r){return q([t],e,r).pop()}function q(t,e,r){let n=[0];for(let i=1;i>>2&1023,u=o[0]>>>12;n.push(+(a>u)+n[n.length-1])}return t.map((i,s)=>{let o=new Map;for(let u of r.sort((c,l)=>c-l)){let c=u&1048575,l=u>>>20;if(n[l]!==s)continue;let g=o.get(l);typeof g=="undefined"&&o.set(l,g=[]),g.push(c)}if(o.size===0)return i;let a=[];for(let[u,c]of o){let l=e[u],g=l[0]>>>12,f=l[l.length-1]>>>12,v=l[l.length-1]>>>2&1023,m=i.slice(g,f+v);for(let x of c.sort((d,y)=>y-d)){let d=(l[x]>>>12)-g,y=(l[x]>>>2&1023)+d;m=[m.slice(0,d),"",m.slice(d,y),"",m.slice(y)].join("")}if(a.push(m)===2)break}return a.join("")})}function oe(t){let e=[];if(typeof t=="undefined")return e;let r=Array.isArray(t)?t:[t];for(let n=0;n{var l;switch(i[l=o+=s]||(i[l]=[]),a){case 0:case 2:i[o].push(u<<12|c-u<<2|a);break;case 1:let g=r[n].slice(u,c);H(g,lunr.tokenizer.separator,(f,v)=>{if(typeof lunr.segmenter!="undefined"){let m=g.slice(f,v);if(/^[MHIK]$/.test(lunr.segmenter.ctype_(m))){let x=lunr.segmenter.segment(m);for(let d=0,y=0;dr){return t.trim().split(/"([^"]+)"/g).map((r,n)=>n&1?r.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):r).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").split(/\s+/g).reduce((r,n)=>{let i=e(n);return[...r,...Array.isArray(i)?i:[i]]},[]).map(r=>/([~^]$)/.test(r)?`${r}1`:r).map(r=>/(^[+-]|[~^]\d+$)/.test(r)?r:`${r}*`).join(" ")}function ue(t){return ae(t,e=>{let r=[],n=new lunr.QueryLexer(e);n.run();for(let{type:i,str:s,start:o,end:a}of n.lexemes)switch(i){case"FIELD":["title","text","tags"].includes(s)||(e=[e.slice(0,a)," ",e.slice(a+1)].join(""));break;case"TERM":H(s,lunr.tokenizer.separator,(...u)=>{r.push([e.slice(0,o),s.slice(...u),e.slice(a)].join(""))})}return r})}function ce(t){let e=new lunr.Query(["title","text","tags"]);new lunr.QueryParser(t,e).parse();for(let n of e.clauses)n.usePipeline=!0,n.term.startsWith("*")&&(n.wildcard=lunr.Query.wildcard.LEADING,n.term=n.term.slice(1)),n.term.endsWith("*")&&(n.wildcard=lunr.Query.wildcard.TRAILING,n.term=n.term.slice(0,-1));return e.clauses}function le(t,e){var i;let r=new Set(t),n={};for(let s=0;s0;){let o=i[--s];for(let u=1;un[o]-u&&(r.add(t.slice(o,o+u)),i[s++]=o+u);let a=o+n[o];n[a]&&ar=>{if(typeof r[e]=="undefined")return;let n=[r.location,e].join(":");return t.set(n,lunr.tokenizer.table=[]),r[e]}}function Re(t,e){let[r,n]=[new Set(t),new Set(e)];return[...new Set([...r].filter(i=>!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){let i=Oe(this.table=new Map);this.map=ne(r),this.options=n,this.index=lunr(function(){this.metadataWhitelist=["position"],this.b(0),e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang)),this.tokenizer=oe,lunr.tokenizer.separator=new RegExp(e.separator),lunr.segmenter="TinySegmenter"in lunr?new lunr.TinySegmenter:void 0;let s=Re(["trimmer","stopWordFilter","stemmer"],e.pipeline);for(let o of e.lang.map(a=>a==="en"?lunr:lunr[a]))for(let a of s)this.pipeline.remove(o[a]),this.searchPipeline.remove(o[a]);this.ref("location");for(let[o,a]of Object.entries(e.fields))this.field(o,B(_({},a),{extractor:i(o)}));for(let o of r)this.add(o,{boost:o.boost})})}search(e){if(e=e.replace(new RegExp("\\p{sc=Han}+","gu"),s=>[...he(s,this.index.invertedIndex)].join("* ")),e=ue(e),!e)return{items:[]};let r=ce(e).filter(s=>s.presence!==lunr.Query.presence.PROHIBITED),n=this.index.search(e).reduce((s,{ref:o,score:a,matchData:u})=>{let c=this.map.get(o);if(typeof c!="undefined"){c=_({},c),c.tags&&(c.tags=[...c.tags]);let l=le(r,Object.keys(u.metadata));for(let f of this.index.fields){if(typeof c[f]=="undefined")continue;let v=[];for(let d of Object.values(u.metadata))typeof d[f]!="undefined"&&v.push(...d[f].position);if(!v.length)continue;let m=this.table.get([c.location,f].join(":")),x=Array.isArray(c[f])?q:se;c[f]=x(c[f],m,v)}let g=+!c.parent+Object.values(l).filter(f=>f).length/Object.keys(l).length;s.push(B(_({},c),{score:a*(1+Z(g,2)),terms:l}))}return s},[]).sort((s,o)=>o.score-s.score).reduce((s,o)=>{let a=this.map.get(o.location);if(typeof a!="undefined"){let u=a.parent?a.parent.location:a.location;s.set(u,[...s.get(u)||[],o])}return s},new Map);for(let[s,o]of n)if(!o.find(a=>a.location===s)){let a=this.map.get(s);o.push(B(_({},a),{score:0,terms:{}}))}let i;if(this.options.suggest){let s=this.index.query(o=>{for(let a of r)o.term(a.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});i=s.length?Object.keys(s[0].matchData.metadata):[]}return _({items:[...n.values()]},typeof i!="undefined"&&{suggest:i})}};var fe;function Ie(t){return W(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=re("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Fe(t){return W(this,null,function*(){switch(t.type){case 0:return yield Ie(t.data.config),fe=new U(t.data),{type:1};case 2:let e=t.data;try{return{type:3,data:fe.search(e)}}catch(r){return console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`),console.warn(r),{type:3,data:{items:[]}}}default:throw new TypeError("Invalid message type")}})}self.lunr=de.default;addEventListener("message",t=>W(void 0,null,function*(){postMessage(yield Fe(t.data))}));})(); +"use strict";(()=>{var xe=Object.create;var G=Object.defineProperty,ve=Object.defineProperties,Se=Object.getOwnPropertyDescriptor,Te=Object.getOwnPropertyDescriptors,Qe=Object.getOwnPropertyNames,Y=Object.getOwnPropertySymbols,Ee=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Z=Math.pow,J=(t,e,r)=>e in t?G(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,_=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(Y)for(var r of Y(e))be.call(e,r)&&J(t,r,e[r]);return t},B=(t,e)=>ve(t,Te(e));var Le=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var we=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Qe(e))!X.call(t,i)&&i!==r&&G(t,i,{get:()=>e[i],enumerable:!(n=Se(e,i))||n.enumerable});return t};var Pe=(t,e,r)=>(r=t!=null?xe(Ee(t)):{},we(e||!t||!t.__esModule?G(r,"default",{value:t,enumerable:!0}):r,t));var W=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var te=Le((K,ee)=>{(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var f=t.utils.clone(r)||{};f.position=[a,c],f.index=s.length,s.push(new t.Token(n.slice(a,o),f))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?f+=2:a==u&&(r+=n[c+1]*i[f+1],c+=2,f+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.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 c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var f=s.str.charAt(0),g=s.str.charAt(1),l;g in s.node.edges?l=s.node.edges[g]:(l=new t.TokenSet,s.node.edges[g]=l),s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:f+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof K=="object"?ee.exports=r():e.lunr=r()}(this,function(){return t})})()});var de=Pe(te());function re(t,e=document){let r=ke(t,e);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${t}" to be present`);return r}function ke(t,e=document){return e.querySelector(t)||void 0}Object.entries||(Object.entries=function(t){let e=[];for(let r of Object.keys(t))e.push([r,t[r]]);return e});Object.values||(Object.values=function(t){let e=[];for(let r of Object.keys(t))e.push(t[r]);return e});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(t,e){typeof t=="object"?(this.scrollLeft=t.left,this.scrollTop=t.top):(this.scrollLeft=t,this.scrollTop=e)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...t){let e=this.parentNode;if(e){t.length===0&&e.removeChild(this);for(let r=t.length-1;r>=0;r--){let n=t[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));function ne(t){let e=new Map;for(let r of t){let[n]=r.location.split("#"),i=e.get(n);typeof i=="undefined"?e.set(n,r):(e.set(r.location,r),r.parent=i)}return e}function H(t,e,r){var s;e=new RegExp(e,"g");let n,i=0;do{n=e.exec(t);let o=(s=n==null?void 0:n.index)!=null?s:t.length;if(in?e(r,1,n,n=i):t.charAt(i)===">"&&(t.charAt(n+1)==="/"?--s===0&&e(r++,2,n,i+1):t.charAt(i-1)!=="/"&&s++===0&&e(r,0,n,i+1),n=i+1);i>n&&e(r,1,n,i)}function se(t,e,r,n=!1){return q([t],e,r,n).pop()}function q(t,e,r,n=!1){let i=[0];for(let s=1;s>>2&1023,c=a[0]>>>12;i.push(+(u>c)+i[i.length-1])}return t.map((s,o)=>{let a=0,u=new Map;for(let f of r.sort((g,l)=>g-l)){let g=f&1048575,l=f>>>20;if(i[l]!==o)continue;let m=u.get(l);typeof m=="undefined"&&u.set(l,m=[]),m.push(g)}if(u.size===0)return s;let c=[];for(let[f,g]of u){let l=e[f],m=l[0]>>>12,x=l[l.length-1]>>>12,v=l[l.length-1]>>>2&1023;n&&m>a&&c.push(s.slice(a,m));let d=s.slice(m,x+v);for(let y of g.sort((b,E)=>E-b)){let b=(l[y]>>>12)-m,E=(l[y]>>>2&1023)+b;d=[d.slice(0,b),"",d.slice(b,E),"",d.slice(E)].join("")}if(a=x+v,c.push(d)===2)break}return n&&a{var f;switch(i[f=o+=s]||(i[f]=[]),a){case 0:case 2:i[o].push(u<<12|c-u<<2|a);break;case 1:let g=r[n].slice(u,c);H(g,lunr.tokenizer.separator,(l,m)=>{if(typeof lunr.segmenter!="undefined"){let x=g.slice(l,m);if(/^[MHIK]$/.test(lunr.segmenter.ctype_(x))){let v=lunr.segmenter.segment(x);for(let d=0,y=0;dr){return t.trim().split(/"([^"]+)"/g).map((r,n)=>n&1?r.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):r).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").split(/\s+/g).reduce((r,n)=>{let i=e(n);return[...r,...Array.isArray(i)?i:[i]]},[]).map(r=>/([~^]$)/.test(r)?`${r}1`:r).map(r=>/(^[+-]|[~^]\d+$)/.test(r)?r:`${r}*`).join(" ")}function ue(t){return ae(t,e=>{let r=[],n=new lunr.QueryLexer(e);n.run();for(let{type:i,str:s,start:o,end:a}of n.lexemes)switch(i){case"FIELD":["title","text","tags"].includes(s)||(e=[e.slice(0,a)," ",e.slice(a+1)].join(""));break;case"TERM":H(s,lunr.tokenizer.separator,(...u)=>{r.push([e.slice(0,o),s.slice(...u),e.slice(a)].join(""))})}return r})}function ce(t){let e=new lunr.Query(["title","text","tags"]);new lunr.QueryParser(t,e).parse();for(let n of e.clauses)n.usePipeline=!0,n.term.startsWith("*")&&(n.wildcard=lunr.Query.wildcard.LEADING,n.term=n.term.slice(1)),n.term.endsWith("*")&&(n.wildcard=lunr.Query.wildcard.TRAILING,n.term=n.term.slice(0,-1));return e.clauses}function le(t,e){var i;let r=new Set(t),n={};for(let s=0;s0;){let o=i[--s];for(let u=1;un[o]-u&&(r.add(t.slice(o,o+u)),i[s++]=o+u);let a=o+n[o];n[a]&&ar=>{if(typeof r[e]=="undefined")return;let n=[r.location,e].join(":");return t.set(n,lunr.tokenizer.table=[]),r[e]}}function Re(t,e){let[r,n]=[new Set(t),new Set(e)];return[...new Set([...r].filter(i=>!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){let i=Oe(this.table=new Map);this.map=ne(r),this.options=n,this.index=lunr(function(){this.metadataWhitelist=["position"],this.b(0),e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang)),this.tokenizer=oe,lunr.tokenizer.separator=new RegExp(e.separator),lunr.segmenter="TinySegmenter"in lunr?new lunr.TinySegmenter:void 0;let s=Re(["trimmer","stopWordFilter","stemmer"],e.pipeline);for(let o of e.lang.map(a=>a==="en"?lunr:lunr[a]))for(let a of s)this.pipeline.remove(o[a]),this.searchPipeline.remove(o[a]);this.ref("location");for(let[o,a]of Object.entries(e.fields))this.field(o,B(_({},a),{extractor:i(o)}));for(let o of r)this.add(o,{boost:o.boost})})}search(e){if(e=e.replace(new RegExp("\\p{sc=Han}+","gu"),s=>[...he(s,this.index.invertedIndex)].join("* ")),e=ue(e),!e)return{items:[]};let r=ce(e).filter(s=>s.presence!==lunr.Query.presence.PROHIBITED),n=this.index.search(e).reduce((s,{ref:o,score:a,matchData:u})=>{let c=this.map.get(o);if(typeof c!="undefined"){c=_({},c),c.tags&&(c.tags=[...c.tags]);let f=le(r,Object.keys(u.metadata));for(let l of this.index.fields){if(typeof c[l]=="undefined")continue;let m=[];for(let d of Object.values(u.metadata))typeof d[l]!="undefined"&&m.push(...d[l].position);if(!m.length)continue;let x=this.table.get([c.location,l].join(":")),v=Array.isArray(c[l])?q:se;c[l]=v(c[l],x,m,l!=="text")}let g=+!c.parent+Object.values(f).filter(l=>l).length/Object.keys(f).length;s.push(B(_({},c),{score:a*(1+Z(g,2)),terms:f}))}return s},[]).sort((s,o)=>o.score-s.score).reduce((s,o)=>{let a=this.map.get(o.location);if(typeof a!="undefined"){let u=a.parent?a.parent.location:a.location;s.set(u,[...s.get(u)||[],o])}return s},new Map);for(let[s,o]of n)if(!o.find(a=>a.location===s)){let a=this.map.get(s);o.push(B(_({},a),{score:0,terms:{}}))}let i;if(this.options.suggest){let s=this.index.query(o=>{for(let a of r)o.term(a.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});i=s.length?Object.keys(s[0].matchData.metadata):[]}return _({items:[...n.values()]},typeof i!="undefined"&&{suggest:i})}};var fe;function Ie(t){return W(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=re("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Fe(t){return W(this,null,function*(){switch(t.type){case 0:return yield Ie(t.data.config),fe=new U(t.data),{type:1};case 2:let e=t.data;try{return{type:3,data:fe.search(e)}}catch(r){return console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`),console.warn(r),{type:3,data:{items:[]}}}default:throw new TypeError("Invalid message type")}})}self.lunr=de.default;addEventListener("message",t=>W(void 0,null,function*(){postMessage(yield Fe(t.data))}));})(); diff --git a/assets/stylesheets/main.b13eea88.min.css b/assets/stylesheets/main.b13eea88.min.css deleted file mode 100644 index b662170..0000000 --- a/assets/stylesheets/main.b13eea88.min.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-bg-color--light:#f5f5f5b3;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:#ffff0080;--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset a code{color:var(--md-typeset-a-color)}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none;transition:background-color 125ms}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;transition:color 125ms,background-color 125ms;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{border-radius:100%;display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.9375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}:root{--md-code-select-icon:url('data:image/svg+xml;charset=utf-8,');--md-code-copy-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-code__content{display:grid}.md-code__nav{background-color:var(--md-code-bg-color--lighter);border-radius:.1rem;display:flex;gap:.2rem;padding:.2rem;position:absolute;right:.25em;top:.25em;transition:background-color .25s;z-index:1}:hover>.md-code__nav{background-color:var(--md-code-bg-color--light)}.md-code__button{color:var(--md-default-fg-color--lightest);cursor:pointer;display:block;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em}:hover>*>.md-code__button{color:var(--md-default-fg-color--light)}.md-code__button.focus-visible,.md-code__button:hover{color:var(--md-accent-fg-color)}.md-code__button--active{color:var(--md-default-fg-color)!important}.md-code__button:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-code__button[data-md-type=select]:after{-webkit-mask-image:var(--md-code-select-icon);mask-image:var(--md-code-select-icon)}.md-code__button[data-md-type=copy]:after{-webkit-mask-image:var(--md-code-copy-icon);mask-image:var(--md-code-copy-icon)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.9375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{align-content:baseline;display:flex;flex-wrap:wrap;justify-content:center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}[dir=ltr] .md-header__title{margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:flex-start;display:flex;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed,.md-nav__link--passed code{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}.md-nav__link .md-icon:last-child{margin-left:auto}.md-nav__link .md-typeset{font-size:.7rem;line-height:1.3}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em}[dir=ltr] .md-nav__link svg+*{margin-left:.4rem}[dir=rtl] .md-nav__link svg+*{margin-right:.4rem}.md-nav__link:not(.md-nav__container):focus,.md-nav__link:not(.md-nav__container):hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link:not(.md-nav__container):focus code,.md-nav__link:not(.md-nav__container):hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest);padding:0}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.9375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:checked~.md-nav,.md-nav__toggle:indeterminate~.md-nav{display:block}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);font-weight:700;margin-top:0;padding:0 .6rem;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}:root{--md-path-icon:url('data:image/svg+xml;charset=utf-8,')}.md-path{display:block;font-size:.7rem;margin:0 .8rem;overflow:auto;padding-top:1.2rem}@media screen and (min-width:76.25em){.md-path{margin:0 1.2rem}}.md-path__list{align-items:center;display:flex;gap:.2rem;list-style:none;margin:0;padding:0}.md-path__item:not(:first-child){display:inline-flex;gap:.2rem;white-space:nowrap}.md-path__item:not(:first-child):before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline;height:.8rem;-webkit-mask-image:var(--md-path-icon);mask-image:var(--md-path-icon);width:.8rem}.md-path__link{align-items:center;color:var(--md-default-fg-color--light);display:flex}.md-path__link:focus,.md-path__link:hover{color:var(--md-accent-fg-color)}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.1875em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary,.md-post>.md-nav:first-child>.md-nav__list{margin:1em 0}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.1875em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.1875em){.md-sidebar.md-sidebar--post{padding:0}}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.1875em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.9375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:#0000}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>.md-icon{margin-left:.2rem}[dir=rtl] .md-search__options>.md-icon{margin-right:.2rem}.md-search__options>.md-icon{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>.md-icon:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.9375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:focus,.md-search-result__link:hover{background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:focus>div,.md-search-result__more>summary:hover>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.9375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.1875em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status{margin-left:.2rem}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags{margin-bottom:.75em;margin-top:-.125em}[dir=ltr] .md-typeset .md-tag{margin-right:.5em}[dir=rtl] .md-typeset .md-tag{margin-left:.5em}.md-typeset .md-tag{background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-block;font-size:.64rem;font-weight:700;letter-spacing:normal;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;margin-right:.4em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,');--md-tooltip-width:20rem}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:xxx;list-style:none}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(xxx);counter-increment:xxx;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.05rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying]{display:block}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .linenodiv span[class]{padding-right:.5882352941em}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.9375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.9375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-accent-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){background-color:var(--md-accent-fg-color--transparent)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/assets/stylesheets/main.cbde490e.min.css b/assets/stylesheets/main.cbde490e.min.css new file mode 100644 index 0000000..1dfc221 --- /dev/null +++ b/assets/stylesheets/main.cbde490e.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-bg-color--light:#f5f5f5b3;--md-code-bg-color--lighter:#f5f5f54d;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset a code{color:var(--md-typeset-a-color)}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none;transition:background-color 125ms}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;transition:color 125ms,background-color 125ms;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{border-radius:100%;display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}:root{--md-code-select-icon:url('data:image/svg+xml;charset=utf-8,');--md-code-copy-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-code__content{display:grid}.md-code__nav{background-color:var(--md-code-bg-color--lighter);border-radius:.1rem;display:flex;gap:.2rem;padding:.2rem;position:absolute;right:.25em;top:.25em;transition:background-color .25s;z-index:1}:hover>.md-code__nav{background-color:var(--md-code-bg-color--light)}.md-code__button{color:var(--md-default-fg-color--lightest);cursor:pointer;display:block;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em}:hover>*>.md-code__button{color:var(--md-default-fg-color--light)}.md-code__button.focus-visible,.md-code__button:hover{color:var(--md-accent-fg-color)}.md-code__button--active{color:var(--md-default-fg-color)!important}.md-code__button:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-code__button[data-md-type=select]:after{-webkit-mask-image:var(--md-code-select-icon);mask-image:var(--md-code-select-icon)}.md-code__button[data-md-type=copy]:after{-webkit-mask-image:var(--md-code-copy-icon);mask-image:var(--md-code-copy-icon)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{align-content:baseline;display:flex;flex-wrap:wrap;justify-content:center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}[dir=ltr] .md-header__title{margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__link{align-items:flex-start;display:flex;gap:.4rem;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed,.md-nav__link--passed code{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}.md-nav__link .md-ellipsis code{word-break:normal}[dir=ltr] .md-nav__link .md-icon:last-child{margin-left:auto}[dir=rtl] .md-nav__link .md-icon:last-child{margin-right:auto}.md-nav__link .md-typeset{font-size:.7rem;line-height:1.3}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em}.md-nav__link[for]:focus,.md-nav__link[for]:hover,.md-nav__link[href]:focus,.md-nav__link[href]:hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link[for]:focus code,.md-nav__link[for]:hover code,.md-nav__link[href]:focus code,.md-nav__link[href]:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1;min-width:0}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.234375em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.984375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav{margin-bottom:-.4rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--secondary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--secondary .md-nav__list{padding-right:.6rem}.md-nav--secondary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--secondary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--secondary .md-nav__item>.md-nav__link{margin-left:.4rem}}@media screen and (min-width:76.25em){.md-nav{margin-bottom:-.4rem;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--primary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--primary .md-nav__list{padding-right:.6rem}.md-nav--primary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--primary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--primary .md-nav__item>.md-nav__link{margin-left:.4rem}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle:checked~.md-nav,.md-nav__toggle:indeterminate~.md-nav{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-icon,.md-nav__item--section>.md-nav__link>[for]{display:none}[dir=ltr] .md-nav__item--section>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav__item--section>.md-nav{margin-right:-.6rem}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);margin-top:0;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}[dir=ltr] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav{margin-right:-.6rem}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:1fr;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}:root{--md-path-icon:url('data:image/svg+xml;charset=utf-8,')}.md-path{display:block;font-size:.7rem;margin:0 .8rem;overflow:auto;padding-top:1.2rem}@media screen and (min-width:76.25em){.md-path{margin:0 1.2rem}}.md-path__list{align-items:center;display:flex;gap:.2rem;list-style:none;margin:0;padding:0}.md-path__item:not(:first-child){display:inline-flex;gap:.2rem;white-space:nowrap}.md-path__item:not(:first-child):before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline;height:.8rem;-webkit-mask-image:var(--md-path-icon);mask-image:var(--md-path-icon);width:.8rem}.md-path__link{align-items:center;color:var(--md-default-fg-color--light);display:flex}.md-path__link:focus,.md-path__link:hover{color:var(--md-accent-fg-color)}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.234375em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem 1.2rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post__title{color:var(--md-default-fg-color--light);font-weight:700}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary{margin:1em 0}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.234375em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.234375em){.md-sidebar.md-sidebar--post{padding:0;position:static;width:100%}.md-sidebar.md-sidebar--post .md-sidebar__inner{padding:0}.md-sidebar.md-sidebar--post .md-post__meta{margin-left:.6rem;margin-right:.6rem}.md-sidebar.md-sidebar--post .md-nav__item{border:none;display:inline}.md-sidebar.md-sidebar--post .md-nav__list{display:inline-flex;flex-wrap:wrap;gap:.6rem;padding-bottom:.6rem;padding-top:.6rem}.md-sidebar.md-sidebar--post .md-nav__link{padding:0}.md-sidebar.md-sidebar--post .md-nav{position:static}}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.234375em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.984375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:#0000}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>.md-icon{margin-left:.2rem}[dir=rtl] .md-search__options>.md-icon{margin-right:.2rem}.md-search__options>.md-icon{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>.md-icon:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.984375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:focus,.md-search-result__link:hover{background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:focus>div,.md-search-result__more>summary:hover>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.984375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.234375em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags{display:inline-flex;flex-wrap:wrap;gap:.5em;margin-bottom:.75em;margin-top:-.125em}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,');--md-tooltip-width:20rem}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:xxx;list-style:none}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(xxx);counter-increment:xxx;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.075rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying]{display:block}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .linenodiv span[class]{padding-right:.5882352941em}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/assets/stylesheets/palette.ab4e12ef.min.css b/assets/stylesheets/palette.ab4e12ef.min.css new file mode 100644 index 0000000..75aaf84 --- /dev/null +++ b/assets/stylesheets/palette.ab4e12ef.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-default-fg-color:hsla(var(--md-hue),15%,90%,0.82);--md-default-fg-color--light:hsla(var(--md-hue),15%,90%,0.56);--md-default-fg-color--lighter:hsla(var(--md-hue),15%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),15%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,14%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,14%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,14%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,14%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,0.82);--md-code-bg-color:hsla(var(--md-hue),15%,18%,1);--md-code-bg-color--light:hsla(var(--md-hue),15%,18%,0.9);--md-code-bg-color--lighter:hsla(var(--md-hue),15%,18%,0.54);--md-code-hl-color:#2977ff;--md-code-hl-color--light:#2977ff1a;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-kbd-color:hsla(var(--md-hue),15%,90%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,90%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-mark-color:#4287ff4d;--md-typeset-table-color:hsla(var(--md-hue),15%,95%,0.12);--md-typeset-table-color--light:hsla(var(--md-hue),15%,95%,0.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,10%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,8%,1);--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #00000040,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;color-scheme:dark}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#c46fd3}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a47bea}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#5488e8}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff764d}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c1775c}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5e8bde}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:hsla(var(--md-hue),0%,100%,1);--md-primary-fg-color--light:hsla(var(--md-hue),0%,100%,0.7);--md-primary-fg-color--dark:hsla(var(--md-hue),0%,0%,0.07);--md-primary-bg-color:hsla(var(--md-hue),0%,0%,0.87);--md-primary-bg-color--light:hsla(var(--md-hue),0%,0%,0.54);--md-typeset-a-color:#4051b5}[data-md-color-primary=white] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=white] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:hsla(var(--md-hue),0%,0%,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:hsla(var(--md-hue),0%,0%,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:hsla(var(--md-hue),0%,0%,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid #00000012}}[data-md-color-primary=black]{--md-primary-fg-color:hsla(var(--md-hue),15%,9%,1);--md-primary-fg-color--light:hsla(var(--md-hue),15%,9%,0.54);--md-primary-fg-color--dark:hsla(var(--md-hue),15%,9%,1);--md-primary-bg-color:hsla(var(--md-hue),15%,100%,1);--md-primary-bg-color--light:hsla(var(--md-hue),15%,100%,0.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=black] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}[data-md-color-primary=black] .md-header{background-color:hsla(var(--md-hue),15%,9%,1)}@media screen and (max-width:59.984375em){[data-md-color-primary=black] .md-nav__source{background-color:hsla(var(--md-hue),15%,11%,.87)}}@media screen and (max-width:76.234375em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:hsla(var(--md-hue),15%,9%,1)}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:hsla(var(--md-hue),15%,9%,1)}} \ No newline at end of file diff --git a/assets/stylesheets/palette.da3f46a0.min.css b/assets/stylesheets/palette.da3f46a0.min.css deleted file mode 100644 index 0c978e4..0000000 --- a/assets/stylesheets/palette.da3f46a0.min.css +++ /dev/null @@ -1 +0,0 @@ -@media screen{[data-md-color-scheme=slate]{--md-hue:232;--md-default-fg-color:hsla(var(--md-hue),75%,95%,1);--md-default-fg-color--light:hsla(var(--md-hue),75%,90%,0.62);--md-default-fg-color--lighter:hsla(var(--md-hue),75%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),75%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,21%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,21%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,21%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,21%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,1);--md-code-bg-color:hsla(var(--md-hue),15%,15%,1);--md-code-bg-color--light:hsla(var(--md-hue),15%,15%,0.9);--md-code-bg-color--lighter:hsla(var(--md-hue),15%,15%,0.54);--md-code-hl-color:#2977ff;--md-code-hl-color--light:#2977ff1a;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:#4287ff4d;--md-typeset-kbd-color:hsla(var(--md-hue),15%,94%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,94%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-table-color:hsla(var(--md-hue),75%,95%,0.12);--md-typeset-table-color--light:hsla(var(--md-hue),75%,95%,0.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,12%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,10%,1);--md-shadow-z1:0 0.2rem 0.5rem #0003,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000004d,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;color-scheme:dark}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#bd78c9}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a682e3}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#739ae2}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff9575}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c7846b}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#6c91d5}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:#fff;--md-primary-fg-color--light:#ffffffb3;--md-primary-fg-color--dark:#00000012;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a;--md-typeset-a-color:#4051b5}[data-md-color-primary=white] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=white] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:#fff}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:#00000012}[data-md-color-primary=white] .md-search__form:hover{background-color:#00000052}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:#000000de}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid #00000012}}[data-md-color-primary=black]{--md-primary-fg-color:#000;--md-primary-fg-color--light:#0000008a;--md-primary-fg-color--dark:#000;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=black] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:#fff}[data-md-color-primary=black] .md-header{background-color:#000}@media screen and (max-width:59.9375em){[data-md-color-primary=black] .md-nav__source{background-color:#000000de}}@media screen and (min-width:60em){[data-md-color-primary=black] .md-search__form{background-color:#ffffff1f}[data-md-color-primary=black] .md-search__form:hover{background-color:#ffffff4d}}@media screen and (max-width:76.1875em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:#000}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:#000}} \ No newline at end of file diff --git a/blog/archive/2023/index.html b/blog/archive/2023/index.html index 8bac8fb..7ce92d9 100644 --- a/blog/archive/2023/index.html +++ b/blog/archive/2023/index.html @@ -11,7 +11,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -423,15 +441,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • + + + + + +
  • - @@ -680,7 +711,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -749,9 +833,13 @@ -
  • + + + + + +
  • - @@ -759,7 +847,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1261,13 +1358,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1289,31 +1412,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1582,10 +1770,10 @@

    + - + - + diff --git a/blog/category/announcements/index.html b/blog/category/announcements/index.html index 24be2cd..26e21b5 100644 --- a/blog/category/announcements/index.html +++ b/blog/category/announcements/index.html @@ -14,14 +14,14 @@ - + - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -423,15 +441,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • + + + + + +
  • - @@ -680,7 +711,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -749,9 +833,13 @@ -
  • + + + + + +
  • - @@ -759,7 +847,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1261,13 +1358,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1289,31 +1412,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1582,10 +1770,10 @@

    + - + - + diff --git a/blog/index.html b/blog/index.html index 9519722..f8f3edc 100644 --- a/blog/index.html +++ b/blog/index.html @@ -14,14 +14,14 @@ - + - + @@ -29,10 +29,10 @@ - + - + @@ -314,6 +314,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -418,15 +436,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • + + + + + +
  • - @@ -673,7 +704,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -742,9 +826,13 @@ -
  • + + + + + +
  • - @@ -752,7 +840,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1254,13 +1351,39 @@
  • - + + + + + + + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + - Installing Juniper vSRX on Proxmox + MikroTik @@ -1282,31 +1405,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1573,10 +1761,10 @@

    + - + - + diff --git a/blog/the-telecom-craft-homelabs-site-has-launched/index.html b/blog/the-telecom-craft-homelabs-site-has-launched/index.html index 1725475..4c3e574 100644 --- a/blog/the-telecom-craft-homelabs-site-has-launched/index.html +++ b/blog/the-telecom-craft-homelabs-site-has-launched/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -315,6 +315,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,15 +439,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -739,9 +823,13 @@ -
  • + + + + + +
  • - @@ -749,7 +837,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1251,13 +1348,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1279,31 +1402,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1504,7 +1692,7 @@
    - @@ -1664,10 +1856,10 @@

    The Telecom Craft Homelabs

    + + + Back to top + @@ -1747,6 +1939,7 @@

    The Telecom Craft Homelabs

    + - + - + diff --git a/diagrams/notes/index.html b/diagrams/notes/index.html index 9420e40..23e8f68 100644 --- a/diagrams/notes/index.html +++ b/diagrams/notes/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + +
    @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Notes

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Notes

    + - + - + diff --git a/index.html b/index.html index 7996998..b42a340 100644 --- a/index.html +++ b/index.html @@ -19,7 +19,7 @@ - + @@ -27,10 +27,10 @@ - + - + @@ -317,6 +317,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -431,9 +449,13 @@ -
  • + + + + + +
  • - @@ -441,7 +463,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -680,7 +711,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -749,9 +833,13 @@ -
  • + + + + + +
  • - @@ -759,7 +847,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1261,13 +1358,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1289,31 +1412,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1596,10 +1784,10 @@

    Welcome to Our Home Labs!

    + + + Back to top + @@ -1679,6 +1867,7 @@

    Welcome to Our Home Labs!

    + - + - + diff --git a/labs/fiber/overview/index.html b/labs/fiber/overview/index.html index 0422814..814b47c 100644 --- a/labs/fiber/overview/index.html +++ b/labs/fiber/overview/index.html @@ -11,17 +11,17 @@ - + - + - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -749,9 +833,13 @@ -
  • + + + + + +
  • - @@ -759,7 +847,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1261,13 +1358,39 @@
  • - + + + + + + + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + - Installing Juniper vSRX on Proxmox + MikroTik @@ -1289,31 +1412,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1565,16 +1753,17 @@

    Fiber Labs Overview

    -

    Welcome to the Telecom Craft series on Fiber Optic Labs.

    +

    Welcome to the Telecom Craft lab series on fiber optic networking.

    In this series we’ll cover what we call the three “Ts” of fiber optic networking skills: termination, testing, and transmission. To learn more about our plans for the Fiber Optic Homelab and how it got started, check out the link to the blog post.

    -

    Before we get started, we want to mention that these videos are designed to focus on skill-building -for people that already know at least some of the fundamentals of fiber optic networking.

    +

    Before we get started, we want to mention that these labs are designed to focus on skill-building and +on-going practice for people that already know at least some of the fundamentals of fiber optic +networking.

    If you’re new to this field, but want to learn the fundamentals, we highly recommend starting with -the excellent and freely available content over at the Fiber Optic Association, or FOA.

    -

    We ourselves are proud FOA members and Certified Fiber Optic Technicians, or CFOTs, and that’s what -you’ll want to check out to begin your learning.

    +the excellent and freely available content over at the
    Fiber Optic Association (FOA).

    +

    We ourselves are proud FOA members and Certified Fiber Optic Technicians (CFOT®), +and that’s what you’ll want to check out to begin your learning.

    @@ -1635,10 +1824,10 @@

    Fiber Labs Overview

    + + + Back to top + @@ -1718,6 +1907,7 @@

    Fiber Labs Overview

    + - + - + diff --git a/labs/fiber/patch-cords-and-connectors/index.html b/labs/fiber/patch-cords-and-connectors/index.html new file mode 100644 index 0000000..9cfb700 --- /dev/null +++ b/labs/fiber/patch-cords-and-connectors/index.html @@ -0,0 +1,2308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Patch Cords and Connectors - Telecom Craft Home Labs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + Skip to content + + +
    +
    + +
    + + + + +
    + + +
    + +
    + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + +

    Fiber Optic Patch Cords and Connectors

    +

    Introduction

    +

    So the role of any network cable is to connect devices, right? They transmit data to allow the +devices to communicate, and more and more often, they also transmit electricity to power the +device as well.

    +

    Patch cords, specifically, provide a temporary link between multiple devices or other cables +It’s considered temporary because it can easily connected and disconnected (REMOVE UTP CABLE), +which no one appreciates.

    +

    In this lab we’re going to take a close look at patch cords and their connectors. As we saw in the +previous episode, they can be used to build simple—but complete—fiber optic networks. So this is a +great place to start as we develop the lab.

    +
    !!! tip
    +
    +Address term cord vs cable
    +
    +

    Tools and Materials Needed

    +
      +
    • Simplex and duplex LC-UPC OS2 cords
    • +
    • Short UTP cables from E1
    • +
    • New duplex LC-UPC cord
    • +
    • Duplex LC-UPC OM4 cord
    • +
    • Duplex LC-UPC OM5 cord
    • +
    • Simplex SC-UPC OS2 cord
    • +
    • Simplex SC-APC OS2 cord
    • +
    • Simplex LC-UPC to ST-UPC OS2 cord
    • +
    • Simplex LC-UPC to FC-UPC OS2 cord
    • +
    • VFL
    • +
    +

    Step 1: Examine the UTP Patch Cord

    +
      +
    • +

      I had to take our tiny network here offline to talk about patch cords we’ve been using to enable my laptop to connect to the router.

      +
    • +
    • +

      Examine the UTP patch cord from E1, and review its components and common roles in networks.

      +
        +
      • Components
          +
        • Copper strands
        • +
        • Coating (color-coded)
        • +
        • Boot
        • +
        • Crimping
        • +
        +
      • +
      • Roles
          +
        • Internet WAN link
        • +
        • Switch links to PCs, cameras, or Wi-Fi radios
        • +
        • PoE delivery
        • +
        +
      • +
      +
    • +
    +

    Step 2: Examine the Fiber Optic Patch Cords

    +

    Review its components and compare/contrast to the UTP patch cord. + - Review components + - 9um SM fiber and 125um cladding + - 250um primary buffer coating + - 900um tight buffer coating + - PVC jacket and labeling + - Ferrule + - Crimp + - Boot + - Review roles + - Internet WAN link + - Switch links to PCs, cameras, or Wi-Fi radios + - Non-conductive, so no PoE, but dielectric nature has advantages too + - There are composite cables that can carry electric with fiber. + - Discuss durability and damage prevention

    +

    Step 3: Identify and Examine the Types of Optical Fibers and Connectors

    +
      +
    • Duplex LC-UPC OM4 cords
    • +
    • Although it looks similar to the previous cord and has the same LC-UPC connector, it’s using MM fiber instead of SM. For a variety of reasons, I prefer SM over MM, but we’ll get to that in a minute.
    • +
    • Duplex LC-UPC OM5 cords
    • +
    • MM colors for boots and connectors (mention FOCIS), speeds
    • +
    • Simplex SC-UPC OS2 cords
    • +
    • Simplex SC-APC OS2 cords
    • +
    • Simplex LC-UPC to ST-UPC OS2 cords
    • +
    • Simplex LC-UPC to FC-UPC OS2 cords
    • +
    • Now that we’ve covered the general role of patch cords, as well as the common types of cables and connectors used, we’ll wrap things up with a few considerations for deciding which patch cords to use.
    • +
    +

    Step 4: Consider Singlemode vs Multimode Tradeoffs

    +

    One of the first things to consider is which type of fiber to use for each cable: singlemode or multimode?

    +

    As you build out your lab, this becomes an increasingly important question. I’ll cover this topic more in-depth in a later episode, but for now, here are some rules of thumb.

    +
      +
    • +

      Rule #1: Determine your distance requirements.** Both SM and MM can go further than TP, but SM can go way further than MM. In your lab, this is generally not a problem, but if you plan to simulate cable plants over 1Km, like I will, SM is needed. Be careful because there are multiple versions of both MM and SM, each with important characteristics!

      +
    • +
    • +

      Rule #2: Determine your device requirements.** Devices can also define constraints on your cabling decisions based on their transceiver specifications. Historically, because most ISP and DC cabling is shorter and MM fiber and transceivers were cheaper, devices standardized on MM. That’s beginning to change as device costs come down while speeds are increasing, and now network designers see long-term advantage of SM cable plants, however. You can find transceivers that will operate with both MM and SM fiber, giving you flexibility. But as always, study your tech specs carefully!

      +
    • +
    • +

      Rule #3: Determine your fiber application requirements.** Depending on your overall lab plans and network needs, which fiber you use will constrain how you can then use it. If you’re experimenting with attenuation, for example, SM generally has lower loss than MM. One of my objectives is to study WDM with my lab, and for that, SM—specifically G652—is the best choice.

      +
    • +
    +

    Step 5: Consider Connector Choice Tradeoffs

    +
      +
    • Next up is considering which type of connector to use for your cable. We’ve reviewed some of the most common options in this episode: an SC or LC form factor, and a UPC or APC polish. Here the options can get a bit more complicated, but the same evaluation process for fiber is useful.
    • +
    • In this case, distance isn’t really an factor, but your device and application requirements still define your constraints.
    • +
    • Transceivers in ISP and DC environments are still generally LC-UPC, so that is straightforward. Between devices, however, such as in patch panels, you might want to consider your port density and rack space constraints, as well as overall cable management standards.
    • +
    • PON networks, however, utilize SC-APC for much of the ISP and OSP. APC has reduced attenuation, and SC form factors are easier to handle, so the application determines the connector.
    • +
    • In any case, remember that you have flexibility through the use of mixed-connector cables as well as adapters within the cable plant to implement the right connector at each termination point.
    • +
    • As a note, there are many other specialized connectors that have their advantages, such as multi-fiber MPOs and highly compact MDCs. I plan to cover some of these later in the lab.
    • +
    +

    Step 6: Consider Buy-vs-Build Tradeoffs of Patch Cords

    +

    Before we wrap up, I wanted to quickly talk about the question of “buy vs build.” Going back to our original UTP patch cords, many people are comfortable making these out of the components: bulk UTP cable, connector boots, and RJ-45s. They can be made on-demand, can be more economical, and made to the exact lengths you need. + - So what about fiber? At a high-level, all of those advantages for making your own patch cords apply. But it is more complicated due to skills, tools, and materials needed for preparing and terminating the cables. As a result, most experienced technicians would not recommend it. + - There are impressive advances in mechanical connectors and splice-on-connectors, and I’d like to explore this later in the lab, but I personally recommend you purchase your patch cords whenever possible. I certainly do!

    +

    Conclusion

    +

    We now covered the roles, types, and tradeoffs of fiber patch cords. In some cases there are no easy +or right answers on what option to use. In each case, research your requirements; understand your +distance, device, and application constraints; and be consistent in your design. And above all, use +your lab to experiment and learn all you can. That’s what it’s for!

    +
    !!! question
    +
    +So what patch cords do you use and why?
    +
    +

    In the next lab in this series, we’ll take a look at fiber optic connectors and adapters, which will +allow us to interconnect patch cords between our devices. This is where the fun really begins.

    +

    Again, if you’re new to fiber optics and like what you saw here, head over to the FOA website and check +out their Fiber U courses and textbooks.

    + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/fiber/safety-tips/index.html b/labs/fiber/safety-tips/index.html new file mode 100644 index 0000000..1faa80d --- /dev/null +++ b/labs/fiber/safety-tips/index.html @@ -0,0 +1,1956 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Safety Tips - Telecom Craft Home Labs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + Skip to content + + +
    +
    + +
    + + + + +
    + + +
    + +
    + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    + + + + + + + + + + + +
    + + + + + + + +

    Safety Tips

    +

    You should always be careful when working with fiber optics. Before you get started in the lab, here are some important safety tips:

    +
      +
    • Wear eye protection when necessary,
    • +
    • Never look into powered cables or optical equipment,
    • +
    • Do not eat or drink while working,
    • +
    • Properly dispose of all fiber scraps, and
    • +
    • Clean your work area thoroughly when finished.
    • +
    +

    Even in your home lab, remember to play it safe to keep working with fiber fun.

    + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/networks/apnic/mikrotik/overview/index.html b/labs/networks/apnic/mikrotik/overview/index.html index df61e3e..8a652cf 100644 --- a/labs/networks/apnic/mikrotik/overview/index.html +++ b/labs/networks/apnic/mikrotik/overview/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • + + +
  • + - - - - + +
  • + + + + -
  • + + + + + +
  • + - + -
  • + + + -
  • + + + + + + - + +
  • - - - + + + + + + + - -
  • + + + + - - + + + + + +
  • + + + + + + + Overview - - - - - + + + + + +
  • - - - + + + + + +
  • - - + -
  • + + @@ -1642,10 +1830,10 @@

    MikroTik Hands-On Exercises

    + + + Back to top + @@ -1725,6 +1913,7 @@

    MikroTik Hands-On Exercises

    + - + - + diff --git a/labs/networks/apnic/routing-labs/index.html b/labs/networks/apnic/routing-labs/index.html index 20e6a1b..f43fa30 100644 --- a/labs/networks/apnic/routing-labs/index.html +++ b/labs/networks/apnic/routing-labs/index.html @@ -11,7 +11,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -314,6 +314,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -416,9 +434,13 @@ -
  • + + + + + +
  • - @@ -426,7 +448,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -665,7 +696,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -736,15 +820,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • + + +
  • + - - - -
  • + + + + -
  • + + + + + +
  • + - + -
  • + + + + + + + + + + + - + + +
  • + + + + + + + + + - -
  • + + + + - - - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1635,10 +1823,10 @@

    Overview

    + + + Back to top + @@ -1718,6 +1906,7 @@

    Overview

    + - + - + diff --git a/labs/networks/general/cloning-a-network-host-template-in-proxmox/index.html b/labs/networks/general/cloning-a-network-host-template-in-proxmox/index.html index e7060b7..354c2de 100644 --- a/labs/networks/general/cloning-a-network-host-template-in-proxmox/index.html +++ b/labs/networks/general/cloning-a-network-host-template-in-proxmox/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1330,13 +1427,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1358,31 +1481,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1814,10 +2002,10 @@

    Step 3: Create Three More + + + Back to top + @@ -1897,6 +2085,7 @@

    Step 3: Create Three More
    + - + - + diff --git a/labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/index.html b/labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/index.html index c45b19b..f0b9c9e 100644 --- a/labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/index.html +++ b/labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1341,13 +1438,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1369,31 +1492,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1978,10 +2166,10 @@

    Step 3: Confirm Hos + + + Back to top + @@ -2061,6 +2249,7 @@

    Step 3: Confirm Hos
    + - + - + diff --git a/labs/networks/general/creating-a-network-host-template-in-proxmox/index.html b/labs/networks/general/creating-a-network-host-template-in-proxmox/index.html index 15cb6f9..aeecb6a 100644 --- a/labs/networks/general/creating-a-network-host-template-in-proxmox/index.html +++ b/labs/networks/general/creating-a-network-host-template-in-proxmox/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1341,13 +1438,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1369,31 +1492,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1915,10 +2103,10 @@

    Ste + + + Back to top + @@ -1998,6 +2186,7 @@

    Ste
    + - + - + diff --git a/labs/networks/general/exploring-subnets-and-vlans-in-proxmox/index.html b/labs/networks/general/exploring-subnets-and-vlans-in-proxmox/index.html index a1eae1e..c9a52a4 100644 --- a/labs/networks/general/exploring-subnets-and-vlans-in-proxmox/index.html +++ b/labs/networks/general/exploring-subnets-and-vlans-in-proxmox/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1352,13 +1449,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1380,31 +1503,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -3544,10 +3732,10 @@

    Conclusion and Next Lab

    + + + Back to top + @@ -3627,6 +3815,7 @@

    Conclusion and Next Lab

    + - + - + diff --git a/labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/index.html b/labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/index.html index 55c71c6..94c1c6c 100644 --- a/labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/index.html +++ b/labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1330,13 +1427,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1358,31 +1481,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -2395,10 +2583,10 @@

    Step 3: Dipping Our Toes + + + Back to top + @@ -2478,6 +2666,7 @@

    Step 3: Dipping Our Toes
    + - + - + diff --git a/labs/networks/general/initial-proxmox-network-configuration/index.html b/labs/networks/general/initial-proxmox-network-configuration/index.html index d5deac3..c83dd80 100644 --- a/labs/networks/general/initial-proxmox-network-configuration/index.html +++ b/labs/networks/general/initial-proxmox-network-configuration/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1358,13 +1455,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1386,31 +1509,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1891,10 +2079,10 @@

    Custom MAC Address Prefix

    + + + Back to top + @@ -1974,6 +2162,7 @@

    Custom MAC Address Prefix

    + - + - + diff --git a/labs/networks/juniper/initial-junos-os-configuration-best-practices/index.html b/labs/networks/juniper/initial-junos-os-configuration-best-practices/index.html index 5f95d2e..baaf329 100644 --- a/labs/networks/juniper/initial-junos-os-configuration-best-practices/index.html +++ b/labs/networks/juniper/initial-junos-os-configuration-best-practices/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -313,6 +313,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -415,9 +433,13 @@ -
  • + + + + + +
  • - @@ -425,7 +447,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -664,7 +695,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -733,9 +817,13 @@ -
  • + + + + + +
  • - @@ -743,7 +831,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1245,13 +1342,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1273,31 +1396,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1799,10 +1987,10 @@

    Verification

    + + + Back to top + @@ -1882,6 +2070,7 @@

    Verification

    + - + - + diff --git a/labs/networks/juniper/installing-vsrx-on-proxmox/index.html b/labs/networks/juniper/installing-vsrx-on-proxmox/index.html index 292a43f..12acdad 100644 --- a/labs/networks/juniper/installing-vsrx-on-proxmox/index.html +++ b/labs/networks/juniper/installing-vsrx-on-proxmox/index.html @@ -11,17 +11,13 @@ - - - - - + @@ -29,10 +25,10 @@ - + - + @@ -284,12 +280,10 @@ - - -
  • +
  • @@ -319,6 +313,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +433,13 @@ -
  • + + + + + +
  • - @@ -431,7 +447,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +695,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -735,21 +813,26 @@ - - -
  • + + + + + +
  • + - + -
  • - - - - - + + +
  • - - + -
  • + + @@ -1649,61 +1741,6 @@ - -
    @@ -1815,10 +1852,10 @@

    Step 4: Verify VM Bootup and + + + Back to top + @@ -1898,6 +1935,7 @@

    Step 4: Verify VM Bootup and
    + - + - + diff --git a/labs/networks/juniper/reinstalling-vsrx-trial-on-proxmox/index.html b/labs/networks/juniper/reinstalling-vsrx-trial-on-proxmox/index.html index f47e4b9..2cf0da4 100644 --- a/labs/networks/juniper/reinstalling-vsrx-trial-on-proxmox/index.html +++ b/labs/networks/juniper/reinstalling-vsrx-trial-on-proxmox/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Reinstalling vsrx trial on proxmox

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Reinstalling vsrx trial on proxmox

    + - + - + diff --git a/labs/networks/mikrotik/connected-routes/index.html b/labs/networks/mikrotik/connected-routes/index.html new file mode 100644 index 0000000..2df6600 --- /dev/null +++ b/labs/networks/mikrotik/connected-routes/index.html @@ -0,0 +1,1888 @@ + + + + + + + + + + + + + + + + + + + + + + + + Connected routes - Telecom Craft Home Labs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + +
    + + + + +
    + + +
    + +
    + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    + + + + + + + + + +
    + + + + + + + +

    Connected routes

    + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/networks/mikrotik/default-routes/index.html b/labs/networks/mikrotik/default-routes/index.html new file mode 100644 index 0000000..228ecce --- /dev/null +++ b/labs/networks/mikrotik/default-routes/index.html @@ -0,0 +1,1898 @@ + + + + + + + + + + + + + + + + + + + + + + + + Default Routes - Telecom Craft Home Labs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + +
    + +
    + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    + + + + + + + + + +
    + + + + + + + +

    Default Routes

    +
      +
    • Basic default routes
    • +
    • Static default routes
    • +
    • Floating default routes
    • +
    + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/networks/mikrotik/initial-routeros-configuration-best-practices/index.html b/labs/networks/mikrotik/initial-routeros-configuration-best-practices/index.html index 2864dcd..da7c683 100644 --- a/labs/networks/mikrotik/initial-routeros-configuration-best-practices/index.html +++ b/labs/networks/mikrotik/initial-routeros-configuration-best-practices/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -313,6 +313,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -415,9 +433,13 @@ -
  • + + + + + +
  • - @@ -425,7 +447,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -664,7 +695,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -733,9 +817,13 @@ -
  • + + + + + +
  • - @@ -743,7 +831,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1245,13 +1342,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1273,31 +1396,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1791,10 +1979,10 @@

    Verification

    + + + Back to top + @@ -1874,6 +2062,7 @@

    Verification

    + - + - + diff --git a/labs/networks/mikrotik/installing-routeros-on-proxmox/index.html b/labs/networks/mikrotik/installing-routeros-on-proxmox/index.html index 57e5c27..59c802d 100644 --- a/labs/networks/mikrotik/installing-routeros-on-proxmox/index.html +++ b/labs/networks/mikrotik/installing-routeros-on-proxmox/index.html @@ -14,14 +14,14 @@ - + - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + - Step 1: Create a MikroTik Account + Step 1: Adding RouterOS as an Image in Proxmox @@ -1251,38 +1346,10 @@
  • - + - Step 2: Adding RouterOS as an Image in Proxmox - - - - - - -
  • - -
  • - - - - Step 3: Creating and Configuring a VM for RouterOS + Step 2: Creating and Configuring a VM for RouterOS @@ -1336,23 +1403,25 @@ + +
  • - + @@ -1380,13 +1449,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1408,31 +1503,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1638,49 +1798,21 @@
  • - - - - Step 1: Create a MikroTik Account - - - - -
  • - -
  • - + - Step 2: Adding RouterOS as an Image in Proxmox - - - - - -
  • - + - Step 3: Creating and Configuring a VM for RouterOS + Step 2: Creating and Configuring a VM for RouterOS @@ -1827,21 +1959,9 @@

    Introduction

    In this lab, we're going to cover the process to install a RouterOS virtual machine (VM) in Proxmox and prepare it for use as a full-featured router/firewall/vpn in our networks.

    -

    Step 1: Create a MikroTik Account

    -

    RouterOS is available to use for free, but with several caveats that you must be -aware of:

    -
      -
    1. -

      Every instance of RouterOS you use must still be registered via a MikroTik -account, even the free version.

      -
    2. -
    3. -

      The free version is limited to

      -
    4. -
    -

    Step 2: Adding RouterOS as an Image in Proxmox

    -

    Option A: Use

    -

    Step 3: Creating and Configuring a VM for RouterOS

    +

    We will be using the

    +

    Step 1: Adding RouterOS as an Image in Proxmox

    +

    Step 2: Creating and Configuring a VM for RouterOS

    Step 3: Installing the RouterOS Image on a VM

    Conclusion and Next Lab

    @@ -1904,10 +2024,10 @@

    Conclusion and Next Lab

    + + + Back to top + @@ -1987,6 +2107,7 @@

    Conclusion and Next Lab

    + - + - + diff --git a/labs/networks/mikrotik/static-routing-between-subnets-with-routeros/index.html b/labs/networks/mikrotik/static-routing-between-subnets-with-routeros/index.html index 7f4e0ff..1f15c15 100644 --- a/labs/networks/mikrotik/static-routing-between-subnets-with-routeros/index.html +++ b/labs/networks/mikrotik/static-routing-between-subnets-with-routeros/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -313,6 +313,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -415,9 +433,13 @@ -
  • + + + + + +
  • - @@ -425,7 +447,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -664,7 +695,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -733,9 +817,13 @@ -
  • + + + + + +
  • - @@ -743,7 +831,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1245,13 +1342,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1273,31 +1396,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1629,10 +1817,10 @@

    Lab Setup

    + + + Back to top + @@ -1712,6 +1900,7 @@

    Lab Setup

    + - + - + diff --git a/labs/networks/overview/index.html b/labs/networks/overview/index.html index dc85193..c99a354 100644 --- a/labs/networks/overview/index.html +++ b/labs/networks/overview/index.html @@ -11,7 +11,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1261,13 +1358,39 @@
  • - + + + + + + + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + - Installing Juniper vSRX on Proxmox + MikroTik @@ -1289,31 +1412,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1628,10 +1816,10 @@

    Network Labs Overview

    + + + Back to top + @@ -1711,6 +1899,7 @@

    Network Labs Overview

    + - + - + diff --git a/labs/networks/vyos/initial-vyos-configuration-best-practices/index.html b/labs/networks/vyos/initial-vyos-configuration-best-practices/index.html index 09a6812..94e37af 100644 --- a/labs/networks/vyos/initial-vyos-configuration-best-practices/index.html +++ b/labs/networks/vyos/initial-vyos-configuration-best-practices/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1435,13 +1532,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1463,31 +1586,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -2031,10 +2219,10 @@

    Verification

    + + + Back to top + @@ -2114,6 +2302,7 @@

    Verification

    + - + - + diff --git a/labs/networks/vyos/installing-vyos-on-proxmox/index.html b/labs/networks/vyos/installing-vyos-on-proxmox/index.html index c822114..e802c04 100644 --- a/labs/networks/vyos/installing-vyos-on-proxmox/index.html +++ b/labs/networks/vyos/installing-vyos-on-proxmox/index.html @@ -21,7 +21,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -319,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -421,9 +439,13 @@ -
  • + + + + + +
  • - @@ -431,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -670,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -741,15 +825,20 @@ -
  • + + + + + +
  • - -
  • - +
  • - +
  • - +
  • - + @@ -1352,13 +1449,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1380,31 +1503,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1956,10 +2144,10 @@

    Conclusion and Next Lab

    + + + Back to top + @@ -2039,6 +2227,7 @@

    Conclusion and Next Lab

    + - + - + diff --git a/labs/networks/vyos/upgrading-vyos/index.html b/labs/networks/vyos/upgrading-vyos/index.html index 6b2c036..44bfd15 100644 --- a/labs/networks/vyos/upgrading-vyos/index.html +++ b/labs/networks/vyos/upgrading-vyos/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Upgrading vyos

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Upgrading vyos

    + - + - + diff --git a/labs/networks/vyos/vyos-rolling-vs-lts/index.html b/labs/networks/vyos/vyos-rolling-vs-lts/index.html index 51fbd70..6f1fc9b 100644 --- a/labs/networks/vyos/vyos-rolling-vs-lts/index.html +++ b/labs/networks/vyos/vyos-rolling-vs-lts/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Vyos rolling vs lts

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Vyos rolling vs lts

    + - + - + diff --git a/labs/security/overview/index.html b/labs/security/overview/index.html index ebfcd2b..d52d77a 100644 --- a/labs/security/overview/index.html +++ b/labs/security/overview/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -313,6 +313,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -415,9 +433,13 @@ -
  • + + + + + +
  • - @@ -425,7 +447,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -664,7 +695,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -733,9 +817,13 @@ -
  • + + + + + +
  • - @@ -743,7 +831,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1245,13 +1342,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1273,31 +1396,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1571,10 +1759,10 @@

    Security Labs Overview

    + + + Back to top + @@ -1654,6 +1842,7 @@

    Security Labs Overview

    + - + - + diff --git a/labs/servers/overview/index.html b/labs/servers/overview/index.html index be08cfd..cea652e 100644 --- a/labs/servers/overview/index.html +++ b/labs/servers/overview/index.html @@ -14,12 +14,14 @@ + + - + @@ -27,10 +29,10 @@ - + - + @@ -317,6 +319,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -419,9 +439,13 @@ -
  • + + + + + +
  • - @@ -429,7 +453,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -668,7 +701,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -737,9 +823,13 @@ -
  • + + + + + +
  • - @@ -747,7 +837,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1249,13 +1348,39 @@
  • - + + + + + + + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + - Installing Juniper vSRX on Proxmox + MikroTik @@ -1277,31 +1402,43 @@ - - + + + +
  • + + + + + + + -
  • + + + + + +
  • + - - - -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - + - - - - - - -
  • + +
  • + - + -
  • @@ -1623,10 +1813,10 @@

    Server Labs Overview

    + + + Back to top + @@ -1706,6 +1896,7 @@

    Server Labs Overview

    + - + - + diff --git a/labs/servers/proxmox-8-overview/index.html b/labs/servers/proxmox-8-overview/index.html index d59e813..473e678 100644 --- a/labs/servers/proxmox-8-overview/index.html +++ b/labs/servers/proxmox-8-overview/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Proxmox 8 overview

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Proxmox 8 overview

    + - + - + diff --git a/plugins/social/templates/default.yml b/plugins/social/templates/default.yml deleted file mode 100644 index 2d803a9..0000000 --- a/plugins/social/templates/default.yml +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright (c) 2016-2023 Martin Donath - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -# ----------------------------------------------------------------------------- -# Configuration -# ----------------------------------------------------------------------------- - -# Definitions -definitions: - - # Background image - - &background_image >- - {{ layout.background_image | x }} - - # Background color (default: indigo) - - &background_color >- - {%- if layout.background_color -%} - {{ layout.background_color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set primary = palette.get("primary", "indigo") -%} - {%- set primary = primary.replace(" ", "-") -%} - {{ { - "red": "#ef5552", - "pink": "#e92063", - "purple": "#ab47bd", - "deep-purple": "#7e56c2", - "indigo": "#4051b5", - "blue": "#2094f3", - "light-blue": "#02a6f2", - "cyan": "#00bdd6", - "teal": "#009485", - "green": "#4cae4f", - "light-green": "#8bc34b", - "lime": "#cbdc38", - "yellow": "#ffec3d", - "amber": "#ffc105", - "orange": "#ffa724", - "deep-orange": "#ff6e42", - "brown": "#795649", - "grey": "#757575", - "blue-grey": "#546d78", - "black": "#000000", - "white": "#ffffff" - }[primary] or "#4051b5" }} - {%- endif -%} - - # Text color (default: white) - - &color >- - {%- if layout.color -%} - {{ layout.color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set primary = palette.get("primary", "indigo") -%} - {%- set primary = primary.replace(" ", "-") -%} - {{ { - "red": "#ffffff", - "pink": "#ffffff", - "purple": "#ffffff", - "deep-purple": "#ffffff", - "indigo": "#ffffff", - "blue": "#ffffff", - "light-blue": "#ffffff", - "cyan": "#ffffff", - "teal": "#ffffff", - "green": "#ffffff", - "light-green": "#ffffff", - "lime": "#000000", - "yellow": "#000000", - "amber": "#000000", - "orange": "#000000", - "deep-orange": "#ffffff", - "brown": "#ffffff", - "grey": "#ffffff", - "blue-grey": "#ffffff", - "black": "#ffffff", - "white": "#000000" - }[primary] or "#ffffff" }} - {%- endif -%} - - # Font family (default: Roboto) - - &font_family >- - {%- if layout.font_family -%} - {{ layout.font_family }} - {%- elif config.theme.font != false -%} - {{ config.theme.font.get("text", "Roboto") }} - {%- else -%} - Roboto - {%- endif -%} - - # Site name - - &site_name >- - {{ config.site_name }} - - # Page title - - &page_title >- - {%- if layout.title -%} - {{ layout.title }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page title with site name - - &page_title_with_site_name >- - {%- if not page.is_homepage -%} - {{ page.meta.get("title", page.title) }} - {{ config.site_name }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page description - - &page_description >- - {%- if layout.description -%} - {{ layout.description }} - {%- else -%} - {{ page.meta.get("description", config.site_description) | x }} - {%- endif -%} - - # Logo - - &logo >- - {%- if layout.logo -%} - {{ layout.logo }} - {%- elif config.theme.logo -%} - {{ config.docs_dir }}/{{ config.theme.logo }} - {%- endif -%} - - # Logo (icon) - - &logo_icon >- - {{ config.theme.icon.logo | x }} - -# Meta tags -tags: - - # Open Graph - og:type: website - og:title: *page_title_with_site_name - og:description: *page_description - og:image: "{{ image.url }}" - og:image:type: "{{ image.type }}" - og:image:width: "{{ image.width }}" - og:image:height: "{{ image.height }}" - og:url: "{{ page.canonical_url }}" - - # Twitter - twitter:card: summary_large_image - twitter.title: *page_title_with_site_name - twitter:description: *page_description - twitter:image: "{{ image.url }}" - -# ----------------------------------------------------------------------------- -# Specification -# ----------------------------------------------------------------------------- - -# Card size and layers -size: { width: 1200, height: 630 } -layers: - - # Background - - background: - image: *background_image - color: *background_color - - # Logo - - size: { width: 144, height: 144 } - offset: { x: 992, y: 64 } - background: - image: *logo - icon: - value: *logo_icon - color: *color - - # Site name - - size: { width: 832, height: 42 } - offset: { x: 64, y: 64 } - typography: - content: *site_name - color: *color - font: - family: *font_family - style: Bold - - # Page title - - size: { width: 832, height: 310 } - offset: { x: 62, y: 160 } - typography: - content: *page_title - align: start - color: *color - line: - amount: 3 - height: 1.25 - font: - family: *font_family - style: Bold - - # Page description - - size: { width: 832, height: 64 } - offset: { x: 64, y: 512 } - typography: - content: *page_description - align: start - color: *color - line: - amount: 2 - height: 1.5 - font: - family: *font_family - style: Regular diff --git a/plugins/social/templates/default/accent.yml b/plugins/social/templates/default/accent.yml deleted file mode 100644 index dde03b5..0000000 --- a/plugins/social/templates/default/accent.yml +++ /dev/null @@ -1,221 +0,0 @@ -# Copyright (c) 2016-2023 Martin Donath - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -# ----------------------------------------------------------------------------- -# Configuration -# ----------------------------------------------------------------------------- - -# Definitions -definitions: - - # Background image - - &background_image >- - {{ layout.background_image | x }} - - # Background color (default: indigo) - - &background_color >- - {%- if layout.background_color -%} - {{ layout.background_color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set accent = palette.get("accent", "indigo") -%} - {%- set accent = accent.replace(" ", "-") -%} - {{ { - "red": "#ff1a47", - "pink": "#f50056", - "purple": "#df41fb", - "deep-purple": "#7c4dff", - "indigo": "#526cfe", - "blue": "#4287ff", - "light-blue": "#0091eb", - "cyan": "#00bad6", - "teal": "#00bda4", - "green": "#00c753", - "light-green": "#63de17", - "lime": "#b0eb00", - "yellow": "#ffd500", - "amber": "#ffaa00", - "orange": "#ff9100", - "deep-orange": "#ff6e42" - }[accent] or "#4051b5" }} - {%- endif -%} - - # Text color (default: white) - - &color >- - {%- if layout.color -%} - {{ layout.color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set accent = palette.get("accent", "indigo") -%} - {%- set accent = accent.replace(" ", "-") -%} - {{ { - "red": "#ffffff", - "pink": "#ffffff", - "purple": "#ffffff", - "deep-purple": "#ffffff", - "indigo": "#ffffff", - "blue": "#ffffff", - "light-blue": "#ffffff", - "cyan": "#ffffff", - "teal": "#ffffff", - "green": "#ffffff", - "light-green": "#ffffff", - "lime": "#000000", - "yellow": "#000000", - "amber": "#000000", - "orange": "#000000", - "deep-orange": "#ffffff" - }[accent] or "#ffffff" }} - {%- endif -%} - - # Font family (default: Roboto) - - &font_family >- - {%- if layout.font_family -%} - {{ layout.font_family }} - {%- elif config.theme.font != false -%} - {{ config.theme.font.get("text", "Roboto") }} - {%- else -%} - Roboto - {%- endif -%} - - # Site name - - &site_name >- - {{ config.site_name }} - - # Page title - - &page_title >- - {%- if layout.title -%} - {{ layout.title }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page title with site name - - &page_title_with_site_name >- - {%- if not page.is_homepage -%} - {{ page.meta.get("title", page.title) }} - {{ config.site_name }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page description - - &page_description >- - {%- if layout.description -%} - {{ layout.description }} - {%- else -%} - {{ page.meta.get("description", config.site_description) | x }} - {%- endif -%} - - # Logo - - &logo >- - {%- if layout.logo -%} - {{ layout.logo }} - {%- elif config.theme.logo -%} - {{ config.docs_dir }}/{{ config.theme.logo }} - {%- endif -%} - - # Logo (icon) - - &logo_icon >- - {{ config.theme.icon.logo | x }} - -# Meta tags -tags: - - # Open Graph - og:type: website - og:title: *page_title_with_site_name - og:description: *page_description - og:image: "{{ image.url }}" - og:image:type: "{{ image.type }}" - og:image:width: "{{ image.width }}" - og:image:height: "{{ image.height }}" - og:url: "{{ page.canonical_url }}" - - # Twitter - twitter:card: summary_large_image - twitter.title: *page_title_with_site_name - twitter:description: *page_description - twitter:image: "{{ image.url }}" - -# ----------------------------------------------------------------------------- -# Specification -# ----------------------------------------------------------------------------- - -# Card size and layers -size: { width: 1200, height: 630 } -layers: - - # Background - - background: - image: *background_image - color: *background_color - - # Logo - - size: { width: 144, height: 144 } - offset: { x: 992, y: 64 } - background: - image: *logo - icon: - value: *logo_icon - color: *color - - # Site name - - size: { width: 832, height: 42 } - offset: { x: 64, y: 64 } - typography: - content: *site_name - color: *color - font: - family: *font_family - style: Bold - - # Page title - - size: { width: 832, height: 310 } - offset: { x: 62, y: 160 } - typography: - content: *page_title - align: start - color: *color - line: - amount: 3 - height: 1.25 - font: - family: *font_family - style: Bold - - # Page description - - size: { width: 832, height: 64 } - offset: { x: 64, y: 512 } - typography: - content: *page_description - align: start - color: *color - line: - amount: 2 - height: 1.5 - font: - family: *font_family - style: Regular diff --git a/plugins/social/templates/default/invert.yml b/plugins/social/templates/default/invert.yml deleted file mode 100644 index 7ea3644..0000000 --- a/plugins/social/templates/default/invert.yml +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright (c) 2016-2023 Martin Donath - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -# ----------------------------------------------------------------------------- -# Configuration -# ----------------------------------------------------------------------------- - -# Definitions -definitions: - - # Background image - - &background_image >- - {{ layout.background_image | x }} - - # Background color (default: white) - - &background_color >- - {%- if layout.background_color -%} - {{ layout.background_color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set primary = palette.get("primary", "indigo") -%} - {%- set primary = primary.replace(" ", "-") -%} - {{ { - "red": "#ffffff", - "pink": "#ffffff", - "purple": "#ffffff", - "deep-purple": "#ffffff", - "indigo": "#ffffff", - "blue": "#ffffff", - "light-blue": "#ffffff", - "cyan": "#ffffff", - "teal": "#ffffff", - "green": "#ffffff", - "light-green": "#ffffff", - "lime": "#000000", - "yellow": "#000000", - "amber": "#000000", - "orange": "#000000", - "deep-orange": "#ffffff", - "brown": "#ffffff", - "grey": "#ffffff", - "blue-grey": "#ffffff", - "black": "#ffffff", - "white": "#000000" - }[primary] or "#ffffff" }} - {%- endif -%} - - # Text color (default: indigo) - - &color >- - {%- if layout.color -%} - {{ layout.color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set primary = palette.get("primary", "indigo") -%} - {%- set primary = primary.replace(" ", "-") -%} - {{ { - "red": "#ef5552", - "pink": "#e92063", - "purple": "#ab47bd", - "deep-purple": "#7e56c2", - "indigo": "#4051b5", - "blue": "#2094f3", - "light-blue": "#02a6f2", - "cyan": "#00bdd6", - "teal": "#009485", - "green": "#4cae4f", - "light-green": "#8bc34b", - "lime": "#cbdc38", - "yellow": "#ffec3d", - "amber": "#ffc105", - "orange": "#ffa724", - "deep-orange": "#ff6e42", - "brown": "#795649", - "grey": "#757575", - "blue-grey": "#546d78", - "black": "#000000", - "white": "#ffffff" - }[primary] or "#4051b5" }} - {%- endif -%} - - # Font family (default: Roboto) - - &font_family >- - {%- if layout.font_family -%} - {{ layout.font_family }} - {%- elif config.theme.font != false -%} - {{ config.theme.font.get("text", "Roboto") }} - {%- else -%} - Roboto - {%- endif -%} - - # Site name - - &site_name >- - {{ config.site_name }} - - # Page title - - &page_title >- - {%- if layout.title -%} - {{ layout.title }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page title with site name - - &page_title_with_site_name >- - {%- if not page.is_homepage -%} - {{ page.meta.get("title", page.title) }} - {{ config.site_name }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page description - - &page_description >- - {%- if layout.description -%} - {{ layout.description }} - {%- else -%} - {{ page.meta.get("description", config.site_description) | x }} - {%- endif -%} - - # Logo - - &logo >- - {%- if layout.logo -%} - {{ layout.logo }} - {%- elif config.theme.logo -%} - {{ config.docs_dir }}/{{ config.theme.logo }} - {%- endif -%} - - # Logo (icon) - - &logo_icon >- - {{ config.theme.icon.logo | x }} - -# Meta tags -tags: - - # Open Graph - og:type: website - og:title: *page_title_with_site_name - og:description: *page_description - og:image: "{{ image.url }}" - og:image:type: "{{ image.type }}" - og:image:width: "{{ image.width }}" - og:image:height: "{{ image.height }}" - og:url: "{{ page.canonical_url }}" - - # Twitter - twitter:card: summary_large_image - twitter.title: *page_title_with_site_name - twitter:description: *page_description - twitter:image: "{{ image.url }}" - -# ----------------------------------------------------------------------------- -# Specification -# ----------------------------------------------------------------------------- - -# Card size and layers -size: { width: 1200, height: 630 } -layers: - - # Background - - background: - image: *background_image - color: *background_color - - # Logo - - size: { width: 144, height: 144 } - offset: { x: 992, y: 64 } - background: - image: *logo - icon: - value: *logo_icon - color: *color - - # Site name - - size: { width: 832, height: 42 } - offset: { x: 64, y: 64 } - typography: - content: *site_name - color: *color - font: - family: *font_family - style: Bold - - # Page title - - size: { width: 832, height: 310 } - offset: { x: 62, y: 160 } - typography: - content: *page_title - align: start - color: *color - line: - amount: 3 - height: 1.25 - font: - family: *font_family - style: Bold - - # Page description - - size: { width: 832, height: 64 } - offset: { x: 64, y: 512 } - typography: - content: *page_description - align: start - color: *color - line: - amount: 2 - height: 1.5 - font: - family: *font_family - style: Regular diff --git a/plugins/social/templates/default/only/image.yml b/plugins/social/templates/default/only/image.yml deleted file mode 100644 index ee10b9c..0000000 --- a/plugins/social/templates/default/only/image.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2016-2023 Martin Donath - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -# ----------------------------------------------------------------------------- -# Configuration -# ----------------------------------------------------------------------------- - -# Definitions -definitions: - - # Background image - - &background_image >- - {{ layout.background_image }} - - # Page title with site name - - &page_title_with_site_name >- - {%- if not page.is_homepage -%} - {{ page.meta.get("title", page.title) }} - {{ config.site_name }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page description - - &page_description >- - {%- if layout.description -%} - {{ layout.description }} - {%- else -%} - {{ page.meta.get("description", config.site_description) | x }} - {%- endif -%} - -# Meta tags -tags: - - # Open Graph - og:type: website - og:title: *page_title_with_site_name - og:description: *page_description - og:image: "{{ image.url }}" - og:image:type: "{{ image.type }}" - og:image:width: "{{ image.width }}" - og:image:height: "{{ image.height }}" - og:url: "{{ page.canonical_url }}" - - # Twitter - twitter:card: summary_large_image - twitter.title: *page_title_with_site_name - twitter:description: *page_description - twitter:image: "{{ image.url }}" - -# ----------------------------------------------------------------------------- -# Specification -# ----------------------------------------------------------------------------- - -# Card size and layers -size: { width: 1200, height: 630 } -layers: - - # Background - - background: - image: *background_image diff --git a/plugins/social/templates/default/variant.yml b/plugins/social/templates/default/variant.yml deleted file mode 100644 index 9f50537..0000000 --- a/plugins/social/templates/default/variant.yml +++ /dev/null @@ -1,242 +0,0 @@ -# Copyright (c) 2016-2023 Martin Donath - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -# ----------------------------------------------------------------------------- -# Configuration -# ----------------------------------------------------------------------------- - -# Definitions -definitions: - - # Background image - - &background_image >- - {{ layout.background_image | x }} - - # Background color (default: indigo) - - &background_color >- - {%- if layout.background_color -%} - {{ layout.background_color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set primary = palette.get("primary", "indigo") -%} - {%- set primary = primary.replace(" ", "-") -%} - {{ { - "red": "#ef5552", - "pink": "#e92063", - "purple": "#ab47bd", - "deep-purple": "#7e56c2", - "indigo": "#4051b5", - "blue": "#2094f3", - "light-blue": "#02a6f2", - "cyan": "#00bdd6", - "teal": "#009485", - "green": "#4cae4f", - "light-green": "#8bc34b", - "lime": "#cbdc38", - "yellow": "#ffec3d", - "amber": "#ffc105", - "orange": "#ffa724", - "deep-orange": "#ff6e42", - "brown": "#795649", - "grey": "#757575", - "blue-grey": "#546d78", - "black": "#000000", - "white": "#ffffff" - }[primary] or "#4051b5" }} - {%- endif -%} - - # Text color (default: white) - - &color >- - {%- if layout.color -%} - {{ layout.color }} - {%- else -%} - {%- set palette = config.theme.palette or {} -%} - {%- if not palette is mapping -%} - {%- set palette = palette | first -%} - {%- endif -%} - {%- set primary = palette.get("primary", "indigo") -%} - {%- set primary = primary.replace(" ", "-") -%} - {{ { - "red": "#ffffff", - "pink": "#ffffff", - "purple": "#ffffff", - "deep-purple": "#ffffff", - "indigo": "#ffffff", - "blue": "#ffffff", - "light-blue": "#ffffff", - "cyan": "#ffffff", - "teal": "#ffffff", - "green": "#ffffff", - "light-green": "#ffffff", - "lime": "#000000", - "yellow": "#000000", - "amber": "#000000", - "orange": "#000000", - "deep-orange": "#ffffff", - "brown": "#ffffff", - "grey": "#ffffff", - "blue-grey": "#ffffff", - "black": "#ffffff", - "white": "#000000" - }[primary] or "#ffffff" }} - {%- endif -%} - - # Font family (default: Roboto) - - &font_family >- - {%- if layout.font_family -%} - {{ layout.font_family }} - {%- elif config.theme.font != false -%} - {{ config.theme.font.get("text", "Roboto") }} - {%- else -%} - Roboto - {%- endif -%} - - # Site name - - &site_name >- - {{ config.site_name }} - - # Page title - - &page_title >- - {%- if layout.title -%} - {{ layout.title }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page title with site name - - &page_title_with_site_name >- - {%- if not page.is_homepage -%} - {{ page.meta.get("title", page.title) }} - {{ config.site_name }} - {%- else -%} - {{ page.meta.get("title", page.title) }} - {%- endif -%} - - # Page description - - &page_description >- - {%- if layout.description -%} - {{ layout.description }} - {%- else -%} - {{ page.meta.get("description", config.site_description) | x }} - {%- endif -%} - - # Page icon - - &page_icon >- - {{ page.meta.icon | x }} - - # Logo - - &logo >- - {%- if layout.logo -%} - {{ layout.logo }} - {%- elif config.theme.logo -%} - {{ config.docs_dir }}/{{ config.theme.logo }} - {%- endif -%} - - # Logo (icon) - - &logo_icon >- - {{ config.theme.icon.logo | x }} - -# Meta tags -tags: - - # Open Graph - og:type: website - og:title: *page_title_with_site_name - og:description: *page_description - og:image: "{{ image.url }}" - og:image:type: "{{ image.type }}" - og:image:width: "{{ image.width }}" - og:image:height: "{{ image.height }}" - og:url: "{{ page.canonical_url }}" - - # Twitter - twitter:card: summary_large_image - twitter.title: *page_title_with_site_name - twitter:description: *page_description - twitter:image: "{{ image.url }}" - -# ----------------------------------------------------------------------------- -# Specification -# ----------------------------------------------------------------------------- - -# Card size and layers -size: { width: 1200, height: 630 } -layers: - - # Background - - background: - image: *background_image - color: *background_color - - # Page icon - - size: { width: 630, height: 630 } - offset: { x: 800, y: 0 } - icon: - value: *page_icon - color: "#00000033" - - # Logo - - size: { width: 64, height: 64 } - offset: { x: 64, y: 64 } - background: - image: *logo - icon: - value: *logo_icon - color: *color - - # Site name - - size: { width: 768, height: 42 } - offset: { x: 160, y: 74 } - typography: - content: *site_name - color: *color - font: - family: *font_family - style: Bold - - # Page title - - size: { width: 864, height: 256 } - offset: { x: 62, y: 192 } - typography: - content: *page_title - align: start - color: *color - line: - amount: 3 - height: 1.25 - font: - family: *font_family - style: Bold - - # Page description - - size: { width: 864, height: 64 } - offset: { x: 64, y: 512 } - typography: - content: *page_description - align: start - color: *color - line: - amount: 2 - height: 1.5 - font: - family: *font_family - style: Regular diff --git a/quickrefs/iproute2/index.html b/quickrefs/iproute2/index.html index 92a316d..03415d4 100644 --- a/quickrefs/iproute2/index.html +++ b/quickrefs/iproute2/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Iproute2

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Iproute2

    + - + - + diff --git a/quickrefs/junos-os/index.html b/quickrefs/junos-os/index.html index ca41fc4..a8e73c5 100644 --- a/quickrefs/junos-os/index.html +++ b/quickrefs/junos-os/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Junos os

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Junos os

    + - + - + diff --git a/quickrefs/networkmanager/index.html b/quickrefs/networkmanager/index.html index 4031ecd..bd29243 100644 --- a/quickrefs/networkmanager/index.html +++ b/quickrefs/networkmanager/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Networkmanager

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Networkmanager

    + - + - + diff --git a/quickrefs/overview/index.html b/quickrefs/overview/index.html new file mode 100644 index 0000000..e650ab0 --- /dev/null +++ b/quickrefs/overview/index.html @@ -0,0 +1,1947 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overview - Telecom Craft Home Labs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + + + + +
    + + +
    + +
    + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    + + + + + + + + + + + +
    + + + + + + + +

    Quick References Overview

    + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickrefs/ping/index.html b/quickrefs/ping/index.html index e8228c8..ca297c0 100644 --- a/quickrefs/ping/index.html +++ b/quickrefs/ping/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Ping

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Ping

    + - + - + diff --git a/quickrefs/routeros-basic-cli/index.html b/quickrefs/routeros-basic-cli/index.html new file mode 100644 index 0000000..1f859b5 --- /dev/null +++ b/quickrefs/routeros-basic-cli/index.html @@ -0,0 +1,1896 @@ + + + + + + + + + + + + + + + + + + + + + + + + RouterOS Basic CLI Commands - Telecom Craft Home Labs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + + + + +
    + + +
    + +
    + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    + + + + + + + + + +
    + + + + + + + +

    RouterOS Basic CLI Commands

    +

    Set the identity (hostname)

    +
    system identity set name="My Router"
    +
    + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickrefs/routeros-basic-setup-checklist/index.html b/quickrefs/routeros-basic-setup-checklist/index.html new file mode 100644 index 0000000..b0a2cc0 --- /dev/null +++ b/quickrefs/routeros-basic-setup-checklist/index.html @@ -0,0 +1,2103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + RouterOS Basic Setup Checklist - Telecom Craft Home Labs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + +
    + +
    + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    + + + + + + + + + + + +
    + + + + + + + +

    RouterOS Basic Setup Checklist

    +

    Clear the Factory Default Configuration

    +

    Disable the Default User

    +

    Create a New User

    +

    Set an IP Address +Setup a Bridge for the LAN Subnet +Setup DHCP for the LAN Subnet +Setup NAT Source Masquerade +Setup the Default Gateway

    +

    + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickrefs/tcpdump/index.html b/quickrefs/tcpdump/index.html index b87d1ab..2de4a22 100644 --- a/quickrefs/tcpdump/index.html +++ b/quickrefs/tcpdump/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -308,6 +308,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -410,9 +428,13 @@ -
  • + + + + + +
  • - @@ -420,7 +442,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -659,7 +690,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -728,9 +812,13 @@ -
  • + + + + + +
  • - @@ -738,7 +826,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1240,13 +1337,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1268,31 +1391,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1566,10 +1754,10 @@

    Tcpdump

    + + + Back to top + @@ -1649,6 +1837,7 @@

    Tcpdump

    + - + - + diff --git a/search/search_index.json b/search/search_index.json index f8e5f42..6222297 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Welcome to Our Home Labs!","text":"

    There isn't too much to see here yet, but head over to the network labs to check out what we've developed so far or read a few articles on our blog to learn more about this site and what we have planned.

    "},{"location":"about/","title":"About This Site","text":"

    This website is dedicated to documenting our home labs. When we started planning out our home labs and making content, we thought it'd be great to have a place we could organize and share our materials in a way that made it easy for our audience to follow along, at their own pace.

    "},{"location":"tags/","title":"Content Index","text":"

    Use this page to find content by tag. Note that content may be marked with multiple tags.

    "},{"location":"tags/#juniper","title":"Juniper","text":"
    • Initial Junos OS Configuration on a vSRX
    • Installing Juniper vSRX on Proxmox
    "},{"location":"tags/#linux","title":"Linux","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#mikrotik","title":"MikroTik","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#proxmox","title":"Proxmox","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Installing Juniper vSRX on Proxmox
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    • Installing VyOS on Proxmox
    "},{"location":"tags/#routeros","title":"RouterOS","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#vyos","title":"VyOS","text":"
    • Initial VyOS Configuration Best Practices
    • Installing VyOS on Proxmox
    "},{"location":"blog/the-telecom-craft-homelabs-site-has-launched/","title":"The Telecom Craft Homelabs Site has Launched!","text":"

    Over the past few months, starting with our fiber optic home lab, we've been slowly making plans and laying the foundation for a broad collection of ICT home lab content. We wanted a place to organize our own learning materials and make that content available as a contribution back to the home lab community that we've learned so much from.

    We're pleased to share the first attempt at this goal with you here at labs.telecomcraft.com, where we practice the discipline of learning in public.

    On this site, we'll publish step-by-step lab exercises on topics such as fiber optics, networks, servers, and security, as well as quick references on common knowledge that we like to have handy and think you may, too. All content will be open, licensed under the Creative Commons, and we'll be planning and publishing new material with ideas and feedback from you, our audience.

    The primary goal of this site is to provide high-quality content that is both technically accurate and accessible so that you can follow along and replicate the steps without struggling too much. We always appreciate great documentation and tutorials and want to provide that level of positive experience to you, too.

    Be sure to check our blog regularly for announcements and updates, and subscribe to our YouTube channel and LinkedIn page for related content and activities.

    "},{"location":"diagrams/notes/","title":"Notes","text":"

    Diagram notes

    "},{"location":"labs/networks/overview/","title":"Network Labs Overview","text":"

    Welcome to the Telecom Craft Network Labs! We're only just getting started, but there are already some labs available in the General section, beginning with Initial Proxmox Network Configuration.

    "},{"location":"labs/networks/apnic/routing-labs/","title":"Overview","text":""},{"location":"labs/networks/apnic/mikrotik/overview/","title":"MikroTik Hands-On Exercises","text":""},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/","title":"Cloning a Network Host Template","text":"

    In the Creating a Network Host Template in Proxmox lab, you learned how to create a custom template of Ubuntu Linux to use as a network host for labs.

    In this lab, you'll learn how to clone and configure that template so it's ready to easily deploy new network hosts in your labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/#step-1-create-the-cloned-network-host","title":"Step 1: Create the Cloned Network Host","text":"
    • To clone the template, select the host0 CT template in the list to bring up that CT's views.
    • Click the More drop-down button at the top-right of the Proxmox VE window, then click Clone.
    • Select the target node (if you have a Proxmox VE cluster), otherwise leave the default selected.
    • Type host1 as the Hostname to identify this node.
    • Select Full Clone as the Mode to create a full and unlinked copy of the template.
    • Click the Clone button to proceed.

    Clone Dialog

    Once the cloning is done, you will see a new CT named host1 in the list.

    • Select the host1 CT and start it up.
    • Using the Console view, log in with the same non-root administrator account as you used for host0.
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/#step-2-configure-the-cloned-network-host","title":"Step 2: Configure the Cloned Network Host","text":"

    Before using the new network host in labs, there are several changes that have to be made to make it different from the template. The hostname, machine ID, and network interface's MAC address are changed as part of the cloning process itself.

    However there is one crucial change that you'll have to manually make for each new host after the clone is created: generating new SSH keys. This is an essential step for any VM or CT, so always verify this was properly done.

    First ensure no files starting with ssh_host exist:

    ls /etc/ssh\n

    Then generate new key pairs:

    sudo dpkg-reconfigure openssh-server\n

    Check again to confirm the creation of the new key pairs:

    ls /etc/ssh\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/#step-3-create-three-more-cloned-network-hosts","title":"Step 3: Create Three More Cloned Network Hosts","text":"

    Now your network host is ready for use. Remember to always complete the steps above when creating new hosts. Before we wrap this lab up, you'll get some more practice.

    Use the steps above to create three more hosts named host2, host3, and host4, which we'll be using in the next lab, Connecting and Configuring Network Hosts.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/","title":"Connecting and Configuring Network Hosts in Proxmox","text":"

    Imagine having two physical Linux servers, each with a single network adapter. If you interconnect the two servers with a patch cord, and configure the network adapters so they can communicate, what will you have?

    A simple, but fully-functional network. And that's where you'll begin your learning on building networks, which is all about connecting hosts together.

    In this lab, we're going to directly connect our network hosts together virtually by adding them to a Linux bridge and configuring them with basic network settings. No additional routers, switches, or firewalls will be necessary at this point; just the built-in functionality of Linux and Proxmox.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-1-create-a-linux-bridge-for-lab-connectivity","title":"Step 1: Create a Linux Bridge for Lab Connectivity","text":"

    A Linux bridge is like a basic switch integrated into the operating system that supports things like STP and VLAN trunking, and allows virtual machines and containers to communicate within hypervisors, like Proxmox.

    When installing Proxmox, a Linux bridge named vmbr0 will be created to connect the hypervisor to the outside world. In my own lab setup, I use vmbr0 to connect the Proxmox cluster and all VMs and CTs to my management subnet. By default, your CTs and Proxmox itself are running on that bridge.

    For our labs at this point, however, we have no need for our CTs to reach outside the lab subnet we'll be creating, so we'll create a second bridge just for our hosts to connect and communicate across. This provides a self-contained Layer 2 broadcast domain we can completely control, just like having a dedicated hardware switch with only your lab links connected.

    1. At the top of the Proxmox resource tree, select the Proxmox node your lab is running within and then select the System > Network view of the content panel.
    2. At the top-left of the network device table, click the Create dropdown button and select Linux Bridge.
    3. In the dialog box, ensure the Name is vmbr1 and Autostart is checked, then click the Create button.
    4. At the top of the network device table, click the Apply Configuration button and the new bridge will be enabled.
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-2-connecting-hosts-to-the-lab-bridge","title":"Step 2: Connecting Hosts to the Lab Bridge","text":"

    With our lab bridge created, we'll need to now change the bridge setting on each host's interface from vmbr0 to vmbr1. Think of this like moving a host's patch cord from one hardware switch to another.

    We'll also be changing each host's MAC address on its interface to match up with the interfaces used in our labs. This helps to ensure your results are consistent with the lab instructions. Use the table below for the MAC address assignments:

    Host MAC Address host1 00:50:56:94:55:70 host2 00:50:56:AD:0E:33 host3 00:50:56:16:30:C7 host4 00:50:56:AD:24:4A

    For each host, perform the following:

    1. From the Proxmox Web UI, select the CT in the resource tree and select the Network content panel.
    2. Select the network device
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-3-configuring-hosts-to-communicate-across-the-bridge","title":"Step 3: Configuring Hosts to Communicate Across the Bridge","text":"

    With our hosts all added to the same bridge, which by default is also the same broadcast domain, they will be able to communicate once they obtain IP address configurations.

    For this lab, we will be using the 10.0.1.0/24 IPv4 subnet for the lab network. Because our network devices are set to static addresses, we'll have to manually assign the right address to the right host. Use the table below for the IP address assignments:

    Host IPv4 Address host1 10.0.1.1/24 host2 10.0.1.2/24 host3 10.0.1.3/24 host4 10.0.1.4/24

    Within each host's Network settings in Proxmox, configure the eth0 network device's IPv4 setting to the respective address in the table above and verify the correct assigned address has been configured:

    sudo ip addr show eth0\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-3-confirm-host-communication-across-the-bridge","title":"Step 3: Confirm Host Communication Across the Bridge","text":"

    At this point, all hosts should be connected and reachable, or \"up.\" As a best practice, always verify this.

    The most common method is to use the ping command, so let's use host1 to test connectivity to the other three hosts. From host1, check to see if host2 is available:

    sudo ping -c4 10.0.1.2\n

    Our ping response should be:

    PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.\n64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.069 ms\n64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.035 ms\n64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=0.035 ms\n64 bytes from 10.0.1.2: icmp_seq=4 ttl=64 time=0.036 ms\n\n--- 10.0.1.2 ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 3071ms\nrtt min/avg/max/mdev = 0.035/0.043/0.069/0.014 ms\n

    Again from host1, check to see if host3 is available:

    sudo ping -c4 10.0.1.3\n

    Our ping response should be:

    PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.\n64 bytes from 10.0.1.3: icmp_seq=1 ttl=64 time=0.118 ms\n64 bytes from 10.0.1.3: icmp_seq=2 ttl=64 time=0.038 ms\n64 bytes from 10.0.1.3: icmp_seq=3 ttl=64 time=0.037 ms\n64 bytes from 10.0.1.3: icmp_seq=4 ttl=64 time=0.036 ms\n\n--- 10.0.1.3 ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 3077ms\nrtt min/avg/max/mdev = 0.036/0.057/0.118/0.035 ms\n

    Again from host1, check to see if host4 is available:

    sudo ping -c4 10.0.1.4\n

    Our ping response should be:

    PING 10.0.1.4 (10.0.1.4) 56(84) bytes of data.\n64 bytes from 10.0.1.4: icmp_seq=1 ttl=64 time=0.099 ms\n64 bytes from 10.0.1.4: icmp_seq=2 ttl=64 time=0.029 ms\n64 bytes from 10.0.1.4: icmp_seq=3 ttl=64 time=0.034 ms\n64 bytes from 10.0.1.4: icmp_seq=4 ttl=64 time=0.026 ms\n\n--- 10.0.1.4 ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 3068ms\nrtt min/avg/max/mdev = 0.026/0.047/0.099/0.030 ms\n

    While ping is an essential tool for network testing, when you are scanning subnets or looking for more information from hosts (such as what ports are open), use nmap. Let's test host connectivity again from host1, using nmap this time:

    nmap -sn 10.0.1.0/24\n

    Our network scan should be:

    Starting Nmap 7.80 ( https://nmap.org ) at 2023-06-21 11:15 UTC\nNmap scan report for 10.0.1.1\nHost is up (0.00034s latency).\nNmap scan report for 10.0.1.2\nHost is up (0.00031s latency).\nNmap scan report for 10.0.1.3\nHost is up (0.00021s latency).\nNmap scan report for 10.0.1.4\nHost is up (0.00016s latency).\nNmap done: 256 IP addresses (4 hosts up) scanned in 15.91 seconds\n

    With one command, we can tell nmap to scan the entire /24 subnet and report back the status of every host, including host1.

    Question

    Practice performing ping and nmap tests between the four hosts to get comfortable with these essential tools. Which approach for network discovery do you think is better?

    Well done! We have built an entire network of Linux hosts that can communicate with each other. In the next lab, Exploring Bridges, Subnets, and Broadcast Domains in Proxmox, we will begin exploring our network to better understand how everything works together.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/","title":"Creating a Network Host Template in Proxmox","text":"

    For a long time, network simulators like Packet Tracer and GNS3 would provide a very basic network host such as VPCS, which could only do a very limited subset of network functions such as serving as a DHCP client and responding to pings.

    But the role of network hosts in your labs can become capable of so much more functionality by using real operating systems such as Linux. Using them offers an opportunity to not only become more familiar with real hosts, but gain a deeper understanding into networking fundamentals as well.

    In addition, because nearly every network operating system (NOS) is built on Linux, understanding the underlying networking capabilities of the Linux kernel and all the included tools in a Linux host provide insights into how routers, switches, and firewalls work.

    In this lab we're going to create an Ubuntu Linux \"template\" inside Proxmox VE that can be cloned and used as powerful network hosts to interact with inside our network labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-1-download-ubuntu-2204-lxc-template-onto-a-proxmox-ve-node","title":"Step 1: Download Ubuntu 22.04 LXC Template Onto a Proxmox VE Node","text":"

    A big advantage of Proxmox for creating labs is the availability of Linux Containers (LXC), a lightweight way to create isolated instances of Linux that are much more efficient than using full virtual machines. The Proxmox UI makes it extremely easy to install and manage containers, so that's what we'll do here.

    • In the Proxmox VE tree, select the local storage view, and select the CT Templates submenu item.
    • At the top of the view, click the Templates button and search for ubuntu-22.04-standard in the search box.
    • Select that item in the list and click the Download button to save that template to your Proxmox VE storage.

    Screenshot

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-2-create-a-proxmox-ct-using-the-ubuntu-lxc-template","title":"Step 2: Create a Proxmox CT Using the Ubuntu LXC Template","text":"

    With the Ubuntu 22.04 LXC template downloaded, we can now create a container in Proxmox (abbreviated to CT) using this template. Click the Create CT button at the top-right of the Proxmox VE window to get started.

    • On the General tab, make sure the correct node (if you have a Proxmox VE cluster) that you saved the Ubuntu LXC template to is selected.
    • Set the hostname to host0.
    • Set and confirm the root password for the CT.

    Screenshot of General

    • On the Template tab, make sure Storage is set to local, and select ubuntu-22.04-1-standard_22.04-1_amd64.tar.zst (or your equivalent based on the platform) for Template.

    Screenshot of Template

    • One the Disks tab, leave all default configurations in place.

    Screenshot of Disks

    • One the CPU tab, leave all default configurations in place.

    Screenshot of CPU

    • One the Memory tab, leave all default configurations in place.

    Screenshot of Memory

    • One the Network tab, change the IPv4 to DHCP. Note that this assumes the default bridge vmbr0 is connected to a gateway that can respond to DHCP requests on an Internet-connected LAN subnet.

    Screenshot of Network

    • One the DNS tab, leave all default configurations in place.

    Screenshot of DNS

    • One the Confirm tab, review all your settings and when complete, click the Finish button.

    Screenshot of Confirm

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-3-update-and-configure-the-ubuntu-linux-ct-for-use-as-a-network-host","title":"Step 3: Update and Configure the Ubuntu Linux CT for Use as a Network Host","text":"

    Before this CT can become a custom template for cloning, there is some configuration to it that must be done. Select the newly-created host0 CT from the list, then select the Console tab and click the Start Now button to run the CT.

    From there, log into the CT's root account using the password entered in Step 2 above, and perform the following configuration tasks.

    Add a non-root administrator account and fill out the proceeding prompts:

    adduser admin\n

    Add the newly-created account to the sudo group to use administrator priveleges:

    addgroup admin sudo\n

    Log out of the root account then log in again using your new user name and password:

    logout\n

    Tip

    Upon login, you should see the following message confirming sudo priveleges:

    To run a command as administrator (user \"root\"), use \"sudo \". See \"man sudo_root\" for details.

    Upgrade all existing packages:

    sudo apt update && sudo apt dist-upgrade\n

    Install several additional packages:

    sudo apt install network-manager nmap ipcalc\n

    Clean up the package database:

    sudo apt clean\n

    Clean up unnecessary packages:

    sudo apt autoremove\n

    Remove the current SSH host keys so each clone regenerates new keys:

    sudo rm /etc/ssh/ssh_host_*\n

    Remove the current machine ID so each clone regenerates a new ID:

    sudo truncate -s 0 /etc/machine-id\n

    Shut down the CT:

    sudo systemctl poweroff\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-4-convert-the-ubuntu-linux-ct-into-a-custom-container-template","title":"Step 4: Convert the Ubuntu Linux CT into a Custom Container Template","text":"

    You're now ready to convert this CT into a custom template.

    • With the CT powered down, click the More drop-down button at the top-right of the Proxmox VE window, then click Convert to template.
    • Click the Yes button to proceed, and the CT will be converted into a template.

    Your network host template is now ready. Complete the Cloning a Network Host Template in Proxmox lab to practice creating Ubuntu Linux network hosts for use in upcoming labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/","title":"Exploring Subnets and VLANs in Proxmox","text":"","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#introduction","title":"Introduction","text":"

    In this lab we're going to continue exploring subnets and begin to look at the role of VLANs in addressing the broadcast domain issue we observed in the previous lab. Recall from that lab that we ended up with two subnets on the same bridge and shared the same broadcast domain.

    VLANs are a way to logically separate broadcast domains within the same Layer 2 network, such as a bridge or switch. This allows us to reduce broadcasts and flooding, which improves network performance. VLANs also:

    • increase network security by segmenting Layer 2 networks and enabling fine-grained control of inter-VLAN communication between hosts via routing and firewalls,
    • provide management flexibility in organizing and controlling traffic based on each host or subnet's role, functions, or priority (quality of service [QoS]) and
    • maximize hardware utilization by enabling multiple VLANs to either exist on the same bridge or switch as well as connecting across multiple bridges or switches.

    In this lab we're going to concentrate on segmenting broadcast domains using VLANs, but we'll be addressing the other applications of VLANs in future labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#step-1-configure-the-bridge-to-be-vlan-aware","title":"Step 1: Configure the Bridge to Be VLAN Aware","text":"

    Before we begin experimenting with VLANS, we have to make a change to bridge vmbr1 in order to allow VLANs on the hosts. On the Networks view of the Proxmox node, edit vmbr1 and check \"VLAN aware.\" Then click the Apply Configuration button and you're ready to use VLANs on the bridge.

    Warning

    Ensure this configuration is performed before attempting to apply VLAN settings to hosts on a bridge. Otherwise, you'll get errors.

    The same is true for attempting to disable VLAN settings on a bridge. In this case, if hosts are configured with VLANs, and you try to uncheck \"VLAN aware\" on the bridge, you will get errors here, as well.

    There are other VLAN configuration options within Proxmox, but this is simplest and most consistent way to configure them at this point. We'll dig into advanced Proxmox networking in future labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#step-2-assign-subnets-to-vlans","title":"Step 2: Assign Subnets to VLANs","text":"

    With the bridge now VLAN aware, it's time to assign VLANS to each subnet in order to separate each subnet's broadcast domain. To do this, we'll use a common VLAN to subnet numbering convention that is helpful while learning these concepts.

    Tip

    Using one VLAN per subnet is the recommended best practice.

    We're going to create two new subnets: 10.0.10.0/24 and 10.0.20.0/24, and assign VLAN 10 to the first subnet and VLAN 20 to the second subnet. Using this convention, the third octet of the subnet matches the VLAN ID.

    Warning

    This numbering convention is helpful for learning purposes, but will often break down or not scale in production networks, and also should not be used as a substitute for good documentation.

    We'll cover both network address planning and documentation in future labs.

    host1 and host2 are going to be assigned to the 10.0.10.0/24 subnet, and host3 and host4 are going to be assigned to the 10.0.20.0/24 subnet. Here's the new addressing plan for our four hosts:

    Host IPv4 Address VLAN host1 10.0.10.1/24 10 host2 10.0.10.2/24 10 host3 10.0.20.3/24 20 host4 10.0.20.4/24 20

    Make these changes by updating the IPv4 address and VLAN ID settings within the network configurations for each host in Proxmox. Verify each host has the right IPv4 address by running an ip command that displays host addressing and reviewing the output:

    ip a\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#step-3-verify-broadcast-domain-isolation-for-each-subnet","title":"Step 3: Verify Broadcast Domain Isolation for Each Subnet","text":"

    Once all configuration changes are made, we'll be ready to verify that the VLANs now isolate the two broadcast domains, as expected. To test, we're going to use nmap again, but this time, we'll also see how it works behind the scenes so you understand why it's a good choice for this test.

    Open up all four hosts in the quarter tile layout so they're all visible, and begin packet captures on host2 and host4:

    sudo tcpdump\n

    Next, we're going to perform a quick scan of each subnet and then examine the results. Starting on host1, run the following on host1:

    nmap -sn 10.0.10.0/24\n

    Then check the output on both host1 and host2

    eron@host1:~$ nmap -sn 10.0.10.0/24\nStarting Nmap 7.80 ( https://nmap.org ) at 2023-06-27 13:54 UTC\nNmap scan report for 10.0.10.1\nHost is up (0.00033s latency).\nNmap scan report for 10.0.10.2\nHost is up (0.00023s latency).\nNmap done: 256 IP addresses (2 hosts up) scanned in 15.91 seconds\n
    eron@host2:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n13:54:02.238931 IP 10.0.10.1.54440 > 10.0.10.2.http: Flags [S], seq 3772918725, win 64240, options [mss 1460,sackOK,TS val 3851871978 ecr 0,nop,wscale 7], length 0\n13:54:02.238938 IP 10.0.10.2.http > 10.0.10.1.54440: Flags [R.], seq 0, ack 3772918726, win 0, length 0\n13:54:02.238976 ARP, Request who-has 10.0.10.3 tell 10.0.10.1, length 28\n13:54:02.238996 ARP, Request who-has 10.0.10.4 tell 10.0.10.1, length 28\n13:54:02.239034 ARP, Request who-has 10.0.10.5 tell 10.0.10.1, length 28\n13:54:02.239061 ARP, Request who-has 10.0.10.6 tell 10.0.10.1, length 28\n13:54:02.239079 ARP, Request who-has 10.0.10.7 tell 10.0.10.1, length 28\n13:54:02.239114 ARP, Request who-has 10.0.10.8 tell 10.0.10.1, length 28\n13:54:02.239140 ARP, Request who-has 10.0.10.9 tell 10.0.10.1, length 28\n13:54:02.239174 ARP, Request who-has 10.0.10.10 tell 10.0.10.1, length 28\n13:54:02.239278 ARP, Request who-has 10.0.10.13 tell 10.0.10.1, length 28\n13:54:02.239317 ARP, Request who-has 10.0.10.14 tell 10.0.10.1, length 28\n13:54:02.239343 ARP, Request who-has 10.0.10.15 tell 10.0.10.1, length 28\n13:54:02.239359 ARP, Request who-has 10.0.10.16 tell 10.0.10.1, length 28\n13:54:02.339041 ARP, Request who-has 10.0.10.65 tell 10.0.10.1, length 28\n13:54:02.339115 ARP, Request who-has 10.0.10.68 tell 10.0.10.1, length 28\n13:54:02.339142 ARP, Request who-has 10.0.10.69 tell 10.0.10.1, length 28\n13:54:02.339160 ARP, Request who-has 10.0.10.70 tell 10.0.10.1, length 28\n13:54:02.339230 ARP, Request who-has 10.0.10.73 tell 10.0.10.1, length 28\n13:54:02.339249 ARP, Request who-has 10.0.10.74 tell 10.0.10.1, length 28\n13:54:02.339267 ARP, Request who-has 10.0.10.75 tell 10.0.10.1, length 28\n13:54:02.339284 ARP, Request who-has 10.0.10.76 tell 10.0.10.1, length 28\n13:54:02.339345 ARP, Request who-has 10.0.10.79 tell 10.0.10.1, length 28\n13:54:02.339362 ARP, Request who-has 10.0.10.80 tell 10.0.10.1, length 28\n13:54:02.339424 ARP, Request who-has 10.0.10.83 tell 10.0.10.1, length 28\n13:54:02.339441 ARP, Request who-has 10.0.10.84 tell 10.0.10.1, length 28\n13:54:02.439092 ARP, Request who-has 10.0.10.131 tell 10.0.10.1, length 28\n13:54:02.439157 ARP, Request who-has 10.0.10.134 tell 10.0.10.1, length 28\n13:54:02.439220 ARP, Request who-has 10.0.10.137 tell 10.0.10.1, length 28\n13:54:02.439238 ARP, Request who-has 10.0.10.138 tell 10.0.10.1, length 28\n13:54:02.439299 ARP, Request who-has 10.0.10.141 tell 10.0.10.1, length 28\n13:54:02.439317 ARP, Request who-has 10.0.10.142 tell 10.0.10.1, length 28\n13:54:02.439378 ARP, Request who-has 10.0.10.145 tell 10.0.10.1, length 28\n13:54:02.439400 ARP, Request who-has 10.0.10.146 tell 10.0.10.1, length 28\n13:54:02.439464 ARP, Request who-has 10.0.10.149 tell 10.0.10.1, length 28\n13:54:02.439483 ARP, Request who-has 10.0.10.150 tell 10.0.10.1, length 28\n13:54:02.439500 ARP, Request who-has 10.0.10.151 tell 10.0.10.1, length 28\n13:54:02.439558 ARP, Request who-has 10.0.10.154 tell 10.0.10.1, length 28\n13:54:02.539133 ARP, Request who-has 10.0.10.193 tell 10.0.10.1, length 28\n13:54:02.539197 ARP, Request who-has 10.0.10.196 tell 10.0.10.1, length 28\n13:54:02.539257 ARP, Request who-has 10.0.10.199 tell 10.0.10.1, length 28\n13:54:02.539315 ARP, Request who-has 10.0.10.202 tell 10.0.10.1, length 28\n13:54:02.539376 ARP, Request who-has 10.0.10.205 tell 10.0.10.1, length 28\n13:54:02.539395 ARP, Request who-has 10.0.10.206 tell 10.0.10.1, length 28\n13:54:02.539455 ARP, Request who-has 10.0.10.209 tell 10.0.10.1, length 28\n13:54:02.539474 ARP, Request who-has 10.0.10.210 tell 10.0.10.1, length 28\n13:54:02.539547 ARP, Request who-has 10.0.10.213 tell 10.0.10.1, length 28\n13:54:02.539565 ARP, Request who-has 10.0.10.214 tell 10.0.10.1, length 28\n13:54:02.539631 ARP, Request who-has 10.0.10.217 tell 10.0.10.1, length 28\n13:54:02.539651 ARP, Request who-has 10.0.10.218 tell 10.0.10.1, length 28\n13:54:02.639187 ARP, Request who-has 10.0.10.253 tell 10.0.10.1, length 28\n13:54:02.639252 ARP, Request who-has 10.0.10.0 tell 10.0.10.1, length 28\n13:54:02.639311 ARP, Request who-has 10.0.10.11 tell 10.0.10.1, length 28\n13:54:02.639369 ARP, Request who-has 10.0.10.17 tell 10.0.10.1, length 28\n13:54:02.639426 ARP, Request who-has 10.0.10.20 tell 10.0.10.1, length 28\n13:54:02.639483 ARP, Request who-has 10.0.10.23 tell 10.0.10.1, length 28\n13:54:02.639544 ARP, Request who-has 10.0.10.26 tell 10.0.10.1, length 28\n13:54:02.639562 ARP, Request who-has 10.0.10.27 tell 10.0.10.1, length 28\n13:54:02.639622 ARP, Request who-has 10.0.10.30 tell 10.0.10.1, length 28\n13:54:02.639640 ARP, Request who-has 10.0.10.31 tell 10.0.10.1, length 28\n13:54:02.639700 ARP, Request who-has 10.0.10.34 tell 10.0.10.1, length 28\n13:54:02.639718 ARP, Request who-has 10.0.10.35 tell 10.0.10.1, length 28\n13:54:02.739241 ARP, Request who-has 10.0.10.71 tell 10.0.10.1, length 28\n13:54:02.739306 ARP, Request who-has 10.0.10.77 tell 10.0.10.1, length 28\n13:54:02.739367 ARP, Request who-has 10.0.10.81 tell 10.0.10.1, length 28\n13:54:02.739429 ARP, Request who-has 10.0.10.85 tell 10.0.10.1, length 28\n13:54:02.739490 ARP, Request who-has 10.0.10.88 tell 10.0.10.1, length 28\n13:54:02.739549 ARP, Request who-has 10.0.10.91 tell 10.0.10.1, length 28\n13:54:02.739609 ARP, Request who-has 10.0.10.94 tell 10.0.10.1, length 28\n13:54:02.739626 ARP, Request who-has 10.0.10.95 tell 10.0.10.1, length 28\n13:54:02.739688 ARP, Request who-has 10.0.10.98 tell 10.0.10.1, length 28\n13:54:02.739705 ARP, Request who-has 10.0.10.99 tell 10.0.10.1, length 28\n13:54:02.739771 ARP, Request who-has 10.0.10.102 tell 10.0.10.1, length 28\n13:54:02.739793 ARP, Request who-has 10.0.10.103 tell 10.0.10.1, length 28\n13:54:02.839291 ARP, Request who-has 10.0.10.132 tell 10.0.10.1, length 28\n13:54:02.839359 ARP, Request who-has 10.0.10.135 tell 10.0.10.1, length 28\n13:54:02.839420 ARP, Request who-has 10.0.10.139 tell 10.0.10.1, length 28\n13:54:02.839481 ARP, Request who-has 10.0.10.143 tell 10.0.10.1, length 28\n13:54:02.839540 ARP, Request who-has 10.0.10.147 tell 10.0.10.1, length 28\n13:54:02.839599 ARP, Request who-has 10.0.10.152 tell 10.0.10.1, length 28\n13:54:02.839660 ARP, Request who-has 10.0.10.155 tell 10.0.10.1, length 28\n13:54:02.839724 ARP, Request who-has 10.0.10.158 tell 10.0.10.1, length 28\n13:54:02.839743 ARP, Request who-has 10.0.10.159 tell 10.0.10.1, length 28\n13:54:02.839802 ARP, Request who-has 10.0.10.162 tell 10.0.10.1, length 28\n13:54:02.839862 ARP, Request who-has 10.0.10.165 tell 10.0.10.1, length 28\n13:54:02.839880 ARP, Request who-has 10.0.10.166 tell 10.0.10.1, length 28\n13:54:02.939327 ARP, Request who-has 10.0.10.191 tell 10.0.10.1, length 28\n13:54:02.939393 ARP, Request who-has 10.0.10.194 tell 10.0.10.1, length 28\n13:54:02.939454 ARP, Request who-has 10.0.10.197 tell 10.0.10.1, length 28\n13:54:02.939513 ARP, Request who-has 10.0.10.200 tell 10.0.10.1, length 28\n13:54:02.939591 ARP, Request who-has 10.0.10.207 tell 10.0.10.1, length 28\n13:54:02.939649 ARP, Request who-has 10.0.10.211 tell 10.0.10.1, length 28\n13:54:02.939708 ARP, Request who-has 10.0.10.215 tell 10.0.10.1, length 28\n13:54:02.939767 ARP, Request who-has 10.0.10.219 tell 10.0.10.1, length 28\n13:54:02.939825 ARP, Request who-has 10.0.10.222 tell 10.0.10.1, length 28\n13:54:02.939884 ARP, Request who-has 10.0.10.225 tell 10.0.10.1, length 28\n13:54:02.939946 ARP, Request who-has 10.0.10.228 tell 10.0.10.1, length 28\n13:54:02.939966 ARP, Request who-has 10.0.10.229 tell 10.0.10.1, length 28\n13:54:03.040226 ARP, Request who-has 10.0.10.232 tell 10.0.10.1, length 28\n13:54:03.040248 ARP, Request who-has 10.0.10.233 tell 10.0.10.1, length 28\n13:54:03.040266 ARP, Request who-has 10.0.10.234 tell 10.0.10.1, length 28\n13:54:03.040292 ARP, Request who-has 10.0.10.235 tell 10.0.10.1, length 28\n13:54:03.040309 ARP, Request who-has 10.0.10.236 tell 10.0.10.1, length 28\n13:54:03.040327 ARP, Request who-has 10.0.10.237 tell 10.0.10.1, length 28\n13:54:03.040345 ARP, Request who-has 10.0.10.238 tell 10.0.10.1, length 28\n13:54:03.040362 ARP, Request who-has 10.0.10.239 tell 10.0.10.1, length 28\n13:54:03.040378 ARP, Request who-has 10.0.10.240 tell 10.0.10.1, length 28\n13:54:03.040395 ARP, Request who-has 10.0.10.241 tell 10.0.10.1, length 28\n13:54:03.040413 ARP, Request who-has 10.0.10.242 tell 10.0.10.1, length 28\n13:54:03.040430 ARP, Request who-has 10.0.10.243 tell 10.0.10.1, length 28\n13:54:03.140269 ARP, Request who-has 10.0.10.60 tell 10.0.10.1, length 28\n13:54:03.140341 ARP, Request who-has 10.0.10.63 tell 10.0.10.1, length 28\n13:54:03.140361 ARP, Request who-has 10.0.10.64 tell 10.0.10.1, length 28\n13:54:03.140382 ARP, Request who-has 10.0.10.66 tell 10.0.10.1, length 28\n13:54:03.140456 ARP, Request who-has 10.0.10.72 tell 10.0.10.1, length 28\n13:54:03.140475 ARP, Request who-has 10.0.10.78 tell 10.0.10.1, length 28\n13:54:03.140492 ARP, Request who-has 10.0.10.82 tell 10.0.10.1, length 28\n13:54:03.140509 ARP, Request who-has 10.0.10.86 tell 10.0.10.1, length 28\n13:54:03.140526 ARP, Request who-has 10.0.10.87 tell 10.0.10.1, length 28\n13:54:03.140543 ARP, Request who-has 10.0.10.89 tell 10.0.10.1, length 28\n13:54:03.140607 ARP, Request who-has 10.0.10.92 tell 10.0.10.1, length 28\n13:54:03.140630 ARP, Request who-has 10.0.10.93 tell 10.0.10.1, length 28\n13:54:03.240320 ARP, Request who-has 10.0.10.148 tell 10.0.10.1, length 28\n13:54:03.240387 ARP, Request who-has 10.0.10.153 tell 10.0.10.1, length 28\n13:54:03.240455 ARP, Request who-has 10.0.10.156 tell 10.0.10.1, length 28\n13:54:03.240474 ARP, Request who-has 10.0.10.157 tell 10.0.10.1, length 28\n13:54:03.240538 ARP, Request who-has 10.0.10.160 tell 10.0.10.1, length 28\n13:54:03.240556 ARP, Request who-has 10.0.10.161 tell 10.0.10.1, length 28\n13:54:03.240573 ARP, Request who-has 10.0.10.163 tell 10.0.10.1, length 28\n13:54:03.240638 ARP, Request who-has 10.0.10.167 tell 10.0.10.1, length 28\n13:54:03.240663 ARP, Request who-has 10.0.10.168 tell 10.0.10.1, length 28\n13:54:03.240681 ARP, Request who-has 10.0.10.169 tell 10.0.10.1, length 28\n13:54:03.240744 ARP, Request who-has 10.0.10.172 tell 10.0.10.1, length 28\n13:54:03.240764 ARP, Request who-has 10.0.10.173 tell 10.0.10.1, length 28\n13:54:03.240880 ARP, Request who-has 10.0.10.16 tell 10.0.10.1, length 28\n13:54:03.240882 ARP, Request who-has 10.0.10.15 tell 10.0.10.1, length 28\n13:54:03.240882 ARP, Request who-has 10.0.10.14 tell 10.0.10.1, length 28\n13:54:03.240883 ARP, Request who-has 10.0.10.13 tell 10.0.10.1, length 28\n13:54:03.240884 ARP, Request who-has 10.0.10.10 tell 10.0.10.1, length 28\n13:54:03.240885 ARP, Request who-has 10.0.10.9 tell 10.0.10.1, length 28\n13:54:03.240885 ARP, Request who-has 10.0.10.8 tell 10.0.10.1, length 28\n13:54:03.240886 ARP, Request who-has 10.0.10.7 tell 10.0.10.1, length 28\n13:54:03.240887 ARP, Request who-has 10.0.10.6 tell 10.0.10.1, length 28\n13:54:03.240887 ARP, Request who-has 10.0.10.5 tell 10.0.10.1, length 28\n13:54:03.240888 ARP, Request who-has 10.0.10.4 tell 10.0.10.1, length 28\n13:54:03.240889 ARP, Request who-has 10.0.10.3 tell 10.0.10.1, length 28\n13:54:03.368936 ARP, Request who-has 10.0.10.84 tell 10.0.10.1, length 28\n13:54:03.368938 ARP, Request who-has 10.0.10.83 tell 10.0.10.1, length 28\n13:54:03.368939 ARP, Request who-has 10.0.10.80 tell 10.0.10.1, length 28\n13:54:03.368939 ARP, Request who-has 10.0.10.79 tell 10.0.10.1, length 28\n13:54:03.368940 ARP, Request who-has 10.0.10.76 tell 10.0.10.1, length 28\n13:54:03.368940 ARP, Request who-has 10.0.10.75 tell 10.0.10.1, length 28\n13:54:03.368941 ARP, Request who-has 10.0.10.74 tell 10.0.10.1, length 28\n13:54:03.368942 ARP, Request who-has 10.0.10.73 tell 10.0.10.1, length 28\n13:54:03.368942 ARP, Request who-has 10.0.10.70 tell 10.0.10.1, length 28\n13:54:03.368943 ARP, Request who-has 10.0.10.69 tell 10.0.10.1, length 28\n13:54:03.368943 ARP, Request who-has 10.0.10.68 tell 10.0.10.1, length 28\n13:54:03.368944 ARP, Request who-has 10.0.10.65 tell 10.0.10.1, length 28\n13:54:03.464947 ARP, Request who-has 10.0.10.154 tell 10.0.10.1, length 28\n13:54:03.464950 ARP, Request who-has 10.0.10.151 tell 10.0.10.1, length 28\n13:54:03.464951 ARP, Request who-has 10.0.10.150 tell 10.0.10.1, length 28\n13:54:03.464952 ARP, Request who-has 10.0.10.149 tell 10.0.10.1, length 28\n13:54:03.464952 ARP, Request who-has 10.0.10.146 tell 10.0.10.1, length 28\n13:54:03.464953 ARP, Request who-has 10.0.10.145 tell 10.0.10.1, length 28\n13:54:03.464954 ARP, Request who-has 10.0.10.142 tell 10.0.10.1, length 28\n13:54:03.464954 ARP, Request who-has 10.0.10.141 tell 10.0.10.1, length 28\n13:54:03.464955 ARP, Request who-has 10.0.10.138 tell 10.0.10.1, length 28\n13:54:03.464955 ARP, Request who-has 10.0.10.137 tell 10.0.10.1, length 28\n13:54:03.464956 ARP, Request who-has 10.0.10.134 tell 10.0.10.1, length 28\n13:54:03.464957 ARP, Request who-has 10.0.10.131 tell 10.0.10.1, length 28\n13:54:03.540432 IP 10.0.10.1.54454 > 10.0.10.2.http: Flags [S], seq 1946917605, win 64240, options [mss 1460,sackOK,TS val 3851873279 ecr 0,nop,wscale 7], length 0\n13:54:03.540440 IP 10.0.10.2.http > 10.0.10.1.54454: Flags [R.], seq 0, ack 1946917606, win 0, length 0\n13:54:03.540670 ARP, Request who-has 10.0.10.96 tell 10.0.10.1, length 28\n13:54:03.540691 ARP, Request who-has 10.0.10.97 tell 10.0.10.1, length 28\n13:54:03.540709 ARP, Request who-has 10.0.10.100 tell 10.0.10.1, length 28\n13:54:03.540727 ARP, Request who-has 10.0.10.101 tell 10.0.10.1, length 28\n13:54:03.540747 ARP, Request who-has 10.0.10.104 tell 10.0.10.1, length 28\n13:54:03.540765 ARP, Request who-has 10.0.10.105 tell 10.0.10.1, length 28\n13:54:03.540782 ARP, Request who-has 10.0.10.106 tell 10.0.10.1, length 28\n13:54:03.540808 ARP, Request who-has 10.0.10.107 tell 10.0.10.1, length 28\n13:54:03.540842 ARP, Request who-has 10.0.10.108 tell 10.0.10.1, length 28\n13:54:03.540860 ARP, Request who-has 10.0.10.109 tell 10.0.10.1, length 28\n13:54:03.540877 ARP, Request who-has 10.0.10.110 tell 10.0.10.1, length 28\n13:54:03.540896 ARP, Request who-has 10.0.10.111 tell 10.0.10.1, length 28\n13:54:03.540913 ARP, Request who-has 10.0.10.112 tell 10.0.10.1, length 28\n13:54:03.540932 ARP, Request who-has 10.0.10.113 tell 10.0.10.1, length 28\n13:54:03.540950 ARP, Request who-has 10.0.10.114 tell 10.0.10.1, length 28\n13:54:03.540970 ARP, Request who-has 10.0.10.115 tell 10.0.10.1, length 28\n13:54:03.540988 ARP, Request who-has 10.0.10.116 tell 10.0.10.1, length 28\n13:54:03.541005 ARP, Request who-has 10.0.10.117 tell 10.0.10.1, length 28\n13:54:03.541023 ARP, Request who-has 10.0.10.118 tell 10.0.10.1, length 28\n13:54:03.541040 ARP, Request who-has 10.0.10.119 tell 10.0.10.1, length 28\n13:54:03.541058 ARP, Request who-has 10.0.10.120 tell 10.0.10.1, length 28\n13:54:03.541079 ARP, Request who-has 10.0.10.121 tell 10.0.10.1, length 28\n13:54:03.541096 ARP, Request who-has 10.0.10.122 tell 10.0.10.1, length 28\n13:54:03.541114 ARP, Request who-has 10.0.10.123 tell 10.0.10.1, length 28\n13:54:03.541133 ARP, Request who-has 10.0.10.124 tell 10.0.10.1, length 28\n13:54:03.541153 ARP, Request who-has 10.0.10.125 tell 10.0.10.1, length 28\n13:54:03.541170 ARP, Request who-has 10.0.10.126 tell 10.0.10.1, length 28\n13:54:03.541189 ARP, Request who-has 10.0.10.127 tell 10.0.10.1, length 28\n13:54:03.541207 ARP, Request who-has 10.0.10.128 tell 10.0.10.1, length 28\n13:54:03.541229 ARP, Request who-has 10.0.10.129 tell 10.0.10.1, length 28\n13:54:03.541248 ARP, Request who-has 10.0.10.130 tell 10.0.10.1, length 28\n13:54:03.541273 ARP, Request who-has 10.0.10.133 tell 10.0.10.1, length 28\n13:54:03.541298 ARP, Request who-has 10.0.10.136 tell 10.0.10.1, length 28\n13:54:03.541337 ARP, Request who-has 10.0.10.140 tell 10.0.10.1, length 28\n13:54:03.541441 ARP, Request who-has 10.0.10.144 tell 10.0.10.1, length 28\n13:54:03.541514 ARP, Request who-has 10.0.10.164 tell 10.0.10.1, length 28\n13:54:03.541530 ARP, Request who-has 10.0.10.170 tell 10.0.10.1, length 28\n13:54:03.541546 ARP, Request who-has 10.0.10.171 tell 10.0.10.1, length 28\n13:54:03.541561 ARP, Request who-has 10.0.10.174 tell 10.0.10.1, length 28\n13:54:03.541581 ARP, Request who-has 10.0.10.175 tell 10.0.10.1, length 28\n13:54:03.541597 ARP, Request who-has 10.0.10.176 tell 10.0.10.1, length 28\n13:54:03.541613 ARP, Request who-has 10.0.10.177 tell 10.0.10.1, length 28\n13:54:03.541630 ARP, Request who-has 10.0.10.178 tell 10.0.10.1, length 28\n13:54:03.541645 ARP, Request who-has 10.0.10.179 tell 10.0.10.1, length 28\n13:54:03.541661 ARP, Request who-has 10.0.10.180 tell 10.0.10.1, length 28\n13:54:03.541676 ARP, Request who-has 10.0.10.181 tell 10.0.10.1, length 28\n13:54:03.541695 ARP, Request who-has 10.0.10.182 tell 10.0.10.1, length 28\n13:54:03.541711 ARP, Request who-has 10.0.10.183 tell 10.0.10.1, length 28\n13:54:03.541731 ARP, Request who-has 10.0.10.184 tell 10.0.10.1, length 28\n13:54:03.541750 ARP, Request who-has 10.0.10.185 tell 10.0.10.1, length 28\n13:54:03.541766 ARP, Request who-has 10.0.10.186 tell 10.0.10.1, length 28\n13:54:03.541782 ARP, Request who-has 10.0.10.187 tell 10.0.10.1, length 28\n13:54:03.541799 ARP, Request who-has 10.0.10.188 tell 10.0.10.1, length 28\n13:54:03.560932 ARP, Request who-has 10.0.10.218 tell 10.0.10.1, length 28\n13:54:03.560934 ARP, Request who-has 10.0.10.217 tell 10.0.10.1, length 28\n13:54:03.560934 ARP, Request who-has 10.0.10.214 tell 10.0.10.1, length 28\n13:54:03.560935 ARP, Request who-has 10.0.10.213 tell 10.0.10.1, length 28\n13:54:03.560936 ARP, Request who-has 10.0.10.210 tell 10.0.10.1, length 28\n13:54:03.560936 ARP, Request who-has 10.0.10.209 tell 10.0.10.1, length 28\n13:54:03.560937 ARP, Request who-has 10.0.10.206 tell 10.0.10.1, length 28\n13:54:03.560938 ARP, Request who-has 10.0.10.205 tell 10.0.10.1, length 28\n13:54:03.560938 ARP, Request who-has 10.0.10.202 tell 10.0.10.1, length 28\n13:54:03.560939 ARP, Request who-has 10.0.10.199 tell 10.0.10.1, length 28\n13:54:03.560940 ARP, Request who-has 10.0.10.196 tell 10.0.10.1, length 28\n13:54:03.560940 ARP, Request who-has 10.0.10.193 tell 10.0.10.1, length 28\n13:54:03.640866 ARP, Request who-has 10.0.10.244 tell 10.0.10.1, length 28\n13:54:03.640890 ARP, Request who-has 10.0.10.245 tell 10.0.10.1, length 28\n13:54:03.640910 ARP, Request who-has 10.0.10.246 tell 10.0.10.1, length 28\n13:54:03.641026 ARP, Request who-has 10.0.10.249 tell 10.0.10.1, length 28\n13:54:03.641043 ARP, Request who-has 10.0.10.250 tell 10.0.10.1, length 28\n13:54:03.641060 ARP, Request who-has 10.0.10.251 tell 10.0.10.1, length 28\n13:54:03.641077 ARP, Request who-has 10.0.10.252 tell 10.0.10.1, length 28\n13:54:03.641094 ARP, Request who-has 10.0.10.254 tell 10.0.10.1, length 28\n13:54:03.641285 ARP, Request who-has 10.0.10.12 tell 10.0.10.1, length 28\n13:54:03.641340 ARP, Request who-has 10.0.10.18 tell 10.0.10.1, length 28\n13:54:03.641357 ARP, Request who-has 10.0.10.19 tell 10.0.10.1, length 28\n13:54:03.641374 ARP, Request who-has 10.0.10.21 tell 10.0.10.1, length 28\n13:54:03.641391 ARP, Request who-has 10.0.10.22 tell 10.0.10.1, length 28\n13:54:03.641409 ARP, Request who-has 10.0.10.24 tell 10.0.10.1, length 28\n13:54:03.641426 ARP, Request who-has 10.0.10.25 tell 10.0.10.1, length 28\n13:54:03.641443 ARP, Request who-has 10.0.10.28 tell 10.0.10.1, length 28\n13:54:03.641467 ARP, Request who-has 10.0.10.29 tell 10.0.10.1, length 28\n13:54:03.641483 ARP, Request who-has 10.0.10.32 tell 10.0.10.1, length 28\n13:54:03.641701 ARP, Request who-has 10.0.10.36 tell 10.0.10.1, length 28\n13:54:03.641717 ARP, Request who-has 10.0.10.37 tell 10.0.10.1, length 28\n13:54:03.641734 ARP, Request who-has 10.0.10.38 tell 10.0.10.1, length 28\n13:54:03.641749 ARP, Request who-has 10.0.10.39 tell 10.0.10.1, length 28\n13:54:03.641764 ARP, Request who-has 10.0.10.40 tell 10.0.10.1, length 28\n13:54:03.641783 ARP, Request who-has 10.0.10.41 tell 10.0.10.1, length 28\n13:54:03.641799 ARP, Request who-has 10.0.10.42 tell 10.0.10.1, length 28\n13:54:03.641919 ARP, Request who-has 10.0.10.45 tell 10.0.10.1, length 28\n13:54:03.641936 ARP, Request who-has 10.0.10.46 tell 10.0.10.1, length 28\n13:54:03.641953 ARP, Request who-has 10.0.10.47 tell 10.0.10.1, length 28\n13:54:03.641969 ARP, Request who-has 10.0.10.48 tell 10.0.10.1, length 28\n13:54:03.641984 ARP, Request who-has 10.0.10.49 tell 10.0.10.1, length 28\n13:54:03.642000 ARP, Request who-has 10.0.10.50 tell 10.0.10.1, length 28\n13:54:03.642015 ARP, Request who-has 10.0.10.51 tell 10.0.10.1, length 28\n13:54:03.642030 ARP, Request who-has 10.0.10.52 tell 10.0.10.1, length 28\n13:54:03.642046 ARP, Request who-has 10.0.10.53 tell 10.0.10.1, length 28\n13:54:03.642062 ARP, Request who-has 10.0.10.54 tell 10.0.10.1, length 28\n13:54:03.642078 ARP, Request who-has 10.0.10.55 tell 10.0.10.1, length 28\n13:54:03.642094 ARP, Request who-has 10.0.10.56 tell 10.0.10.1, length 28\n13:54:03.642112 ARP, Request who-has 10.0.10.57 tell 10.0.10.1, length 28\n13:54:03.642128 ARP, Request who-has 10.0.10.58 tell 10.0.10.1, length 28\n13:54:03.642143 ARP, Request who-has 10.0.10.59 tell 10.0.10.1, length 28\n13:54:03.642159 ARP, Request who-has 10.0.10.61 tell 10.0.10.1, length 28\n13:54:03.642175 ARP, Request who-has 10.0.10.62 tell 10.0.10.1, length 28\n13:54:03.656893 ARP, Request who-has 10.0.10.35 tell 10.0.10.1, length 28\n13:54:03.656895 ARP, Request who-has 10.0.10.34 tell 10.0.10.1, length 28\n13:54:03.656895 ARP, Request who-has 10.0.10.31 tell 10.0.10.1, length 28\n13:54:03.656896 ARP, Request who-has 10.0.10.30 tell 10.0.10.1, length 28\n13:54:03.656897 ARP, Request who-has 10.0.10.27 tell 10.0.10.1, length 28\n13:54:03.656898 ARP, Request who-has 10.0.10.26 tell 10.0.10.1, length 28\n13:54:03.656898 ARP, Request who-has 10.0.10.23 tell 10.0.10.1, length 28\n13:54:03.656899 ARP, Request who-has 10.0.10.20 tell 10.0.10.1, length 28\n13:54:03.656899 ARP, Request who-has 10.0.10.17 tell 10.0.10.1, length 28\n13:54:03.656900 ARP, Request who-has 10.0.10.11 tell 10.0.10.1, length 28\n13:54:03.656901 ARP, Request who-has 10.0.10.0 tell 10.0.10.1, length 28\n13:54:03.656901 ARP, Request who-has 10.0.10.253 tell 10.0.10.1, length 28\n13:54:03.741047 ARP, Request who-has 10.0.10.189 tell 10.0.10.1, length 28\n13:54:03.741067 ARP, Request who-has 10.0.10.190 tell 10.0.10.1, length 28\n13:54:03.741163 ARP, Request who-has 10.0.10.195 tell 10.0.10.1, length 28\n13:54:03.741190 ARP, Request who-has 10.0.10.198 tell 10.0.10.1, length 28\n13:54:03.741441 ARP, Request who-has 10.0.10.204 tell 10.0.10.1, length 28\n13:54:03.741537 ARP, Request who-has 10.0.10.208 tell 10.0.10.1, length 28\n13:54:03.741572 ARP, Request who-has 10.0.10.212 tell 10.0.10.1, length 28\n13:54:03.741608 ARP, Request who-has 10.0.10.216 tell 10.0.10.1, length 28\n13:54:03.741717 ARP, Request who-has 10.0.10.220 tell 10.0.10.1, length 28\n13:54:03.741733 ARP, Request who-has 10.0.10.221 tell 10.0.10.1, length 28\n13:54:03.741761 ARP, Request who-has 10.0.10.223 tell 10.0.10.1, length 28\n13:54:03.741795 ARP, Request who-has 10.0.10.224 tell 10.0.10.1, length 28\n13:54:03.741810 ARP, Request who-has 10.0.10.226 tell 10.0.10.1, length 28\n13:54:03.741827 ARP, Request who-has 10.0.10.227 tell 10.0.10.1, length 28\n13:54:03.741843 ARP, Request who-has 10.0.10.230 tell 10.0.10.1, length 28\n13:54:03.741877 ARP, Request who-has 10.0.10.231 tell 10.0.10.1, length 28\n13:54:03.741895 ARP, Request who-has 10.0.10.247 tell 10.0.10.1, length 28\n13:54:03.742130 ARP, Request who-has 10.0.10.33 tell 10.0.10.1, length 28\n13:54:03.742162 ARP, Request who-has 10.0.10.43 tell 10.0.10.1, length 28\n13:54:03.742178 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:03.742313 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:03.752936 ARP, Request who-has 10.0.10.103 tell 10.0.10.1, length 28\n13:54:03.752938 ARP, Request who-has 10.0.10.102 tell 10.0.10.1, length 28\n13:54:03.752938 ARP, Request who-has 10.0.10.99 tell 10.0.10.1, length 28\n13:54:03.752939 ARP, Request who-has 10.0.10.98 tell 10.0.10.1, length 28\n13:54:03.752940 ARP, Request who-has 10.0.10.95 tell 10.0.10.1, length 28\n13:54:03.752940 ARP, Request who-has 10.0.10.94 tell 10.0.10.1, length 28\n13:54:03.752941 ARP, Request who-has 10.0.10.91 tell 10.0.10.1, length 28\n13:54:03.752942 ARP, Request who-has 10.0.10.88 tell 10.0.10.1, length 28\n13:54:03.752942 ARP, Request who-has 10.0.10.85 tell 10.0.10.1, length 28\n13:54:03.752943 ARP, Request who-has 10.0.10.81 tell 10.0.10.1, length 28\n13:54:03.752943 ARP, Request who-has 10.0.10.77 tell 10.0.10.1, length 28\n13:54:03.752944 ARP, Request who-has 10.0.10.71 tell 10.0.10.1, length 28\n13:54:03.841344 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:03.841437 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:03.841464 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:03.842322 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:03.848953 ARP, Request who-has 10.0.10.166 tell 10.0.10.1, length 28\n13:54:03.848954 ARP, Request who-has 10.0.10.165 tell 10.0.10.1, length 28\n13:54:03.848955 ARP, Request who-has 10.0.10.162 tell 10.0.10.1, length 28\n13:54:03.848956 ARP, Request who-has 10.0.10.159 tell 10.0.10.1, length 28\n13:54:03.848956 ARP, Request who-has 10.0.10.158 tell 10.0.10.1, length 28\n13:54:03.848957 ARP, Request who-has 10.0.10.155 tell 10.0.10.1, length 28\n13:54:03.848958 ARP, Request who-has 10.0.10.152 tell 10.0.10.1, length 28\n13:54:03.848958 ARP, Request who-has 10.0.10.147 tell 10.0.10.1, length 28\n13:54:03.848959 ARP, Request who-has 10.0.10.143 tell 10.0.10.1, length 28\n13:54:03.848960 ARP, Request who-has 10.0.10.139 tell 10.0.10.1, length 28\n13:54:03.848960 ARP, Request who-has 10.0.10.135 tell 10.0.10.1, length 28\n13:54:03.848961 ARP, Request who-has 10.0.10.132 tell 10.0.10.1, length 28\n13:54:03.941560 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:03.944939 ARP, Request who-has 10.0.10.229 tell 10.0.10.1, length 28\n13:54:03.944941 ARP, Request who-has 10.0.10.228 tell 10.0.10.1, length 28\n13:54:03.944942 ARP, Request who-has 10.0.10.225 tell 10.0.10.1, length 28\n13:54:03.944943 ARP, Request who-has 10.0.10.222 tell 10.0.10.1, length 28\n13:54:03.944943 ARP, Request who-has 10.0.10.219 tell 10.0.10.1, length 28\n13:54:03.944944 ARP, Request who-has 10.0.10.215 tell 10.0.10.1, length 28\n13:54:03.944945 ARP, Request who-has 10.0.10.211 tell 10.0.10.1, length 28\n13:54:03.944945 ARP, Request who-has 10.0.10.207 tell 10.0.10.1, length 28\n13:54:03.944946 ARP, Request who-has 10.0.10.200 tell 10.0.10.1, length 28\n13:54:03.944947 ARP, Request who-has 10.0.10.197 tell 10.0.10.1, length 28\n13:54:03.944947 ARP, Request who-has 10.0.10.194 tell 10.0.10.1, length 28\n13:54:03.944948 ARP, Request who-has 10.0.10.191 tell 10.0.10.1, length 28\n13:54:04.044932 ARP, Request who-has 10.0.10.243 tell 10.0.10.1, length 28\n13:54:04.044934 ARP, Request who-has 10.0.10.242 tell 10.0.10.1, length 28\n13:54:04.044934 ARP, Request who-has 10.0.10.241 tell 10.0.10.1, length 28\n13:54:04.044935 ARP, Request who-has 10.0.10.240 tell 10.0.10.1, length 28\n13:54:04.044935 ARP, Request who-has 10.0.10.239 tell 10.0.10.1, length 28\n13:54:04.044936 ARP, Request who-has 10.0.10.238 tell 10.0.10.1, length 28\n13:54:04.044937 ARP, Request who-has 10.0.10.237 tell 10.0.10.1, length 28\n13:54:04.044937 ARP, Request who-has 10.0.10.236 tell 10.0.10.1, length 28\n13:54:04.044938 ARP, Request who-has 10.0.10.235 tell 10.0.10.1, length 28\n13:54:04.044939 ARP, Request who-has 10.0.10.234 tell 10.0.10.1, length 28\n13:54:04.044939 ARP, Request who-has 10.0.10.233 tell 10.0.10.1, length 28\n13:54:04.044940 ARP, Request who-has 10.0.10.232 tell 10.0.10.1, length 28\n13:54:04.168927 ARP, Request who-has 10.0.10.93 tell 10.0.10.1, length 28\n13:54:04.168929 ARP, Request who-has 10.0.10.92 tell 10.0.10.1, length 28\n13:54:04.168930 ARP, Request who-has 10.0.10.89 tell 10.0.10.1, length 28\n13:54:04.168930 ARP, Request who-has 10.0.10.87 tell 10.0.10.1, length 28\n13:54:04.168931 ARP, Request who-has 10.0.10.86 tell 10.0.10.1, length 28\n13:54:04.168932 ARP, Request who-has 10.0.10.82 tell 10.0.10.1, length 28\n13:54:04.168932 ARP, Request who-has 10.0.10.78 tell 10.0.10.1, length 28\n13:54:04.168933 ARP, Request who-has 10.0.10.72 tell 10.0.10.1, length 28\n13:54:04.168934 ARP, Request who-has 10.0.10.66 tell 10.0.10.1, length 28\n13:54:04.168934 ARP, Request who-has 10.0.10.64 tell 10.0.10.1, length 28\n13:54:04.168935 ARP, Request who-has 10.0.10.63 tell 10.0.10.1, length 28\n13:54:04.168936 ARP, Request who-has 10.0.10.60 tell 10.0.10.1, length 28\n13:54:04.265000 ARP, Request who-has 10.0.10.3 tell 10.0.10.1, length 28\n13:54:04.265002 ARP, Request who-has 10.0.10.4 tell 10.0.10.1, length 28\n13:54:04.265002 ARP, Request who-has 10.0.10.5 tell 10.0.10.1, length 28\n13:54:04.265003 ARP, Request who-has 10.0.10.6 tell 10.0.10.1, length 28\n13:54:04.265004 ARP, Request who-has 10.0.10.7 tell 10.0.10.1, length 28\n13:54:04.265004 ARP, Request who-has 10.0.10.8 tell 10.0.10.1, length 28\n13:54:04.265005 ARP, Request who-has 10.0.10.9 tell 10.0.10.1, length 28\n13:54:04.265006 ARP, Request who-has 10.0.10.10 tell 10.0.10.1, length 28\n13:54:04.265006 ARP, Request who-has 10.0.10.13 tell 10.0.10.1, length 28\n13:54:04.265007 ARP, Request who-has 10.0.10.14 tell 10.0.10.1, length 28\n13:54:04.265007 ARP, Request who-has 10.0.10.15 tell 10.0.10.1, length 28\n13:54:04.265008 ARP, Request who-has 10.0.10.16 tell 10.0.10.1, length 28\n13:54:04.265009 ARP, Request who-has 10.0.10.173 tell 10.0.10.1, length 28\n13:54:04.265009 ARP, Request who-has 10.0.10.172 tell 10.0.10.1, length 28\n13:54:04.265010 ARP, Request who-has 10.0.10.169 tell 10.0.10.1, length 28\n13:54:04.265011 ARP, Request who-has 10.0.10.168 tell 10.0.10.1, length 28\n13:54:04.265011 ARP, Request who-has 10.0.10.167 tell 10.0.10.1, length 28\n13:54:04.265012 ARP, Request who-has 10.0.10.163 tell 10.0.10.1, length 28\n13:54:04.265013 ARP, Request who-has 10.0.10.161 tell 10.0.10.1, length 28\n13:54:04.265013 ARP, Request who-has 10.0.10.160 tell 10.0.10.1, length 28\n13:54:04.265014 ARP, Request who-has 10.0.10.157 tell 10.0.10.1, length 28\n13:54:04.265015 ARP, Request who-has 10.0.10.156 tell 10.0.10.1, length 28\n13:54:04.265015 ARP, Request who-has 10.0.10.153 tell 10.0.10.1, length 28\n13:54:04.265016 ARP, Request who-has 10.0.10.148 tell 10.0.10.1, length 28\n13:54:04.392915 ARP, Request who-has 10.0.10.65 tell 10.0.10.1, length 28\n13:54:04.392917 ARP, Request who-has 10.0.10.68 tell 10.0.10.1, length 28\n13:54:04.392918 ARP, Request who-has 10.0.10.69 tell 10.0.10.1, length 28\n13:54:04.392919 ARP, Request who-has 10.0.10.70 tell 10.0.10.1, length 28\n13:54:04.392919 ARP, Request who-has 10.0.10.73 tell 10.0.10.1, length 28\n13:54:04.392920 ARP, Request who-has 10.0.10.74 tell 10.0.10.1, length 28\n13:54:04.392921 ARP, Request who-has 10.0.10.75 tell 10.0.10.1, length 28\n13:54:04.392921 ARP, Request who-has 10.0.10.76 tell 10.0.10.1, length 28\n13:54:04.392922 ARP, Request who-has 10.0.10.79 tell 10.0.10.1, length 28\n13:54:04.392922 ARP, Request who-has 10.0.10.80 tell 10.0.10.1, length 28\n13:54:04.392923 ARP, Request who-has 10.0.10.83 tell 10.0.10.1, length 28\n13:54:04.392924 ARP, Request who-has 10.0.10.84 tell 10.0.10.1, length 28\n13:54:04.488924 ARP, Request who-has 10.0.10.131 tell 10.0.10.1, length 28\n13:54:04.488925 ARP, Request who-has 10.0.10.134 tell 10.0.10.1, length 28\n13:54:04.488926 ARP, Request who-has 10.0.10.137 tell 10.0.10.1, length 28\n13:54:04.488927 ARP, Request who-has 10.0.10.138 tell 10.0.10.1, length 28\n13:54:04.488927 ARP, Request who-has 10.0.10.141 tell 10.0.10.1, length 28\n13:54:04.488928 ARP, Request who-has 10.0.10.142 tell 10.0.10.1, length 28\n13:54:04.488929 ARP, Request who-has 10.0.10.145 tell 10.0.10.1, length 28\n13:54:04.488929 ARP, Request who-has 10.0.10.146 tell 10.0.10.1, length 28\n13:54:04.488930 ARP, Request who-has 10.0.10.149 tell 10.0.10.1, length 28\n13:54:04.488930 ARP, Request who-has 10.0.10.150 tell 10.0.10.1, length 28\n13:54:04.488931 ARP, Request who-has 10.0.10.151 tell 10.0.10.1, length 28\n13:54:04.488932 ARP, Request who-has 10.0.10.154 tell 10.0.10.1, length 28\n13:54:04.557150 ARP, Request who-has 10.0.10.188 tell 10.0.10.1, length 28\n13:54:04.557152 ARP, Request who-has 10.0.10.187 tell 10.0.10.1, length 28\n13:54:04.557153 ARP, Request who-has 10.0.10.186 tell 10.0.10.1, length 28\n13:54:04.557154 ARP, Request who-has 10.0.10.185 tell 10.0.10.1, length 28\n13:54:04.557154 ARP, Request who-has 10.0.10.184 tell 10.0.10.1, length 28\n13:54:04.557155 ARP, Request who-has 10.0.10.183 tell 10.0.10.1, length 28\n13:54:04.557156 ARP, Request who-has 10.0.10.182 tell 10.0.10.1, length 28\n13:54:04.557156 ARP, Request who-has 10.0.10.181 tell 10.0.10.1, length 28\n13:54:04.557157 ARP, Request who-has 10.0.10.180 tell 10.0.10.1, length 28\n13:54:04.557158 ARP, Request who-has 10.0.10.179 tell 10.0.10.1, length 28\n13:54:04.557158 ARP, Request who-has 10.0.10.178 tell 10.0.10.1, length 28\n13:54:04.557159 ARP, Request who-has 10.0.10.177 tell 10.0.10.1, length 28\n13:54:04.557160 ARP, Request who-has 10.0.10.176 tell 10.0.10.1, length 28\n13:54:04.557160 ARP, Request who-has 10.0.10.175 tell 10.0.10.1, length 28\n13:54:04.557161 ARP, Request who-has 10.0.10.174 tell 10.0.10.1, length 28\n13:54:04.557162 ARP, Request who-has 10.0.10.171 tell 10.0.10.1, length 28\n13:54:04.557162 ARP, Request who-has 10.0.10.170 tell 10.0.10.1, length 28\n13:54:04.557163 ARP, Request who-has 10.0.10.164 tell 10.0.10.1, length 28\n13:54:04.557164 ARP, Request who-has 10.0.10.144 tell 10.0.10.1, length 28\n13:54:04.557165 ARP, Request who-has 10.0.10.140 tell 10.0.10.1, length 28\n13:54:04.557165 ARP, Request who-has 10.0.10.136 tell 10.0.10.1, length 28\n13:54:04.557166 ARP, Request who-has 10.0.10.133 tell 10.0.10.1, length 28\n13:54:04.557167 ARP, Request who-has 10.0.10.130 tell 10.0.10.1, length 28\n13:54:04.557167 ARP, Request who-has 10.0.10.129 tell 10.0.10.1, length 28\n13:54:04.557168 ARP, Request who-has 10.0.10.128 tell 10.0.10.1, length 28\n13:54:04.557168 ARP, Request who-has 10.0.10.127 tell 10.0.10.1, length 28\n13:54:04.557169 ARP, Request who-has 10.0.10.126 tell 10.0.10.1, length 28\n13:54:04.557170 ARP, Request who-has 10.0.10.125 tell 10.0.10.1, length 28\n13:54:04.557170 ARP, Request who-has 10.0.10.124 tell 10.0.10.1, length 28\n13:54:04.557171 ARP, Request who-has 10.0.10.123 tell 10.0.10.1, length 28\n13:54:04.557172 ARP, Request who-has 10.0.10.122 tell 10.0.10.1, length 28\n13:54:04.557172 ARP, Request who-has 10.0.10.121 tell 10.0.10.1, length 28\n13:54:04.557173 ARP, Request who-has 10.0.10.120 tell 10.0.10.1, length 28\n13:54:04.557174 ARP, Request who-has 10.0.10.119 tell 10.0.10.1, length 28\n13:54:04.557174 ARP, Request who-has 10.0.10.118 tell 10.0.10.1, length 28\n13:54:04.557175 ARP, Request who-has 10.0.10.117 tell 10.0.10.1, length 28\n13:54:04.557175 ARP, Request who-has 10.0.10.116 tell 10.0.10.1, length 28\n13:54:04.557176 ARP, Request who-has 10.0.10.115 tell 10.0.10.1, length 28\n13:54:04.557177 ARP, Request who-has 10.0.10.114 tell 10.0.10.1, length 28\n13:54:04.557178 ARP, Request who-has 10.0.10.113 tell 10.0.10.1, length 28\n13:54:04.557178 ARP, Request who-has 10.0.10.112 tell 10.0.10.1, length 28\n13:54:04.557179 ARP, Request who-has 10.0.10.111 tell 10.0.10.1, length 28\n13:54:04.557180 ARP, Request who-has 10.0.10.110 tell 10.0.10.1, length 28\n13:54:04.557180 ARP, Request who-has 10.0.10.109 tell 10.0.10.1, length 28\n13:54:04.557181 ARP, Request who-has 10.0.10.108 tell 10.0.10.1, length 28\n13:54:04.557182 ARP, Request who-has 10.0.10.107 tell 10.0.10.1, length 28\n13:54:04.557182 ARP, Request who-has 10.0.10.106 tell 10.0.10.1, length 28\n13:54:04.557183 ARP, Request who-has 10.0.10.105 tell 10.0.10.1, length 28\n13:54:04.557184 ARP, Request who-has 10.0.10.104 tell 10.0.10.1, length 28\n13:54:04.557184 ARP, Request who-has 10.0.10.101 tell 10.0.10.1, length 28\n13:54:04.557185 ARP, Request who-has 10.0.10.100 tell 10.0.10.1, length 28\n13:54:04.557185 ARP, Request who-has 10.0.10.97 tell 10.0.10.1, length 28\n13:54:04.557186 ARP, Request who-has 10.0.10.96 tell 10.0.10.1, length 28\n13:54:04.588884 ARP, Request who-has 10.0.10.193 tell 10.0.10.1, length 28\n13:54:04.588885 ARP, Request who-has 10.0.10.196 tell 10.0.10.1, length 28\n13:54:04.588886 ARP, Request who-has 10.0.10.199 tell 10.0.10.1, length 28\n13:54:04.588887 ARP, Request who-has 10.0.10.202 tell 10.0.10.1, length 28\n13:54:04.588887 ARP, Request who-has 10.0.10.205 tell 10.0.10.1, length 28\n13:54:04.588888 ARP, Request who-has 10.0.10.206 tell 10.0.10.1, length 28\n13:54:04.588889 ARP, Request who-has 10.0.10.209 tell 10.0.10.1, length 28\n13:54:04.588889 ARP, Request who-has 10.0.10.210 tell 10.0.10.1, length 28\n13:54:04.588890 ARP, Request who-has 10.0.10.213 tell 10.0.10.1, length 28\n13:54:04.588890 ARP, Request who-has 10.0.10.214 tell 10.0.10.1, length 28\n13:54:04.588891 ARP, Request who-has 10.0.10.217 tell 10.0.10.1, length 28\n13:54:04.588892 ARP, Request who-has 10.0.10.218 tell 10.0.10.1, length 28\n13:54:04.649103 ARP, Request who-has 10.0.10.62 tell 10.0.10.1, length 28\n13:54:04.649105 ARP, Request who-has 10.0.10.61 tell 10.0.10.1, length 28\n13:54:04.649105 ARP, Request who-has 10.0.10.59 tell 10.0.10.1, length 28\n13:54:04.649106 ARP, Request who-has 10.0.10.58 tell 10.0.10.1, length 28\n13:54:04.649107 ARP, Request who-has 10.0.10.57 tell 10.0.10.1, length 28\n13:54:04.649107 ARP, Request who-has 10.0.10.56 tell 10.0.10.1, length 28\n13:54:04.649108 ARP, Request who-has 10.0.10.55 tell 10.0.10.1, length 28\n13:54:04.649109 ARP, Request who-has 10.0.10.54 tell 10.0.10.1, length 28\n13:54:04.649109 ARP, Request who-has 10.0.10.53 tell 10.0.10.1, length 28\n13:54:04.649110 ARP, Request who-has 10.0.10.52 tell 10.0.10.1, length 28\n13:54:04.649111 ARP, Request who-has 10.0.10.51 tell 10.0.10.1, length 28\n13:54:04.649111 ARP, Request who-has 10.0.10.50 tell 10.0.10.1, length 28\n13:54:04.649112 ARP, Request who-has 10.0.10.49 tell 10.0.10.1, length 28\n13:54:04.649113 ARP, Request who-has 10.0.10.48 tell 10.0.10.1, length 28\n13:54:04.649113 ARP, Request who-has 10.0.10.47 tell 10.0.10.1, length 28\n13:54:04.649114 ARP, Request who-has 10.0.10.46 tell 10.0.10.1, length 28\n13:54:04.649114 ARP, Request who-has 10.0.10.45 tell 10.0.10.1, length 28\n13:54:04.649115 ARP, Request who-has 10.0.10.42 tell 10.0.10.1, length 28\n13:54:04.649116 ARP, Request who-has 10.0.10.41 tell 10.0.10.1, length 28\n13:54:04.649117 ARP, Request who-has 10.0.10.40 tell 10.0.10.1, length 28\n13:54:04.649117 ARP, Request who-has 10.0.10.39 tell 10.0.10.1, length 28\n13:54:04.649118 ARP, Request who-has 10.0.10.38 tell 10.0.10.1, length 28\n13:54:04.649119 ARP, Request who-has 10.0.10.37 tell 10.0.10.1, length 28\n13:54:04.649119 ARP, Request who-has 10.0.10.36 tell 10.0.10.1, length 28\n13:54:04.649120 ARP, Request who-has 10.0.10.32 tell 10.0.10.1, length 28\n13:54:04.649121 ARP, Request who-has 10.0.10.29 tell 10.0.10.1, length 28\n13:54:04.649121 ARP, Request who-has 10.0.10.28 tell 10.0.10.1, length 28\n13:54:04.649122 ARP, Request who-has 10.0.10.25 tell 10.0.10.1, length 28\n13:54:04.649123 ARP, Request who-has 10.0.10.24 tell 10.0.10.1, length 28\n13:54:04.649123 ARP, Request who-has 10.0.10.22 tell 10.0.10.1, length 28\n13:54:04.649124 ARP, Request who-has 10.0.10.21 tell 10.0.10.1, length 28\n13:54:04.649125 ARP, Request who-has 10.0.10.19 tell 10.0.10.1, length 28\n13:54:04.649125 ARP, Request who-has 10.0.10.18 tell 10.0.10.1, length 28\n13:54:04.649126 ARP, Request who-has 10.0.10.12 tell 10.0.10.1, length 28\n13:54:04.649127 ARP, Request who-has 10.0.10.254 tell 10.0.10.1, length 28\n13:54:04.649127 ARP, Request who-has 10.0.10.252 tell 10.0.10.1, length 28\n13:54:04.649128 ARP, Request who-has 10.0.10.251 tell 10.0.10.1, length 28\n13:54:04.649129 ARP, Request who-has 10.0.10.250 tell 10.0.10.1, length 28\n13:54:04.649129 ARP, Request who-has 10.0.10.249 tell 10.0.10.1, length 28\n13:54:04.649130 ARP, Request who-has 10.0.10.246 tell 10.0.10.1, length 28\n13:54:04.649131 ARP, Request who-has 10.0.10.245 tell 10.0.10.1, length 28\n13:54:04.649131 ARP, Request who-has 10.0.10.244 tell 10.0.10.1, length 28\n13:54:04.680926 ARP, Request who-has 10.0.10.253 tell 10.0.10.1, length 28\n13:54:04.680928 ARP, Request who-has 10.0.10.0 tell 10.0.10.1, length 28\n13:54:04.680928 ARP, Request who-has 10.0.10.11 tell 10.0.10.1, length 28\n13:54:04.680929 ARP, Request who-has 10.0.10.17 tell 10.0.10.1, length 28\n13:54:04.680930 ARP, Request who-has 10.0.10.20 tell 10.0.10.1, length 28\n13:54:04.680930 ARP, Request who-has 10.0.10.23 tell 10.0.10.1, length 28\n13:54:04.680931 ARP, Request who-has 10.0.10.26 tell 10.0.10.1, length 28\n13:54:04.680932 ARP, Request who-has 10.0.10.27 tell 10.0.10.1, length 28\n13:54:04.680932 ARP, Request who-has 10.0.10.30 tell 10.0.10.1, length 28\n13:54:04.680933 ARP, Request who-has 10.0.10.31 tell 10.0.10.1, length 28\n13:54:04.680934 ARP, Request who-has 10.0.10.34 tell 10.0.10.1, length 28\n13:54:04.680934 ARP, Request who-has 10.0.10.35 tell 10.0.10.1, length 28\n13:54:04.744975 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:04.744977 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:04.744978 ARP, Request who-has 10.0.10.43 tell 10.0.10.1, length 28\n13:54:04.744978 ARP, Request who-has 10.0.10.33 tell 10.0.10.1, length 28\n13:54:04.744979 ARP, Request who-has 10.0.10.247 tell 10.0.10.1, length 28\n13:54:04.744980 ARP, Request who-has 10.0.10.231 tell 10.0.10.1, length 28\n13:54:04.744981 ARP, Request who-has 10.0.10.230 tell 10.0.10.1, length 28\n13:54:04.744981 ARP, Request who-has 10.0.10.227 tell 10.0.10.1, length 28\n13:54:04.744982 ARP, Request who-has 10.0.10.226 tell 10.0.10.1, length 28\n13:54:04.744982 ARP, Request who-has 10.0.10.224 tell 10.0.10.1, length 28\n13:54:04.744983 ARP, Request who-has 10.0.10.223 tell 10.0.10.1, length 28\n13:54:04.744984 ARP, Request who-has 10.0.10.221 tell 10.0.10.1, length 28\n13:54:04.744984 ARP, Request who-has 10.0.10.220 tell 10.0.10.1, length 28\n13:54:04.744985 ARP, Request who-has 10.0.10.216 tell 10.0.10.1, length 28\n13:54:04.744986 ARP, Request who-has 10.0.10.212 tell 10.0.10.1, length 28\n13:54:04.744986 ARP, Request who-has 10.0.10.208 tell 10.0.10.1, length 28\n13:54:04.744987 ARP, Request who-has 10.0.10.204 tell 10.0.10.1, length 28\n13:54:04.744988 ARP, Request who-has 10.0.10.198 tell 10.0.10.1, length 28\n13:54:04.744988 ARP, Request who-has 10.0.10.195 tell 10.0.10.1, length 28\n13:54:04.744989 ARP, Request who-has 10.0.10.190 tell 10.0.10.1, length 28\n13:54:04.744989 ARP, Request who-has 10.0.10.189 tell 10.0.10.1, length 28\n13:54:04.776896 ARP, Request who-has 10.0.10.71 tell 10.0.10.1, length 28\n13:54:04.776898 ARP, Request who-has 10.0.10.77 tell 10.0.10.1, length 28\n13:54:04.776898 ARP, Request who-has 10.0.10.81 tell 10.0.10.1, length 28\n13:54:04.776899 ARP, Request who-has 10.0.10.85 tell 10.0.10.1, length 28\n13:54:04.776900 ARP, Request who-has 10.0.10.88 tell 10.0.10.1, length 28\n13:54:04.776900 ARP, Request who-has 10.0.10.91 tell 10.0.10.1, length 28\n13:54:04.776901 ARP, Request who-has 10.0.10.94 tell 10.0.10.1, length 28\n13:54:04.776902 ARP, Request who-has 10.0.10.95 tell 10.0.10.1, length 28\n13:54:04.776902 ARP, Request who-has 10.0.10.98 tell 10.0.10.1, length 28\n13:54:04.776903 ARP, Request who-has 10.0.10.99 tell 10.0.10.1, length 28\n13:54:04.776903 ARP, Request who-has 10.0.10.102 tell 10.0.10.1, length 28\n13:54:04.776904 ARP, Request who-has 10.0.10.103 tell 10.0.10.1, length 28\n13:54:04.872958 ARP, Request who-has 10.0.10.132 tell 10.0.10.1, length 28\n13:54:04.872959 ARP, Request who-has 10.0.10.135 tell 10.0.10.1, length 28\n13:54:04.872960 ARP, Request who-has 10.0.10.139 tell 10.0.10.1, length 28\n13:54:04.872961 ARP, Request who-has 10.0.10.143 tell 10.0.10.1, length 28\n13:54:04.872961 ARP, Request who-has 10.0.10.147 tell 10.0.10.1, length 28\n13:54:04.872962 ARP, Request who-has 10.0.10.152 tell 10.0.10.1, length 28\n13:54:04.872963 ARP, Request who-has 10.0.10.155 tell 10.0.10.1, length 28\n13:54:04.872963 ARP, Request who-has 10.0.10.158 tell 10.0.10.1, length 28\n13:54:04.872964 ARP, Request who-has 10.0.10.159 tell 10.0.10.1, length 28\n13:54:04.872965 ARP, Request who-has 10.0.10.162 tell 10.0.10.1, length 28\n13:54:04.872965 ARP, Request who-has 10.0.10.165 tell 10.0.10.1, length 28\n13:54:04.872966 ARP, Request who-has 10.0.10.166 tell 10.0.10.1, length 28\n13:54:04.872967 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:04.872967 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:04.872968 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:04.872969 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:04.940875 IP 10.0.10.1.57006 > 10.0.10.2.http: Flags [S], seq 2246678905, win 64240, options [mss 1460,sackOK,TS val 3851874680 ecr 0,nop,wscale 7], length 0\n13:54:04.940882 IP 10.0.10.2.http > 10.0.10.1.57006: Flags [R.], seq 0, ack 2246678906, win 0, length 0\n13:54:04.968925 ARP, Request who-has 10.0.10.191 tell 10.0.10.1, length 28\n13:54:04.968927 ARP, Request who-has 10.0.10.194 tell 10.0.10.1, length 28\n13:54:04.968927 ARP, Request who-has 10.0.10.197 tell 10.0.10.1, length 28\n13:54:04.968928 ARP, Request who-has 10.0.10.200 tell 10.0.10.1, length 28\n13:54:04.968929 ARP, Request who-has 10.0.10.207 tell 10.0.10.1, length 28\n13:54:04.968929 ARP, Request who-has 10.0.10.211 tell 10.0.10.1, length 28\n13:54:04.968930 ARP, Request who-has 10.0.10.215 tell 10.0.10.1, length 28\n13:54:04.968930 ARP, Request who-has 10.0.10.219 tell 10.0.10.1, length 28\n13:54:04.968931 ARP, Request who-has 10.0.10.222 tell 10.0.10.1, length 28\n13:54:04.968932 ARP, Request who-has 10.0.10.225 tell 10.0.10.1, length 28\n13:54:04.968932 ARP, Request who-has 10.0.10.228 tell 10.0.10.1, length 28\n13:54:04.968933 ARP, Request who-has 10.0.10.229 tell 10.0.10.1, length 28\n13:54:04.968934 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:05.064931 ARP, Request who-has 10.0.10.232 tell 10.0.10.1, length 28\n13:54:05.064933 ARP, Request who-has 10.0.10.233 tell 10.0.10.1, length 28\n13:54:05.064934 ARP, Request who-has 10.0.10.234 tell 10.0.10.1, length 28\n13:54:05.064934 ARP, Request who-has 10.0.10.235 tell 10.0.10.1, length 28\n13:54:05.064935 ARP, Request who-has 10.0.10.236 tell 10.0.10.1, length 28\n13:54:05.064936 ARP, Request who-has 10.0.10.237 tell 10.0.10.1, length 28\n13:54:05.064936 ARP, Request who-has 10.0.10.238 tell 10.0.10.1, length 28\n13:54:05.064937 ARP, Request who-has 10.0.10.239 tell 10.0.10.1, length 28\n13:54:05.064938 ARP, Request who-has 10.0.10.240 tell 10.0.10.1, length 28\n13:54:05.064938 ARP, Request who-has 10.0.10.241 tell 10.0.10.1, length 28\n13:54:05.064939 ARP, Request who-has 10.0.10.242 tell 10.0.10.1, length 28\n13:54:05.064939 ARP, Request who-has 10.0.10.243 tell 10.0.10.1, length 28\n13:54:05.192927 ARP, Request who-has 10.0.10.60 tell 10.0.10.1, length 28\n13:54:05.192929 ARP, Request who-has 10.0.10.63 tell 10.0.10.1, length 28\n13:54:05.192929 ARP, Request who-has 10.0.10.64 tell 10.0.10.1, length 28\n13:54:05.192930 ARP, Request who-has 10.0.10.66 tell 10.0.10.1, length 28\n13:54:05.192931 ARP, Request who-has 10.0.10.72 tell 10.0.10.1, length 28\n13:54:05.192932 ARP, Request who-has 10.0.10.78 tell 10.0.10.1, length 28\n13:54:05.192932 ARP, Request who-has 10.0.10.82 tell 10.0.10.1, length 28\n13:54:05.192933 ARP, Request who-has 10.0.10.86 tell 10.0.10.1, length 28\n13:54:05.192933 ARP, Request who-has 10.0.10.87 tell 10.0.10.1, length 28\n13:54:05.192934 ARP, Request who-has 10.0.10.89 tell 10.0.10.1, length 28\n13:54:05.192935 ARP, Request who-has 10.0.10.92 tell 10.0.10.1, length 28\n13:54:05.192935 ARP, Request who-has 10.0.10.93 tell 10.0.10.1, length 28\n13:54:05.289141 ARP, Request who-has 10.0.10.148 tell 10.0.10.1, length 28\n13:54:05.289143 ARP, Request who-has 10.0.10.153 tell 10.0.10.1, length 28\n13:54:05.289143 ARP, Request who-has 10.0.10.156 tell 10.0.10.1, length 28\n13:54:05.289144 ARP, Request who-has 10.0.10.157 tell 10.0.10.1, length 28\n13:54:05.289145 ARP, Request who-has 10.0.10.160 tell 10.0.10.1, length 28\n13:54:05.289145 ARP, Request who-has 10.0.10.161 tell 10.0.10.1, length 28\n13:54:05.289146 ARP, Request who-has 10.0.10.163 tell 10.0.10.1, length 28\n13:54:05.289147 ARP, Request who-has 10.0.10.167 tell 10.0.10.1, length 28\n13:54:05.289147 ARP, Request who-has 10.0.10.168 tell 10.0.10.1, length 28\n13:54:05.289148 ARP, Request who-has 10.0.10.169 tell 10.0.10.1, length 28\n13:54:05.289149 ARP, Request who-has 10.0.10.172 tell 10.0.10.1, length 28\n13:54:05.289149 ARP, Request who-has 10.0.10.173 tell 10.0.10.1, length 28\n13:54:05.577198 ARP, Request who-has 10.0.10.96 tell 10.0.10.1, length 28\n13:54:05.577202 ARP, Request who-has 10.0.10.97 tell 10.0.10.1, length 28\n13:54:05.577203 ARP, Request who-has 10.0.10.100 tell 10.0.10.1, length 28\n13:54:05.577203 ARP, Request who-has 10.0.10.101 tell 10.0.10.1, length 28\n13:54:05.577204 ARP, Request who-has 10.0.10.104 tell 10.0.10.1, length 28\n13:54:05.577205 ARP, Request who-has 10.0.10.105 tell 10.0.10.1, length 28\n13:54:05.577205 ARP, Request who-has 10.0.10.106 tell 10.0.10.1, length 28\n13:54:05.577206 ARP, Request who-has 10.0.10.107 tell 10.0.10.1, length 28\n13:54:05.577207 ARP, Request who-has 10.0.10.108 tell 10.0.10.1, length 28\n13:54:05.577207 ARP, Request who-has 10.0.10.109 tell 10.0.10.1, length 28\n13:54:05.577208 ARP, Request who-has 10.0.10.110 tell 10.0.10.1, length 28\n13:54:05.577209 ARP, Request who-has 10.0.10.111 tell 10.0.10.1, length 28\n13:54:05.577209 ARP, Request who-has 10.0.10.112 tell 10.0.10.1, length 28\n13:54:05.577210 ARP, Request who-has 10.0.10.113 tell 10.0.10.1, length 28\n13:54:05.577210 ARP, Request who-has 10.0.10.114 tell 10.0.10.1, length 28\n13:54:05.577211 ARP, Request who-has 10.0.10.115 tell 10.0.10.1, length 28\n13:54:05.577212 ARP, Request who-has 10.0.10.116 tell 10.0.10.1, length 28\n13:54:05.577212 ARP, Request who-has 10.0.10.117 tell 10.0.10.1, length 28\n13:54:05.577213 ARP, Request who-has 10.0.10.118 tell 10.0.10.1, length 28\n13:54:05.577214 ARP, Request who-has 10.0.10.119 tell 10.0.10.1, length 28\n13:54:05.577215 ARP, Request who-has 10.0.10.120 tell 10.0.10.1, length 28\n13:54:05.577216 ARP, Request who-has 10.0.10.121 tell 10.0.10.1, length 28\n13:54:05.577216 ARP, Request who-has 10.0.10.122 tell 10.0.10.1, length 28\n13:54:05.577217 ARP, Request who-has 10.0.10.123 tell 10.0.10.1, length 28\n13:54:05.577218 ARP, Request who-has 10.0.10.124 tell 10.0.10.1, length 28\n13:54:05.577218 ARP, Request who-has 10.0.10.125 tell 10.0.10.1, length 28\n13:54:05.577219 ARP, Request who-has 10.0.10.126 tell 10.0.10.1, length 28\n13:54:05.577220 ARP, Request who-has 10.0.10.127 tell 10.0.10.1, length 28\n13:54:05.577220 ARP, Request who-has 10.0.10.128 tell 10.0.10.1, length 28\n13:54:05.577221 ARP, Request who-has 10.0.10.129 tell 10.0.10.1, length 28\n13:54:05.577222 ARP, Request who-has 10.0.10.130 tell 10.0.10.1, length 28\n13:54:05.577222 ARP, Request who-has 10.0.10.133 tell 10.0.10.1, length 28\n13:54:05.577223 ARP, Request who-has 10.0.10.136 tell 10.0.10.1, length 28\n13:54:05.577224 ARP, Request who-has 10.0.10.140 tell 10.0.10.1, length 28\n13:54:05.577224 ARP, Request who-has 10.0.10.144 tell 10.0.10.1, length 28\n13:54:05.577225 ARP, Request who-has 10.0.10.164 tell 10.0.10.1, length 28\n13:54:05.577226 ARP, Request who-has 10.0.10.170 tell 10.0.10.1, length 28\n13:54:05.577226 ARP, Request who-has 10.0.10.171 tell 10.0.10.1, length 28\n13:54:05.577227 ARP, Request who-has 10.0.10.174 tell 10.0.10.1, length 28\n13:54:05.577228 ARP, Request who-has 10.0.10.175 tell 10.0.10.1, length 28\n13:54:05.577229 ARP, Request who-has 10.0.10.176 tell 10.0.10.1, length 28\n13:54:05.577229 ARP, Request who-has 10.0.10.177 tell 10.0.10.1, length 28\n13:54:05.577230 ARP, Request who-has 10.0.10.178 tell 10.0.10.1, length 28\n13:54:05.577231 ARP, Request who-has 10.0.10.179 tell 10.0.10.1, length 28\n13:54:05.577231 ARP, Request who-has 10.0.10.180 tell 10.0.10.1, length 28\n13:54:05.577232 ARP, Request who-has 10.0.10.181 tell 10.0.10.1, length 28\n13:54:05.577233 ARP, Request who-has 10.0.10.182 tell 10.0.10.1, length 28\n13:54:05.577233 ARP, Request who-has 10.0.10.183 tell 10.0.10.1, length 28\n13:54:05.577234 ARP, Request who-has 10.0.10.184 tell 10.0.10.1, length 28\n13:54:05.577234 ARP, Request who-has 10.0.10.185 tell 10.0.10.1, length 28\n13:54:05.577235 ARP, Request who-has 10.0.10.186 tell 10.0.10.1, length 28\n13:54:05.577236 ARP, Request who-has 10.0.10.187 tell 10.0.10.1, length 28\n13:54:05.577236 ARP, Request who-has 10.0.10.188 tell 10.0.10.1, length 28\n13:54:05.673096 ARP, Request who-has 10.0.10.244 tell 10.0.10.1, length 28\n13:54:05.673099 ARP, Request who-has 10.0.10.245 tell 10.0.10.1, length 28\n13:54:05.673100 ARP, Request who-has 10.0.10.246 tell 10.0.10.1, length 28\n13:54:05.673101 ARP, Request who-has 10.0.10.249 tell 10.0.10.1, length 28\n13:54:05.673101 ARP, Request who-has 10.0.10.250 tell 10.0.10.1, length 28\n13:54:05.673102 ARP, Request who-has 10.0.10.251 tell 10.0.10.1, length 28\n13:54:05.673103 ARP, Request who-has 10.0.10.252 tell 10.0.10.1, length 28\n13:54:05.673103 ARP, Request who-has 10.0.10.254 tell 10.0.10.1, length 28\n13:54:05.673104 ARP, Request who-has 10.0.10.12 tell 10.0.10.1, length 28\n13:54:05.673105 ARP, Request who-has 10.0.10.18 tell 10.0.10.1, length 28\n13:54:05.673105 ARP, Request who-has 10.0.10.19 tell 10.0.10.1, length 28\n13:54:05.673106 ARP, Request who-has 10.0.10.21 tell 10.0.10.1, length 28\n13:54:05.673107 ARP, Request who-has 10.0.10.22 tell 10.0.10.1, length 28\n13:54:05.673107 ARP, Request who-has 10.0.10.24 tell 10.0.10.1, length 28\n13:54:05.673108 ARP, Request who-has 10.0.10.25 tell 10.0.10.1, length 28\n13:54:05.673108 ARP, Request who-has 10.0.10.28 tell 10.0.10.1, length 28\n13:54:05.673109 ARP, Request who-has 10.0.10.29 tell 10.0.10.1, length 28\n13:54:05.673110 ARP, Request who-has 10.0.10.32 tell 10.0.10.1, length 28\n13:54:05.673110 ARP, Request who-has 10.0.10.36 tell 10.0.10.1, length 28\n13:54:05.673111 ARP, Request who-has 10.0.10.37 tell 10.0.10.1, length 28\n13:54:05.673112 ARP, Request who-has 10.0.10.38 tell 10.0.10.1, length 28\n13:54:05.673113 ARP, Request who-has 10.0.10.39 tell 10.0.10.1, length 28\n13:54:05.673113 ARP, Request who-has 10.0.10.40 tell 10.0.10.1, length 28\n13:54:05.673114 ARP, Request who-has 10.0.10.41 tell 10.0.10.1, length 28\n13:54:05.673115 ARP, Request who-has 10.0.10.42 tell 10.0.10.1, length 28\n13:54:05.673115 ARP, Request who-has 10.0.10.45 tell 10.0.10.1, length 28\n13:54:05.673116 ARP, Request who-has 10.0.10.46 tell 10.0.10.1, length 28\n13:54:05.673116 ARP, Request who-has 10.0.10.47 tell 10.0.10.1, length 28\n13:54:05.673117 ARP, Request who-has 10.0.10.48 tell 10.0.10.1, length 28\n13:54:05.673118 ARP, Request who-has 10.0.10.49 tell 10.0.10.1, length 28\n13:54:05.673118 ARP, Request who-has 10.0.10.50 tell 10.0.10.1, length 28\n13:54:05.673119 ARP, Request who-has 10.0.10.51 tell 10.0.10.1, length 28\n13:54:05.673120 ARP, Request who-has 10.0.10.52 tell 10.0.10.1, length 28\n13:54:05.673120 ARP, Request who-has 10.0.10.53 tell 10.0.10.1, length 28\n13:54:05.673121 ARP, Request who-has 10.0.10.54 tell 10.0.10.1, length 28\n13:54:05.673121 ARP, Request who-has 10.0.10.55 tell 10.0.10.1, length 28\n13:54:05.673122 ARP, Request who-has 10.0.10.56 tell 10.0.10.1, length 28\n13:54:05.673123 ARP, Request who-has 10.0.10.57 tell 10.0.10.1, length 28\n13:54:05.673123 ARP, Request who-has 10.0.10.58 tell 10.0.10.1, length 28\n13:54:05.673124 ARP, Request who-has 10.0.10.59 tell 10.0.10.1, length 28\n13:54:05.673125 ARP, Request who-has 10.0.10.61 tell 10.0.10.1, length 28\n13:54:05.673125 ARP, Request who-has 10.0.10.62 tell 10.0.10.1, length 28\n13:54:05.768982 ARP, Request who-has 10.0.10.189 tell 10.0.10.1, length 28\n13:54:05.768985 ARP, Request who-has 10.0.10.190 tell 10.0.10.1, length 28\n13:54:05.768986 ARP, Request who-has 10.0.10.195 tell 10.0.10.1, length 28\n13:54:05.768986 ARP, Request who-has 10.0.10.198 tell 10.0.10.1, length 28\n13:54:05.768987 ARP, Request who-has 10.0.10.204 tell 10.0.10.1, length 28\n13:54:05.768988 ARP, Request who-has 10.0.10.208 tell 10.0.10.1, length 28\n13:54:05.768988 ARP, Request who-has 10.0.10.212 tell 10.0.10.1, length 28\n13:54:05.768989 ARP, Request who-has 10.0.10.216 tell 10.0.10.1, length 28\n13:54:05.768990 ARP, Request who-has 10.0.10.220 tell 10.0.10.1, length 28\n13:54:05.768990 ARP, Request who-has 10.0.10.221 tell 10.0.10.1, length 28\n13:54:05.768991 ARP, Request who-has 10.0.10.223 tell 10.0.10.1, length 28\n13:54:05.768991 ARP, Request who-has 10.0.10.224 tell 10.0.10.1, length 28\n13:54:05.768992 ARP, Request who-has 10.0.10.226 tell 10.0.10.1, length 28\n13:54:05.768993 ARP, Request who-has 10.0.10.227 tell 10.0.10.1, length 28\n13:54:05.768993 ARP, Request who-has 10.0.10.230 tell 10.0.10.1, length 28\n13:54:05.768994 ARP, Request who-has 10.0.10.231 tell 10.0.10.1, length 28\n13:54:05.768995 ARP, Request who-has 10.0.10.247 tell 10.0.10.1, length 28\n13:54:05.768995 ARP, Request who-has 10.0.10.33 tell 10.0.10.1, length 28\n13:54:05.768996 ARP, Request who-has 10.0.10.43 tell 10.0.10.1, length 28\n13:54:05.768997 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:05.768997 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:05.897167 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:05.897170 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:05.993145 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:07.432845 ARP, Request who-has 10.0.10.1 tell 10.0.10.2, length 28\n13:54:07.432890 ARP, Request who-has 10.0.10.2 tell 10.0.10.1, length 28\n13:54:07.432893 ARP, Reply 10.0.10.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n13:54:07.432898 ARP, Reply 10.0.10.1 is-at 00:50:56:94:55:70 (oui Unknown), length 28\n

    This generated a lot of broadcast traffic! For practice, see if you can find the ARP request and response packets for host1 and host2 in the packet capture output. We can tell that they were properly discovered in the output from host1.

    Now check the output on host4, which should pick up the above packets if it was still on the same broadcasting domain:

    eron@host4:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n

    Still nothing? Awesome, there should be no packets yet if everything has been set up right.

    Now we're going to perform a quick scan of the other subnet and examine the results. Starting on host3, run the following:

    nmap -sn 10.0.10.0/24\n

    When nmap is finished, cancel the packet capture on host4, and then check the output on both host3 and host4:

    eron@host3:~$ nmap -sn 10.0.20.0/24\nStarting Nmap 7.80 ( https://nmap.org ) at 2023-06-27 13:54 UTC\nNmap scan report for 10.0.20.3\nHost is up (0.00052s latency).\nNmap scan report for 10.0.20.4\nHost is up (0.00040s latency).\nNmap done: 256 IP addresses (2 hosts up) scanned in 15.91 seconds\n
    eron@host4:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n13:54:49.924495 ARP, Request who-has 10.0.20.1 tell 10.0.20.3, length 28\n13:54:49.924534 ARP, Request who-has 10.0.20.2 tell 10.0.20.3, length 28\n13:54:49.924579 ARP, Request who-has 10.0.20.4 tell 10.0.20.3, length 28\n13:54:49.924593 ARP, Reply 10.0.20.4 is-at 00:50:56:ad:24:4a (oui Unknown), length 28\n13:54:49.924613 IP 10.0.20.3.57422 > 10.0.20.4.http: Flags [S], seq 2960543896, win 64240, options [mss 1460,sackOK,TS val 230221782 ecr 0,nop,wscale 7], length 0\n13:54:49.924619 IP 10.0.20.4.http > 10.0.20.3.57422: Flags [R.], seq 0, ack 2960543897, win 0, length 0\n13:54:49.924956 ARP, Request who-has 10.0.20.5 tell 10.0.20.3, length 28\n13:54:49.924977 ARP, Request who-has 10.0.20.6 tell 10.0.20.3, length 28\n13:54:49.924995 ARP, Request who-has 10.0.20.7 tell 10.0.20.3, length 28\n13:54:49.925013 ARP, Request who-has 10.0.20.8 tell 10.0.20.3, length 28\n13:54:49.925030 ARP, Request who-has 10.0.20.9 tell 10.0.20.3, length 28\n13:54:49.925047 ARP, Request who-has 10.0.20.10 tell 10.0.20.3, length 28\n13:54:49.925135 ARP, Request who-has 10.0.20.13 tell 10.0.20.3, length 28\n13:54:49.925151 ARP, Request who-has 10.0.20.14 tell 10.0.20.3, length 28\n13:54:49.925182 ARP, Request who-has 10.0.20.15 tell 10.0.20.3, length 28\n13:54:49.925199 ARP, Request who-has 10.0.20.16 tell 10.0.20.3, length 28\n13:54:50.025457 ARP, Request who-has 10.0.20.19 tell 10.0.20.3, length 28\n13:54:50.025481 ARP, Request who-has 10.0.20.20 tell 10.0.20.3, length 28\n13:54:50.025504 ARP, Request who-has 10.0.20.21 tell 10.0.20.3, length 28\n13:54:50.025522 ARP, Request who-has 10.0.20.22 tell 10.0.20.3, length 28\n13:54:50.025540 ARP, Request who-has 10.0.20.23 tell 10.0.20.3, length 28\n13:54:50.025557 ARP, Request who-has 10.0.20.24 tell 10.0.20.3, length 28\n13:54:50.025576 ARP, Request who-has 10.0.20.25 tell 10.0.20.3, length 28\n13:54:50.025594 ARP, Request who-has 10.0.20.26 tell 10.0.20.3, length 28\n13:54:50.025611 ARP, Request who-has 10.0.20.27 tell 10.0.20.3, length 28\n13:54:50.025629 ARP, Request who-has 10.0.20.28 tell 10.0.20.3, length 28\n13:54:50.025646 ARP, Request who-has 10.0.20.29 tell 10.0.20.3, length 28\n13:54:50.025664 ARP, Request who-has 10.0.20.30 tell 10.0.20.3, length 28\n13:54:50.125512 ARP, Request who-has 10.0.20.93 tell 10.0.20.3, length 28\n13:54:50.125582 ARP, Request who-has 10.0.20.96 tell 10.0.20.3, length 28\n13:54:50.125602 ARP, Request who-has 10.0.20.97 tell 10.0.20.3, length 28\n13:54:50.125619 ARP, Request who-has 10.0.20.98 tell 10.0.20.3, length 28\n13:54:50.125690 ARP, Request who-has 10.0.20.101 tell 10.0.20.3, length 28\n13:54:50.125708 ARP, Request who-has 10.0.20.102 tell 10.0.20.3, length 28\n13:54:50.125725 ARP, Request who-has 10.0.20.103 tell 10.0.20.3, length 28\n13:54:50.125743 ARP, Request who-has 10.0.20.104 tell 10.0.20.3, length 28\n13:54:50.125760 ARP, Request who-has 10.0.20.105 tell 10.0.20.3, length 28\n13:54:50.125778 ARP, Request who-has 10.0.20.106 tell 10.0.20.3, length 28\n13:54:50.125839 ARP, Request who-has 10.0.20.109 tell 10.0.20.3, length 28\n13:54:50.125858 ARP, Request who-has 10.0.20.110 tell 10.0.20.3, length 28\n13:54:50.225570 ARP, Request who-has 10.0.20.163 tell 10.0.20.3, length 28\n13:54:50.225637 ARP, Request who-has 10.0.20.166 tell 10.0.20.3, length 28\n13:54:50.225701 ARP, Request who-has 10.0.20.169 tell 10.0.20.3, length 28\n13:54:50.225719 ARP, Request who-has 10.0.20.170 tell 10.0.20.3, length 28\n13:54:50.225783 ARP, Request who-has 10.0.20.173 tell 10.0.20.3, length 28\n13:54:50.225801 ARP, Request who-has 10.0.20.174 tell 10.0.20.3, length 28\n13:54:50.225818 ARP, Request who-has 10.0.20.175 tell 10.0.20.3, length 28\n13:54:50.225900 ARP, Request who-has 10.0.20.178 tell 10.0.20.3, length 28\n13:54:50.225918 ARP, Request who-has 10.0.20.179 tell 10.0.20.3, length 28\n13:54:50.225936 ARP, Request who-has 10.0.20.180 tell 10.0.20.3, length 28\n13:54:50.225952 ARP, Request who-has 10.0.20.181 tell 10.0.20.3, length 28\n13:54:50.226013 ARP, Request who-has 10.0.20.184 tell 10.0.20.3, length 28\n13:54:50.325608 ARP, Request who-has 10.0.20.223 tell 10.0.20.3, length 28\n13:54:50.325675 ARP, Request who-has 10.0.20.226 tell 10.0.20.3, length 28\n13:54:50.325737 ARP, Request who-has 10.0.20.229 tell 10.0.20.3, length 28\n13:54:50.325797 ARP, Request who-has 10.0.20.232 tell 10.0.20.3, length 28\n13:54:50.325861 ARP, Request who-has 10.0.20.235 tell 10.0.20.3, length 28\n13:54:50.325880 ARP, Request who-has 10.0.20.236 tell 10.0.20.3, length 28\n13:54:50.325897 ARP, Request who-has 10.0.20.237 tell 10.0.20.3, length 28\n13:54:50.325960 ARP, Request who-has 10.0.20.240 tell 10.0.20.3, length 28\n13:54:50.325979 ARP, Request who-has 10.0.20.241 tell 10.0.20.3, length 28\n13:54:50.326040 ARP, Request who-has 10.0.20.244 tell 10.0.20.3, length 28\n13:54:50.326059 ARP, Request who-has 10.0.20.245 tell 10.0.20.3, length 28\n13:54:50.326118 ARP, Request who-has 10.0.20.248 tell 10.0.20.3, length 28\n13:54:50.425662 ARP, Request who-has 10.0.20.31 tell 10.0.20.3, length 28\n13:54:50.425729 ARP, Request who-has 10.0.20.34 tell 10.0.20.3, length 28\n13:54:50.425791 ARP, Request who-has 10.0.20.37 tell 10.0.20.3, length 28\n13:54:50.425851 ARP, Request who-has 10.0.20.40 tell 10.0.20.3, length 28\n13:54:50.425911 ARP, Request who-has 10.0.20.43 tell 10.0.20.3, length 28\n13:54:50.425972 ARP, Request who-has 10.0.20.46 tell 10.0.20.3, length 28\n13:54:50.425990 ARP, Request who-has 10.0.20.47 tell 10.0.20.3, length 28\n13:54:50.426052 ARP, Request who-has 10.0.20.50 tell 10.0.20.3, length 28\n13:54:50.426070 ARP, Request who-has 10.0.20.51 tell 10.0.20.3, length 28\n13:54:50.426132 ARP, Request who-has 10.0.20.54 tell 10.0.20.3, length 28\n13:54:50.426151 ARP, Request who-has 10.0.20.55 tell 10.0.20.3, length 28\n13:54:50.426216 ARP, Request who-has 10.0.20.58 tell 10.0.20.3, length 28\n13:54:50.525719 ARP, Request who-has 10.0.20.87 tell 10.0.20.3, length 28\n13:54:50.525786 ARP, Request who-has 10.0.20.90 tell 10.0.20.3, length 28\n13:54:50.525849 ARP, Request who-has 10.0.20.94 tell 10.0.20.3, length 28\n13:54:50.525910 ARP, Request who-has 10.0.20.99 tell 10.0.20.3, length 28\n13:54:50.525970 ARP, Request who-has 10.0.20.107 tell 10.0.20.3, length 28\n13:54:50.526032 ARP, Request who-has 10.0.20.111 tell 10.0.20.3, length 28\n13:54:50.526050 ARP, Request who-has 10.0.20.112 tell 10.0.20.3, length 28\n13:54:50.526111 ARP, Request who-has 10.0.20.115 tell 10.0.20.3, length 28\n13:54:50.526129 ARP, Request who-has 10.0.20.116 tell 10.0.20.3, length 28\n13:54:50.526191 ARP, Request who-has 10.0.20.119 tell 10.0.20.3, length 28\n13:54:50.526209 ARP, Request who-has 10.0.20.120 tell 10.0.20.3, length 28\n13:54:50.526269 ARP, Request who-has 10.0.20.123 tell 10.0.20.3, length 28\n13:54:50.625771 ARP, Request who-has 10.0.20.152 tell 10.0.20.3, length 28\n13:54:50.625838 ARP, Request who-has 10.0.20.155 tell 10.0.20.3, length 28\n13:54:50.625900 ARP, Request who-has 10.0.20.158 tell 10.0.20.3, length 28\n13:54:50.625965 ARP, Request who-has 10.0.20.161 tell 10.0.20.3, length 28\n13:54:50.626026 ARP, Request who-has 10.0.20.164 tell 10.0.20.3, length 28\n13:54:50.626086 ARP, Request who-has 10.0.20.167 tell 10.0.20.3, length 28\n13:54:50.626148 ARP, Request who-has 10.0.20.171 tell 10.0.20.3, length 28\n13:54:50.626166 ARP, Request who-has 10.0.20.172 tell 10.0.20.3, length 28\n13:54:50.626227 ARP, Request who-has 10.0.20.176 tell 10.0.20.3, length 28\n13:54:50.626245 ARP, Request who-has 10.0.20.177 tell 10.0.20.3, length 28\n13:54:50.626306 ARP, Request who-has 10.0.20.182 tell 10.0.20.3, length 28\n13:54:50.626324 ARP, Request who-has 10.0.20.183 tell 10.0.20.3, length 28\n13:54:50.725827 ARP, Request who-has 10.0.20.212 tell 10.0.20.3, length 28\n13:54:50.725894 ARP, Request who-has 10.0.20.215 tell 10.0.20.3, length 28\n13:54:50.725955 ARP, Request who-has 10.0.20.218 tell 10.0.20.3, length 28\n13:54:50.726022 ARP, Request who-has 10.0.20.221 tell 10.0.20.3, length 28\n13:54:50.726083 ARP, Request who-has 10.0.20.224 tell 10.0.20.3, length 28\n13:54:50.726143 ARP, Request who-has 10.0.20.227 tell 10.0.20.3, length 28\n13:54:50.726205 ARP, Request who-has 10.0.20.230 tell 10.0.20.3, length 28\n13:54:50.726226 ARP, Request who-has 10.0.20.231 tell 10.0.20.3, length 28\n13:54:50.726289 ARP, Request who-has 10.0.20.234 tell 10.0.20.3, length 28\n13:54:50.726307 ARP, Request who-has 10.0.20.238 tell 10.0.20.3, length 28\n13:54:50.726369 ARP, Request who-has 10.0.20.242 tell 10.0.20.3, length 28\n13:54:50.726388 ARP, Request who-has 10.0.20.243 tell 10.0.20.3, length 28\n13:54:50.825885 ARP, Request who-has 10.0.20.18 tell 10.0.20.3, length 28\n13:54:50.825956 ARP, Request who-has 10.0.20.32 tell 10.0.20.3, length 28\n13:54:50.826018 ARP, Request who-has 10.0.20.35 tell 10.0.20.3, length 28\n13:54:50.826079 ARP, Request who-has 10.0.20.38 tell 10.0.20.3, length 28\n13:54:50.826141 ARP, Request who-has 10.0.20.41 tell 10.0.20.3, length 28\n13:54:50.826203 ARP, Request who-has 10.0.20.44 tell 10.0.20.3, length 28\n13:54:50.826265 ARP, Request who-has 10.0.20.48 tell 10.0.20.3, length 28\n13:54:50.826283 ARP, Request who-has 10.0.20.49 tell 10.0.20.3, length 28\n13:54:50.826342 ARP, Request who-has 10.0.20.52 tell 10.0.20.3, length 28\n13:54:50.826406 ARP, Request who-has 10.0.20.56 tell 10.0.20.3, length 28\n13:54:50.826469 ARP, Request who-has 10.0.20.59 tell 10.0.20.3, length 28\n13:54:50.826489 ARP, Request who-has 10.0.20.60 tell 10.0.20.3, length 28\n13:54:50.925934 ARP, Request who-has 10.0.20.83 tell 10.0.20.3, length 28\n13:54:50.926002 ARP, Request who-has 10.0.20.86 tell 10.0.20.3, length 28\n13:54:50.926065 ARP, Request who-has 10.0.20.89 tell 10.0.20.3, length 28\n13:54:50.926126 ARP, Request who-has 10.0.20.92 tell 10.0.20.3, length 28\n13:54:50.926189 ARP, Request who-has 10.0.20.95 tell 10.0.20.3, length 28\n13:54:50.926249 ARP, Request who-has 10.0.20.100 tell 10.0.20.3, length 28\n13:54:50.926309 ARP, Request who-has 10.0.20.108 tell 10.0.20.3, length 28\n13:54:50.926370 ARP, Request who-has 10.0.20.113 tell 10.0.20.3, length 28\n13:54:50.926437 ARP, Request who-has 10.0.20.117 tell 10.0.20.3, length 28\n13:54:50.926498 ARP, Request who-has 10.0.20.121 tell 10.0.20.3, length 28\n13:54:50.926561 ARP, Request who-has 10.0.20.124 tell 10.0.20.3, length 28\n13:54:50.926582 ARP, Request who-has 10.0.20.125 tell 10.0.20.3, length 28\n13:54:50.952936 ARP, Request who-has 10.0.20.16 tell 10.0.20.3, length 28\n13:54:50.952937 ARP, Request who-has 10.0.20.15 tell 10.0.20.3, length 28\n13:54:50.952938 ARP, Request who-has 10.0.20.14 tell 10.0.20.3, length 28\n13:54:50.952938 ARP, Request who-has 10.0.20.13 tell 10.0.20.3, length 28\n13:54:50.952939 ARP, Request who-has 10.0.20.10 tell 10.0.20.3, length 28\n13:54:50.952940 ARP, Request who-has 10.0.20.9 tell 10.0.20.3, length 28\n13:54:50.952940 ARP, Request who-has 10.0.20.8 tell 10.0.20.3, length 28\n13:54:50.952941 ARP, Request who-has 10.0.20.7 tell 10.0.20.3, length 28\n13:54:50.952942 ARP, Request who-has 10.0.20.6 tell 10.0.20.3, length 28\n13:54:50.952942 ARP, Request who-has 10.0.20.5 tell 10.0.20.3, length 28\n13:54:50.952943 ARP, Request who-has 10.0.20.2 tell 10.0.20.3, length 28\n13:54:50.952943 ARP, Request who-has 10.0.20.1 tell 10.0.20.3, length 28\n13:54:51.048924 ARP, Request who-has 10.0.20.30 tell 10.0.20.3, length 28\n13:54:51.048926 ARP, Request who-has 10.0.20.29 tell 10.0.20.3, length 28\n13:54:51.048927 ARP, Request who-has 10.0.20.28 tell 10.0.20.3, length 28\n13:54:51.048928 ARP, Request who-has 10.0.20.27 tell 10.0.20.3, length 28\n13:54:51.048928 ARP, Request who-has 10.0.20.26 tell 10.0.20.3, length 28\n13:54:51.048929 ARP, Request who-has 10.0.20.25 tell 10.0.20.3, length 28\n13:54:51.048930 ARP, Request who-has 10.0.20.24 tell 10.0.20.3, length 28\n13:54:51.048930 ARP, Request who-has 10.0.20.23 tell 10.0.20.3, length 28\n13:54:51.048931 ARP, Request who-has 10.0.20.22 tell 10.0.20.3, length 28\n13:54:51.048931 ARP, Request who-has 10.0.20.21 tell 10.0.20.3, length 28\n13:54:51.048932 ARP, Request who-has 10.0.20.20 tell 10.0.20.3, length 28\n13:54:51.048933 ARP, Request who-has 10.0.20.19 tell 10.0.20.3, length 28\n13:54:51.144945 ARP, Request who-has 10.0.20.110 tell 10.0.20.3, length 28\n13:54:51.144949 ARP, Request who-has 10.0.20.109 tell 10.0.20.3, length 28\n13:54:51.144949 ARP, Request who-has 10.0.20.106 tell 10.0.20.3, length 28\n13:54:51.144950 ARP, Request who-has 10.0.20.105 tell 10.0.20.3, length 28\n13:54:51.144950 ARP, Request who-has 10.0.20.104 tell 10.0.20.3, length 28\n13:54:51.144951 ARP, Request who-has 10.0.20.103 tell 10.0.20.3, length 28\n13:54:51.144951 ARP, Request who-has 10.0.20.102 tell 10.0.20.3, length 28\n13:54:51.144952 ARP, Request who-has 10.0.20.101 tell 10.0.20.3, length 28\n13:54:51.144953 ARP, Request who-has 10.0.20.98 tell 10.0.20.3, length 28\n13:54:51.144953 ARP, Request who-has 10.0.20.97 tell 10.0.20.3, length 28\n13:54:51.144954 ARP, Request who-has 10.0.20.96 tell 10.0.20.3, length 28\n13:54:51.144954 ARP, Request who-has 10.0.20.93 tell 10.0.20.3, length 28\n13:54:51.226935 IP 10.0.20.3.57436 > 10.0.20.4.http: Flags [S], seq 2574521844, win 64240, options [mss 1460,sackOK,TS val 230223085 ecr 0,nop,wscale 7], length 0\n13:54:51.226947 IP 10.0.20.4.http > 10.0.20.3.57436: Flags [R.], seq 0, ack 2574521845, win 0, length 0\n13:54:51.227247 ARP, Request who-has 10.0.20.11 tell 10.0.20.3, length 28\n13:54:51.227269 ARP, Request who-has 10.0.20.12 tell 10.0.20.3, length 28\n13:54:51.227322 ARP, Request who-has 10.0.20.17 tell 10.0.20.3, length 28\n13:54:51.227454 ARP, Request who-has 10.0.20.33 tell 10.0.20.3, length 28\n13:54:51.227471 ARP, Request who-has 10.0.20.36 tell 10.0.20.3, length 28\n13:54:51.227488 ARP, Request who-has 10.0.20.39 tell 10.0.20.3, length 28\n13:54:51.227504 ARP, Request who-has 10.0.20.42 tell 10.0.20.3, length 28\n13:54:51.227521 ARP, Request who-has 10.0.20.45 tell 10.0.20.3, length 28\n13:54:51.227542 ARP, Request who-has 10.0.20.53 tell 10.0.20.3, length 28\n13:54:51.227559 ARP, Request who-has 10.0.20.57 tell 10.0.20.3, length 28\n13:54:51.227578 ARP, Request who-has 10.0.20.61 tell 10.0.20.3, length 28\n13:54:51.227594 ARP, Request who-has 10.0.20.62 tell 10.0.20.3, length 28\n13:54:51.227614 ARP, Request who-has 10.0.20.63 tell 10.0.20.3, length 28\n13:54:51.227640 ARP, Request who-has 10.0.20.64 tell 10.0.20.3, length 28\n13:54:51.227667 ARP, Request who-has 10.0.20.65 tell 10.0.20.3, length 28\n13:54:51.227682 ARP, Request who-has 10.0.20.66 tell 10.0.20.3, length 28\n13:54:51.227697 ARP, Request who-has 10.0.20.67 tell 10.0.20.3, length 28\n13:54:51.227817 ARP, Request who-has 10.0.20.70 tell 10.0.20.3, length 28\n13:54:51.227848 ARP, Request who-has 10.0.20.71 tell 10.0.20.3, length 28\n13:54:51.227870 ARP, Request who-has 10.0.20.72 tell 10.0.20.3, length 28\n13:54:51.227888 ARP, Request who-has 10.0.20.73 tell 10.0.20.3, length 28\n13:54:51.227908 ARP, Request who-has 10.0.20.74 tell 10.0.20.3, length 28\n13:54:51.227927 ARP, Request who-has 10.0.20.75 tell 10.0.20.3, length 28\n13:54:51.227945 ARP, Request who-has 10.0.20.76 tell 10.0.20.3, length 28\n13:54:51.227963 ARP, Request who-has 10.0.20.77 tell 10.0.20.3, length 28\n13:54:51.227981 ARP, Request who-has 10.0.20.78 tell 10.0.20.3, length 28\n13:54:51.228003 ARP, Request who-has 10.0.20.79 tell 10.0.20.3, length 28\n13:54:51.228037 ARP, Request who-has 10.0.20.80 tell 10.0.20.3, length 28\n13:54:51.228055 ARP, Request who-has 10.0.20.81 tell 10.0.20.3, length 28\n13:54:51.228081 ARP, Request who-has 10.0.20.82 tell 10.0.20.3, length 28\n13:54:51.228097 ARP, Request who-has 10.0.20.84 tell 10.0.20.3, length 28\n13:54:51.228111 ARP, Request who-has 10.0.20.85 tell 10.0.20.3, length 28\n13:54:51.228126 ARP, Request who-has 10.0.20.88 tell 10.0.20.3, length 28\n13:54:51.228141 ARP, Request who-has 10.0.20.91 tell 10.0.20.3, length 28\n13:54:51.240943 ARP, Request who-has 10.0.20.184 tell 10.0.20.3, length 28\n13:54:51.240946 ARP, Request who-has 10.0.20.181 tell 10.0.20.3, length 28\n13:54:51.240956 ARP, Request who-has 10.0.20.180 tell 10.0.20.3, length 28\n13:54:51.240957 ARP, Request who-has 10.0.20.179 tell 10.0.20.3, length 28\n13:54:51.240957 ARP, Request who-has 10.0.20.178 tell 10.0.20.3, length 28\n13:54:51.240958 ARP, Request who-has 10.0.20.175 tell 10.0.20.3, length 28\n13:54:51.240959 ARP, Request who-has 10.0.20.174 tell 10.0.20.3, length 28\n13:54:51.240959 ARP, Request who-has 10.0.20.173 tell 10.0.20.3, length 28\n13:54:51.240960 ARP, Request who-has 10.0.20.170 tell 10.0.20.3, length 28\n13:54:51.240960 ARP, Request who-has 10.0.20.169 tell 10.0.20.3, length 28\n13:54:51.240961 ARP, Request who-has 10.0.20.166 tell 10.0.20.3, length 28\n13:54:51.240962 ARP, Request who-has 10.0.20.163 tell 10.0.20.3, length 28\n13:54:51.327457 ARP, Request who-has 10.0.20.126 tell 10.0.20.3, length 28\n13:54:51.327490 ARP, Request who-has 10.0.20.127 tell 10.0.20.3, length 28\n13:54:51.327781 ARP, Request who-has 10.0.20.130 tell 10.0.20.3, length 28\n13:54:51.327809 ARP, Request who-has 10.0.20.131 tell 10.0.20.3, length 28\n13:54:51.327827 ARP, Request who-has 10.0.20.132 tell 10.0.20.3, length 28\n13:54:51.327843 ARP, Request who-has 10.0.20.133 tell 10.0.20.3, length 28\n13:54:51.327864 ARP, Request who-has 10.0.20.134 tell 10.0.20.3, length 28\n13:54:51.328013 ARP, Request who-has 10.0.20.137 tell 10.0.20.3, length 28\n13:54:51.328053 ARP, Request who-has 10.0.20.138 tell 10.0.20.3, length 28\n13:54:51.328079 ARP, Request who-has 10.0.20.139 tell 10.0.20.3, length 28\n13:54:51.328095 ARP, Request who-has 10.0.20.140 tell 10.0.20.3, length 28\n13:54:51.328111 ARP, Request who-has 10.0.20.141 tell 10.0.20.3, length 28\n13:54:51.328127 ARP, Request who-has 10.0.20.142 tell 10.0.20.3, length 28\n13:54:51.328143 ARP, Request who-has 10.0.20.143 tell 10.0.20.3, length 28\n13:54:51.328160 ARP, Request who-has 10.0.20.144 tell 10.0.20.3, length 28\n13:54:51.328178 ARP, Request who-has 10.0.20.145 tell 10.0.20.3, length 28\n13:54:51.328194 ARP, Request who-has 10.0.20.146 tell 10.0.20.3, length 28\n13:54:51.328211 ARP, Request who-has 10.0.20.147 tell 10.0.20.3, length 28\n13:54:51.328226 ARP, Request who-has 10.0.20.148 tell 10.0.20.3, length 28\n13:54:51.328242 ARP, Request who-has 10.0.20.149 tell 10.0.20.3, length 28\n13:54:51.328258 ARP, Request who-has 10.0.20.150 tell 10.0.20.3, length 28\n13:54:51.328279 ARP, Request who-has 10.0.20.151 tell 10.0.20.3, length 28\n13:54:51.328490 ARP, Request who-has 10.0.20.154 tell 10.0.20.3, length 28\n13:54:51.328509 ARP, Request who-has 10.0.20.156 tell 10.0.20.3, length 28\n13:54:51.328525 ARP, Request who-has 10.0.20.157 tell 10.0.20.3, length 28\n13:54:51.328541 ARP, Request who-has 10.0.20.159 tell 10.0.20.3, length 28\n13:54:51.328557 ARP, Request who-has 10.0.20.160 tell 10.0.20.3, length 28\n13:54:51.328581 ARP, Request who-has 10.0.20.162 tell 10.0.20.3, length 28\n13:54:51.328606 ARP, Request who-has 10.0.20.165 tell 10.0.20.3, length 28\n13:54:51.328630 ARP, Request who-has 10.0.20.168 tell 10.0.20.3, length 28\n13:54:51.336932 ARP, Request who-has 10.0.20.248 tell 10.0.20.3, length 28\n13:54:51.336934 ARP, Request who-has 10.0.20.245 tell 10.0.20.3, length 28\n13:54:51.336935 ARP, Request who-has 10.0.20.244 tell 10.0.20.3, length 28\n13:54:51.336935 ARP, Request who-has 10.0.20.241 tell 10.0.20.3, length 28\n13:54:51.336936 ARP, Request who-has 10.0.20.240 tell 10.0.20.3, length 28\n13:54:51.336946 ARP, Request who-has 10.0.20.237 tell 10.0.20.3, length 28\n13:54:51.336947 ARP, Request who-has 10.0.20.236 tell 10.0.20.3, length 28\n13:54:51.336948 ARP, Request who-has 10.0.20.235 tell 10.0.20.3, length 28\n13:54:51.336948 ARP, Request who-has 10.0.20.232 tell 10.0.20.3, length 28\n13:54:51.336949 ARP, Request who-has 10.0.20.229 tell 10.0.20.3, length 28\n13:54:51.336949 ARP, Request who-has 10.0.20.226 tell 10.0.20.3, length 28\n13:54:51.336950 ARP, Request who-has 10.0.20.223 tell 10.0.20.3, length 28\n13:54:51.427504 ARP, Request who-has 10.0.20.199 tell 10.0.20.3, length 28\n13:54:51.427547 ARP, Request who-has 10.0.20.200 tell 10.0.20.3, length 28\n13:54:51.427661 ARP, Request who-has 10.0.20.203 tell 10.0.20.3, length 28\n13:54:51.427699 ARP, Request who-has 10.0.20.204 tell 10.0.20.3, length 28\n13:54:51.427734 ARP, Request who-has 10.0.20.205 tell 10.0.20.3, length 28\n13:54:51.427763 ARP, Request who-has 10.0.20.206 tell 10.0.20.3, length 28\n13:54:51.427793 ARP, Request who-has 10.0.20.207 tell 10.0.20.3, length 28\n13:54:51.427945 ARP, Request who-has 10.0.20.210 tell 10.0.20.3, length 28\n13:54:51.427981 ARP, Request who-has 10.0.20.211 tell 10.0.20.3, length 28\n13:54:51.428003 ARP, Request who-has 10.0.20.213 tell 10.0.20.3, length 28\n13:54:51.428019 ARP, Request who-has 10.0.20.214 tell 10.0.20.3, length 28\n13:54:51.428036 ARP, Request who-has 10.0.20.216 tell 10.0.20.3, length 28\n13:54:51.428071 ARP, Request who-has 10.0.20.217 tell 10.0.20.3, length 28\n13:54:51.428088 ARP, Request who-has 10.0.20.219 tell 10.0.20.3, length 28\n13:54:51.428105 ARP, Request who-has 10.0.20.220 tell 10.0.20.3, length 28\n13:54:51.428124 ARP, Request who-has 10.0.20.222 tell 10.0.20.3, length 28\n13:54:51.428149 ARP, Request who-has 10.0.20.225 tell 10.0.20.3, length 28\n13:54:51.428174 ARP, Request who-has 10.0.20.228 tell 10.0.20.3, length 28\n13:54:51.428205 ARP, Request who-has 10.0.20.233 tell 10.0.20.3, length 28\n13:54:51.428384 ARP, Request who-has 10.0.20.246 tell 10.0.20.3, length 28\n13:54:51.428401 ARP, Request who-has 10.0.20.247 tell 10.0.20.3, length 28\n13:54:51.428425 ARP, Request who-has 10.0.20.249 tell 10.0.20.3, length 28\n13:54:51.428443 ARP, Request who-has 10.0.20.250 tell 10.0.20.3, length 28\n13:54:51.428460 ARP, Request who-has 10.0.20.251 tell 10.0.20.3, length 28\n13:54:51.428476 ARP, Request who-has 10.0.20.252 tell 10.0.20.3, length 28\n13:54:51.428496 ARP, Request who-has 10.0.20.253 tell 10.0.20.3, length 28\n13:54:51.428513 ARP, Request who-has 10.0.20.254 tell 10.0.20.3, length 28\n13:54:51.428542 ARP, Request who-has 10.0.20.0 tell 10.0.20.3, length 28\n13:54:51.428687 ARP, Request who-has 10.0.20.68 tell 10.0.20.3, length 28\n13:54:51.428706 ARP, Request who-has 10.0.20.69 tell 10.0.20.3, length 28\n13:54:51.428757 ARP, Request who-has 10.0.20.114 tell 10.0.20.3, length 28\n13:54:51.428775 ARP, Request who-has 10.0.20.118 tell 10.0.20.3, length 28\n13:54:51.428795 ARP, Request who-has 10.0.20.122 tell 10.0.20.3, length 28\n13:54:51.432294 ARP, Request who-has 10.0.20.128 tell 10.0.20.3, length 28\n13:54:51.432327 ARP, Request who-has 10.0.20.129 tell 10.0.20.3, length 28\n13:54:51.432353 ARP, Request who-has 10.0.20.135 tell 10.0.20.3, length 28\n13:54:51.432384 ARP, Request who-has 10.0.20.136 tell 10.0.20.3, length 28\n13:54:51.432402 ARP, Request who-has 10.0.20.153 tell 10.0.20.3, length 28\n13:54:51.432897 ARP, Request who-has 10.0.20.58 tell 10.0.20.3, length 28\n13:54:51.432899 ARP, Request who-has 10.0.20.55 tell 10.0.20.3, length 28\n13:54:51.432900 ARP, Request who-has 10.0.20.54 tell 10.0.20.3, length 28\n13:54:51.432900 ARP, Request who-has 10.0.20.51 tell 10.0.20.3, length 28\n13:54:51.432901 ARP, Request who-has 10.0.20.50 tell 10.0.20.3, length 28\n13:54:51.432902 ARP, Request who-has 10.0.20.47 tell 10.0.20.3, length 28\n13:54:51.432902 ARP, Request who-has 10.0.20.46 tell 10.0.20.3, length 28\n13:54:51.432903 ARP, Request who-has 10.0.20.43 tell 10.0.20.3, length 28\n13:54:51.432903 ARP, Request who-has 10.0.20.40 tell 10.0.20.3, length 28\n13:54:51.432904 ARP, Request who-has 10.0.20.37 tell 10.0.20.3, length 28\n13:54:51.432905 ARP, Request who-has 10.0.20.34 tell 10.0.20.3, length 28\n13:54:51.432905 ARP, Request who-has 10.0.20.31 tell 10.0.20.3, length 28\n13:54:51.528083 ARP, Request who-has 10.0.20.239 tell 10.0.20.3, length 28\n13:54:51.532392 ARP, Request who-has 10.0.20.194 tell 10.0.20.3, length 28\n13:54:51.532479 ARP, Request who-has 10.0.20.197 tell 10.0.20.3, length 28\n13:54:51.532500 ARP, Request who-has 10.0.20.198 tell 10.0.20.3, length 28\n13:54:51.532518 ARP, Request who-has 10.0.20.201 tell 10.0.20.3, length 28\n13:54:51.532537 ARP, Request who-has 10.0.20.202 tell 10.0.20.3, length 28\n13:54:51.532614 ARP, Request who-has 10.0.20.208 tell 10.0.20.3, length 28\n13:54:51.532637 ARP, Request who-has 10.0.20.209 tell 10.0.20.3, length 28\n13:54:51.532893 ARP, Request who-has 10.0.20.123 tell 10.0.20.3, length 28\n13:54:51.532894 ARP, Request who-has 10.0.20.120 tell 10.0.20.3, length 28\n13:54:51.532895 ARP, Request who-has 10.0.20.119 tell 10.0.20.3, length 28\n13:54:51.532895 ARP, Request who-has 10.0.20.116 tell 10.0.20.3, length 28\n13:54:51.532896 ARP, Request who-has 10.0.20.115 tell 10.0.20.3, length 28\n13:54:51.532897 ARP, Request who-has 10.0.20.112 tell 10.0.20.3, length 28\n13:54:51.532897 ARP, Request who-has 10.0.20.111 tell 10.0.20.3, length 28\n13:54:51.532898 ARP, Request who-has 10.0.20.107 tell 10.0.20.3, length 28\n13:54:51.532899 ARP, Request who-has 10.0.20.99 tell 10.0.20.3, length 28\n13:54:51.532899 ARP, Request who-has 10.0.20.94 tell 10.0.20.3, length 28\n13:54:51.532900 ARP, Request who-has 10.0.20.90 tell 10.0.20.3, length 28\n13:54:51.532900 ARP, Request who-has 10.0.20.87 tell 10.0.20.3, length 28\n13:54:51.628025 ARP, Request who-has 10.0.20.186 tell 10.0.20.3, length 28\n13:54:51.628094 ARP, Request who-has 10.0.20.189 tell 10.0.20.3, length 28\n13:54:51.628160 ARP, Request who-has 10.0.20.192 tell 10.0.20.3, length 28\n13:54:51.628228 ARP, Request who-has 10.0.20.195 tell 10.0.20.3, length 28\n13:54:51.628610 ARP, Request who-has 10.0.20.185 tell 10.0.20.3, length 28\n13:54:51.628751 ARP, Request who-has 10.0.20.188 tell 10.0.20.3, length 28\n13:54:51.628924 ARP, Request who-has 10.0.20.191 tell 10.0.20.3, length 28\n13:54:51.628958 ARP, Request who-has 10.0.20.193 tell 10.0.20.3, length 28\n13:54:51.629091 ARP, Request who-has 10.0.20.187 tell 10.0.20.3, length 28\n13:54:51.629131 ARP, Request who-has 10.0.20.190 tell 10.0.20.3, length 28\n13:54:51.632603 ARP, Request who-has 10.0.20.196 tell 10.0.20.3, length 28\n13:54:51.656931 ARP, Request who-has 10.0.20.183 tell 10.0.20.3, length 28\n13:54:51.656932 ARP, Request who-has 10.0.20.182 tell 10.0.20.3, length 28\n13:54:51.656933 ARP, Request who-has 10.0.20.177 tell 10.0.20.3, length 28\n13:54:51.656934 ARP, Request who-has 10.0.20.176 tell 10.0.20.3, length 28\n13:54:51.656934 ARP, Request who-has 10.0.20.172 tell 10.0.20.3, length 28\n13:54:51.656935 ARP, Request who-has 10.0.20.171 tell 10.0.20.3, length 28\n13:54:51.656936 ARP, Request who-has 10.0.20.167 tell 10.0.20.3, length 28\n13:54:51.656936 ARP, Request who-has 10.0.20.164 tell 10.0.20.3, length 28\n13:54:51.656937 ARP, Request who-has 10.0.20.161 tell 10.0.20.3, length 28\n13:54:51.656938 ARP, Request who-has 10.0.20.158 tell 10.0.20.3, length 28\n13:54:51.656938 ARP, Request who-has 10.0.20.155 tell 10.0.20.3, length 28\n13:54:51.656939 ARP, Request who-has 10.0.20.152 tell 10.0.20.3, length 28\n13:54:51.752909 ARP, Request who-has 10.0.20.243 tell 10.0.20.3, length 28\n13:54:51.752911 ARP, Request who-has 10.0.20.242 tell 10.0.20.3, length 28\n13:54:51.752912 ARP, Request who-has 10.0.20.238 tell 10.0.20.3, length 28\n13:54:51.752912 ARP, Request who-has 10.0.20.234 tell 10.0.20.3, length 28\n13:54:51.752913 ARP, Request who-has 10.0.20.231 tell 10.0.20.3, length 28\n13:54:51.752913 ARP, Request who-has 10.0.20.230 tell 10.0.20.3, length 28\n13:54:51.752914 ARP, Request who-has 10.0.20.227 tell 10.0.20.3, length 28\n13:54:51.752915 ARP, Request who-has 10.0.20.224 tell 10.0.20.3, length 28\n13:54:51.752915 ARP, Request who-has 10.0.20.221 tell 10.0.20.3, length 28\n13:54:51.752916 ARP, Request who-has 10.0.20.218 tell 10.0.20.3, length 28\n13:54:51.752917 ARP, Request who-has 10.0.20.215 tell 10.0.20.3, length 28\n13:54:51.752917 ARP, Request who-has 10.0.20.212 tell 10.0.20.3, length 28\n13:54:51.848938 ARP, Request who-has 10.0.20.60 tell 10.0.20.3, length 28\n13:54:51.848940 ARP, Request who-has 10.0.20.59 tell 10.0.20.3, length 28\n13:54:51.848941 ARP, Request who-has 10.0.20.56 tell 10.0.20.3, length 28\n13:54:51.848942 ARP, Request who-has 10.0.20.52 tell 10.0.20.3, length 28\n13:54:51.848942 ARP, Request who-has 10.0.20.49 tell 10.0.20.3, length 28\n13:54:51.848943 ARP, Request who-has 10.0.20.48 tell 10.0.20.3, length 28\n13:54:51.848944 ARP, Request who-has 10.0.20.44 tell 10.0.20.3, length 28\n13:54:51.848944 ARP, Request who-has 10.0.20.41 tell 10.0.20.3, length 28\n13:54:51.848945 ARP, Request who-has 10.0.20.38 tell 10.0.20.3, length 28\n13:54:51.848946 ARP, Request who-has 10.0.20.35 tell 10.0.20.3, length 28\n13:54:51.848946 ARP, Request who-has 10.0.20.32 tell 10.0.20.3, length 28\n13:54:51.848947 ARP, Request who-has 10.0.20.18 tell 10.0.20.3, length 28\n13:54:51.948923 ARP, Request who-has 10.0.20.125 tell 10.0.20.3, length 28\n13:54:51.948925 ARP, Request who-has 10.0.20.124 tell 10.0.20.3, length 28\n13:54:51.948925 ARP, Request who-has 10.0.20.121 tell 10.0.20.3, length 28\n13:54:51.948926 ARP, Request who-has 10.0.20.117 tell 10.0.20.3, length 28\n13:54:51.948927 ARP, Request who-has 10.0.20.113 tell 10.0.20.3, length 28\n13:54:51.948927 ARP, Request who-has 10.0.20.108 tell 10.0.20.3, length 28\n13:54:51.948928 ARP, Request who-has 10.0.20.100 tell 10.0.20.3, length 28\n13:54:51.948929 ARP, Request who-has 10.0.20.95 tell 10.0.20.3, length 28\n13:54:51.948929 ARP, Request who-has 10.0.20.92 tell 10.0.20.3, length 28\n13:54:51.948930 ARP, Request who-has 10.0.20.89 tell 10.0.20.3, length 28\n13:54:51.948931 ARP, Request who-has 10.0.20.86 tell 10.0.20.3, length 28\n13:54:51.948931 ARP, Request who-has 10.0.20.83 tell 10.0.20.3, length 28\n13:54:51.976931 ARP, Request who-has 10.0.20.1 tell 10.0.20.3, length 28\n13:54:51.976933 ARP, Request who-has 10.0.20.2 tell 10.0.20.3, length 28\n13:54:51.976934 ARP, Request who-has 10.0.20.5 tell 10.0.20.3, length 28\n13:54:51.976934 ARP, Request who-has 10.0.20.6 tell 10.0.20.3, length 28\n13:54:51.976935 ARP, Request who-has 10.0.20.7 tell 10.0.20.3, length 28\n13:54:51.976936 ARP, Request who-has 10.0.20.8 tell 10.0.20.3, length 28\n13:54:51.976936 ARP, Request who-has 10.0.20.9 tell 10.0.20.3, length 28\n13:54:51.976937 ARP, Request who-has 10.0.20.10 tell 10.0.20.3, length 28\n13:54:51.976938 ARP, Request who-has 10.0.20.13 tell 10.0.20.3, length 28\n13:54:51.976938 ARP, Request who-has 10.0.20.14 tell 10.0.20.3, length 28\n13:54:51.976939 ARP, Request who-has 10.0.20.15 tell 10.0.20.3, length 28\n13:54:51.976939 ARP, Request who-has 10.0.20.16 tell 10.0.20.3, length 28\n13:54:52.072939 ARP, Request who-has 10.0.20.19 tell 10.0.20.3, length 28\n13:54:52.072942 ARP, Request who-has 10.0.20.20 tell 10.0.20.3, length 28\n13:54:52.072943 ARP, Request who-has 10.0.20.21 tell 10.0.20.3, length 28\n13:54:52.072944 ARP, Request who-has 10.0.20.22 tell 10.0.20.3, length 28\n13:54:52.072944 ARP, Request who-has 10.0.20.23 tell 10.0.20.3, length 28\n13:54:52.072945 ARP, Request who-has 10.0.20.24 tell 10.0.20.3, length 28\n13:54:52.072945 ARP, Request who-has 10.0.20.25 tell 10.0.20.3, length 28\n13:54:52.072946 ARP, Request who-has 10.0.20.26 tell 10.0.20.3, length 28\n13:54:52.072946 ARP, Request who-has 10.0.20.27 tell 10.0.20.3, length 28\n13:54:52.072947 ARP, Request who-has 10.0.20.28 tell 10.0.20.3, length 28\n13:54:52.072948 ARP, Request who-has 10.0.20.29 tell 10.0.20.3, length 28\n13:54:52.072948 ARP, Request who-has 10.0.20.30 tell 10.0.20.3, length 28\n13:54:52.168928 ARP, Request who-has 10.0.20.93 tell 10.0.20.3, length 28\n13:54:52.168932 ARP, Request who-has 10.0.20.96 tell 10.0.20.3, length 28\n13:54:52.168932 ARP, Request who-has 10.0.20.97 tell 10.0.20.3, length 28\n13:54:52.168933 ARP, Request who-has 10.0.20.98 tell 10.0.20.3, length 28\n13:54:52.168934 ARP, Request who-has 10.0.20.101 tell 10.0.20.3, length 28\n13:54:52.168934 ARP, Request who-has 10.0.20.102 tell 10.0.20.3, length 28\n13:54:52.168935 ARP, Request who-has 10.0.20.103 tell 10.0.20.3, length 28\n13:54:52.168935 ARP, Request who-has 10.0.20.104 tell 10.0.20.3, length 28\n13:54:52.168936 ARP, Request who-has 10.0.20.105 tell 10.0.20.3, length 28\n13:54:52.168937 ARP, Request who-has 10.0.20.106 tell 10.0.20.3, length 28\n13:54:52.168937 ARP, Request who-has 10.0.20.109 tell 10.0.20.3, length 28\n13:54:52.168938 ARP, Request who-has 10.0.20.110 tell 10.0.20.3, length 28\n13:54:52.233031 ARP, Request who-has 10.0.20.91 tell 10.0.20.3, length 28\n13:54:52.233033 ARP, Request who-has 10.0.20.88 tell 10.0.20.3, length 28\n13:54:52.233034 ARP, Request who-has 10.0.20.85 tell 10.0.20.3, length 28\n13:54:52.233035 ARP, Request who-has 10.0.20.84 tell 10.0.20.3, length 28\n13:54:52.233035 ARP, Request who-has 10.0.20.82 tell 10.0.20.3, length 28\n13:54:52.233036 ARP, Request who-has 10.0.20.81 tell 10.0.20.3, length 28\n13:54:52.233037 ARP, Request who-has 10.0.20.80 tell 10.0.20.3, length 28\n13:54:52.233037 ARP, Request who-has 10.0.20.79 tell 10.0.20.3, length 28\n13:54:52.233038 ARP, Request who-has 10.0.20.78 tell 10.0.20.3, length 28\n13:54:52.233039 ARP, Request who-has 10.0.20.77 tell 10.0.20.3, length 28\n13:54:52.233039 ARP, Request who-has 10.0.20.76 tell 10.0.20.3, length 28\n13:54:52.233040 ARP, Request who-has 10.0.20.75 tell 10.0.20.3, length 28\n13:54:52.233041 ARP, Request who-has 10.0.20.74 tell 10.0.20.3, length 28\n13:54:52.233041 ARP, Request who-has 10.0.20.73 tell 10.0.20.3, length 28\n13:54:52.233042 ARP, Request who-has 10.0.20.72 tell 10.0.20.3, length 28\n13:54:52.233043 ARP, Request who-has 10.0.20.71 tell 10.0.20.3, length 28\n13:54:52.233043 ARP, Request who-has 10.0.20.70 tell 10.0.20.3, length 28\n13:54:52.233044 ARP, Request who-has 10.0.20.67 tell 10.0.20.3, length 28\n13:54:52.233045 ARP, Request who-has 10.0.20.66 tell 10.0.20.3, length 28\n13:54:52.233046 ARP, Request who-has 10.0.20.65 tell 10.0.20.3, length 28\n13:54:52.233047 ARP, Request who-has 10.0.20.64 tell 10.0.20.3, length 28\n13:54:52.233047 ARP, Request who-has 10.0.20.63 tell 10.0.20.3, length 28\n13:54:52.233048 ARP, Request who-has 10.0.20.62 tell 10.0.20.3, length 28\n13:54:52.233048 ARP, Request who-has 10.0.20.61 tell 10.0.20.3, length 28\n13:54:52.233049 ARP, Request who-has 10.0.20.57 tell 10.0.20.3, length 28\n13:54:52.233050 ARP, Request who-has 10.0.20.53 tell 10.0.20.3, length 28\n13:54:52.233050 ARP, Request who-has 10.0.20.45 tell 10.0.20.3, length 28\n13:54:52.233051 ARP, Request who-has 10.0.20.42 tell 10.0.20.3, length 28\n13:54:52.233052 ARP, Request who-has 10.0.20.39 tell 10.0.20.3, length 28\n13:54:52.233052 ARP, Request who-has 10.0.20.36 tell 10.0.20.3, length 28\n13:54:52.233053 ARP, Request who-has 10.0.20.33 tell 10.0.20.3, length 28\n13:54:52.233054 ARP, Request who-has 10.0.20.17 tell 10.0.20.3, length 28\n13:54:52.233054 ARP, Request who-has 10.0.20.12 tell 10.0.20.3, length 28\n13:54:52.233055 ARP, Request who-has 10.0.20.11 tell 10.0.20.3, length 28\n13:54:52.264917 ARP, Request who-has 10.0.20.163 tell 10.0.20.3, length 28\n13:54:52.264918 ARP, Request who-has 10.0.20.166 tell 10.0.20.3, length 28\n13:54:52.264919 ARP, Request who-has 10.0.20.169 tell 10.0.20.3, length 28\n13:54:52.264920 ARP, Request who-has 10.0.20.170 tell 10.0.20.3, length 28\n13:54:52.264920 ARP, Request who-has 10.0.20.173 tell 10.0.20.3, length 28\n13:54:52.264921 ARP, Request who-has 10.0.20.174 tell 10.0.20.3, length 28\n13:54:52.264925 ARP, Request who-has 10.0.20.175 tell 10.0.20.3, length 28\n13:54:52.264925 ARP, Request who-has 10.0.20.178 tell 10.0.20.3, length 28\n13:54:52.264926 ARP, Request who-has 10.0.20.179 tell 10.0.20.3, length 28\n13:54:52.264927 ARP, Request who-has 10.0.20.180 tell 10.0.20.3, length 28\n13:54:52.264927 ARP, Request who-has 10.0.20.181 tell 10.0.20.3, length 28\n13:54:52.264928 ARP, Request who-has 10.0.20.184 tell 10.0.20.3, length 28\n13:54:52.333031 ARP, Request who-has 10.0.20.168 tell 10.0.20.3, length 28\n13:54:52.333032 ARP, Request who-has 10.0.20.165 tell 10.0.20.3, length 28\n13:54:52.333033 ARP, Request who-has 10.0.20.162 tell 10.0.20.3, length 28\n13:54:52.333034 ARP, Request who-has 10.0.20.160 tell 10.0.20.3, length 28\n13:54:52.333034 ARP, Request who-has 10.0.20.159 tell 10.0.20.3, length 28\n13:54:52.333035 ARP, Request who-has 10.0.20.157 tell 10.0.20.3, length 28\n13:54:52.333036 ARP, Request who-has 10.0.20.156 tell 10.0.20.3, length 28\n13:54:52.333036 ARP, Request who-has 10.0.20.154 tell 10.0.20.3, length 28\n13:54:52.333037 ARP, Request who-has 10.0.20.151 tell 10.0.20.3, length 28\n13:54:52.333038 ARP, Request who-has 10.0.20.150 tell 10.0.20.3, length 28\n13:54:52.333039 ARP, Request who-has 10.0.20.149 tell 10.0.20.3, length 28\n13:54:52.333039 ARP, Request who-has 10.0.20.148 tell 10.0.20.3, length 28\n13:54:52.333040 ARP, Request who-has 10.0.20.147 tell 10.0.20.3, length 28\n13:54:52.333040 ARP, Request who-has 10.0.20.146 tell 10.0.20.3, length 28\n13:54:52.333041 ARP, Request who-has 10.0.20.145 tell 10.0.20.3, length 28\n13:54:52.333042 ARP, Request who-has 10.0.20.144 tell 10.0.20.3, length 28\n13:54:52.333042 ARP, Request who-has 10.0.20.143 tell 10.0.20.3, length 28\n13:54:52.333043 ARP, Request who-has 10.0.20.142 tell 10.0.20.3, length 28\n13:54:52.333044 ARP, Request who-has 10.0.20.141 tell 10.0.20.3, length 28\n13:54:52.333044 ARP, Request who-has 10.0.20.140 tell 10.0.20.3, length 28\n13:54:52.333045 ARP, Request who-has 10.0.20.139 tell 10.0.20.3, length 28\n13:54:52.333045 ARP, Request who-has 10.0.20.138 tell 10.0.20.3, length 28\n13:54:52.333046 ARP, Request who-has 10.0.20.137 tell 10.0.20.3, length 28\n13:54:52.333047 ARP, Request who-has 10.0.20.134 tell 10.0.20.3, length 28\n13:54:52.333048 ARP, Request who-has 10.0.20.133 tell 10.0.20.3, length 28\n13:54:52.333048 ARP, Request who-has 10.0.20.132 tell 10.0.20.3, length 28\n13:54:52.333049 ARP, Request who-has 10.0.20.131 tell 10.0.20.3, length 28\n13:54:52.333049 ARP, Request who-has 10.0.20.130 tell 10.0.20.3, length 28\n13:54:52.333050 ARP, Request who-has 10.0.20.127 tell 10.0.20.3, length 28\n13:54:52.333051 ARP, Request who-has 10.0.20.126 tell 10.0.20.3, length 28\n13:54:52.360921 ARP, Request who-has 10.0.20.223 tell 10.0.20.3, length 28\n13:54:52.360922 ARP, Request who-has 10.0.20.226 tell 10.0.20.3, length 28\n13:54:52.360923 ARP, Request who-has 10.0.20.229 tell 10.0.20.3, length 28\n13:54:52.360924 ARP, Request who-has 10.0.20.232 tell 10.0.20.3, length 28\n13:54:52.360924 ARP, Request who-has 10.0.20.235 tell 10.0.20.3, length 28\n13:54:52.360925 ARP, Request who-has 10.0.20.236 tell 10.0.20.3, length 28\n13:54:52.360926 ARP, Request who-has 10.0.20.237 tell 10.0.20.3, length 28\n13:54:52.360926 ARP, Request who-has 10.0.20.240 tell 10.0.20.3, length 28\n13:54:52.360927 ARP, Request who-has 10.0.20.241 tell 10.0.20.3, length 28\n13:54:52.360928 ARP, Request who-has 10.0.20.244 tell 10.0.20.3, length 28\n13:54:52.360928 ARP, Request who-has 10.0.20.245 tell 10.0.20.3, length 28\n13:54:52.360929 ARP, Request who-has 10.0.20.248 tell 10.0.20.3, length 28\n13:54:52.457147 ARP, Request who-has 10.0.20.31 tell 10.0.20.3, length 28\n13:54:52.457149 ARP, Request who-has 10.0.20.34 tell 10.0.20.3, length 28\n13:54:52.457149 ARP, Request who-has 10.0.20.37 tell 10.0.20.3, length 28\n13:54:52.457150 ARP, Request who-has 10.0.20.40 tell 10.0.20.3, length 28\n13:54:52.457151 ARP, Request who-has 10.0.20.43 tell 10.0.20.3, length 28\n13:54:52.457152 ARP, Request who-has 10.0.20.46 tell 10.0.20.3, length 28\n13:54:52.457152 ARP, Request who-has 10.0.20.47 tell 10.0.20.3, length 28\n13:54:52.457153 ARP, Request who-has 10.0.20.50 tell 10.0.20.3, length 28\n13:54:52.457154 ARP, Request who-has 10.0.20.51 tell 10.0.20.3, length 28\n13:54:52.457154 ARP, Request who-has 10.0.20.54 tell 10.0.20.3, length 28\n13:54:52.457155 ARP, Request who-has 10.0.20.55 tell 10.0.20.3, length 28\n13:54:52.457156 ARP, Request who-has 10.0.20.58 tell 10.0.20.3, length 28\n13:54:52.457156 ARP, Request who-has 10.0.20.153 tell 10.0.20.3, length 28\n13:54:52.457157 ARP, Request who-has 10.0.20.136 tell 10.0.20.3, length 28\n13:54:52.457158 ARP, Request who-has 10.0.20.135 tell 10.0.20.3, length 28\n13:54:52.457158 ARP, Request who-has 10.0.20.129 tell 10.0.20.3, length 28\n13:54:52.457159 ARP, Request who-has 10.0.20.128 tell 10.0.20.3, length 28\n13:54:52.457160 ARP, Request who-has 10.0.20.122 tell 10.0.20.3, length 28\n13:54:52.457160 ARP, Request who-has 10.0.20.118 tell 10.0.20.3, length 28\n13:54:52.457161 ARP, Request who-has 10.0.20.114 tell 10.0.20.3, length 28\n13:54:52.457162 ARP, Request who-has 10.0.20.69 tell 10.0.20.3, length 28\n13:54:52.457162 ARP, Request who-has 10.0.20.68 tell 10.0.20.3, length 28\n13:54:52.457163 ARP, Request who-has 10.0.20.0 tell 10.0.20.3, length 28\n13:54:52.457164 ARP, Request who-has 10.0.20.254 tell 10.0.20.3, length 28\n13:54:52.457165 ARP, Request who-has 10.0.20.253 tell 10.0.20.3, length 28\n13:54:52.457165 ARP, Request who-has 10.0.20.252 tell 10.0.20.3, length 28\n13:54:52.457166 ARP, Request who-has 10.0.20.251 tell 10.0.20.3, length 28\n13:54:52.457166 ARP, Request who-has 10.0.20.250 tell 10.0.20.3, length 28\n13:54:52.457167 ARP, Request who-has 10.0.20.249 tell 10.0.20.3, length 28\n13:54:52.457168 ARP, Request who-has 10.0.20.247 tell 10.0.20.3, length 28\n13:54:52.457168 ARP, Request who-has 10.0.20.246 tell 10.0.20.3, length 28\n13:54:52.457169 ARP, Request who-has 10.0.20.233 tell 10.0.20.3, length 28\n13:54:52.457170 ARP, Request who-has 10.0.20.228 tell 10.0.20.3, length 28\n13:54:52.457170 ARP, Request who-has 10.0.20.225 tell 10.0.20.3, length 28\n13:54:52.457171 ARP, Request who-has 10.0.20.222 tell 10.0.20.3, length 28\n13:54:52.457172 ARP, Request who-has 10.0.20.220 tell 10.0.20.3, length 28\n13:54:52.457172 ARP, Request who-has 10.0.20.219 tell 10.0.20.3, length 28\n13:54:52.457173 ARP, Request who-has 10.0.20.217 tell 10.0.20.3, length 28\n13:54:52.457174 ARP, Request who-has 10.0.20.216 tell 10.0.20.3, length 28\n13:54:52.457174 ARP, Request who-has 10.0.20.214 tell 10.0.20.3, length 28\n13:54:52.457175 ARP, Request who-has 10.0.20.213 tell 10.0.20.3, length 28\n13:54:52.457176 ARP, Request who-has 10.0.20.211 tell 10.0.20.3, length 28\n13:54:52.457177 ARP, Request who-has 10.0.20.210 tell 10.0.20.3, length 28\n13:54:52.457177 ARP, Request who-has 10.0.20.207 tell 10.0.20.3, length 28\n13:54:52.457178 ARP, Request who-has 10.0.20.206 tell 10.0.20.3, length 28\n13:54:52.457178 ARP, Request who-has 10.0.20.205 tell 10.0.20.3, length 28\n13:54:52.457179 ARP, Request who-has 10.0.20.204 tell 10.0.20.3, length 28\n13:54:52.457180 ARP, Request who-has 10.0.20.203 tell 10.0.20.3, length 28\n13:54:52.457180 ARP, Request who-has 10.0.20.200 tell 10.0.20.3, length 28\n13:54:52.457181 ARP, Request who-has 10.0.20.199 tell 10.0.20.3, length 28\n13:54:52.552958 ARP, Request who-has 10.0.20.87 tell 10.0.20.3, length 28\n13:54:52.552959 ARP, Request who-has 10.0.20.90 tell 10.0.20.3, length 28\n13:54:52.552960 ARP, Request who-has 10.0.20.94 tell 10.0.20.3, length 28\n13:54:52.552961 ARP, Request who-has 10.0.20.99 tell 10.0.20.3, length 28\n13:54:52.552962 ARP, Request who-has 10.0.20.107 tell 10.0.20.3, length 28\n13:54:52.552962 ARP, Request who-has 10.0.20.111 tell 10.0.20.3, length 28\n13:54:52.552963 ARP, Request who-has 10.0.20.112 tell 10.0.20.3, length 28\n13:54:52.552964 ARP, Request who-has 10.0.20.115 tell 10.0.20.3, length 28\n13:54:52.552964 ARP, Request who-has 10.0.20.116 tell 10.0.20.3, length 28\n13:54:52.552965 ARP, Request who-has 10.0.20.119 tell 10.0.20.3, length 28\n13:54:52.552965 ARP, Request who-has 10.0.20.120 tell 10.0.20.3, length 28\n13:54:52.552966 ARP, Request who-has 10.0.20.123 tell 10.0.20.3, length 28\n13:54:52.552967 ARP, Request who-has 10.0.20.209 tell 10.0.20.3, length 28\n13:54:52.552967 ARP, Request who-has 10.0.20.208 tell 10.0.20.3, length 28\n13:54:52.552968 ARP, Request who-has 10.0.20.202 tell 10.0.20.3, length 28\n13:54:52.552969 ARP, Request who-has 10.0.20.201 tell 10.0.20.3, length 28\n13:54:52.552969 ARP, Request who-has 10.0.20.198 tell 10.0.20.3, length 28\n13:54:52.552970 ARP, Request who-has 10.0.20.197 tell 10.0.20.3, length 28\n13:54:52.552970 ARP, Request who-has 10.0.20.194 tell 10.0.20.3, length 28\n13:54:52.552971 ARP, Request who-has 10.0.20.239 tell 10.0.20.3, length 28\n13:54:52.648942 ARP, Request who-has 10.0.20.196 tell 10.0.20.3, length 28\n13:54:52.648943 ARP, Request who-has 10.0.20.190 tell 10.0.20.3, length 28\n13:54:52.648944 ARP, Request who-has 10.0.20.187 tell 10.0.20.3, length 28\n13:54:52.648945 ARP, Request who-has 10.0.20.193 tell 10.0.20.3, length 28\n13:54:52.648945 ARP, Request who-has 10.0.20.191 tell 10.0.20.3, length 28\n13:54:52.648946 ARP, Request who-has 10.0.20.188 tell 10.0.20.3, length 28\n13:54:52.648947 ARP, Request who-has 10.0.20.185 tell 10.0.20.3, length 28\n13:54:52.648947 ARP, Request who-has 10.0.20.195 tell 10.0.20.3, length 28\n13:54:52.648948 ARP, Request who-has 10.0.20.192 tell 10.0.20.3, length 28\n13:54:52.648948 ARP, Request who-has 10.0.20.189 tell 10.0.20.3, length 28\n13:54:52.648949 ARP, Request who-has 10.0.20.186 tell 10.0.20.3, length 28\n13:54:52.680923 ARP, Request who-has 10.0.20.152 tell 10.0.20.3, length 28\n13:54:52.680924 ARP, Request who-has 10.0.20.155 tell 10.0.20.3, length 28\n13:54:52.680925 ARP, Request who-has 10.0.20.158 tell 10.0.20.3, length 28\n13:54:52.680925 ARP, Request who-has 10.0.20.161 tell 10.0.20.3, length 28\n13:54:52.680926 ARP, Request who-has 10.0.20.164 tell 10.0.20.3, length 28\n13:54:52.680927 ARP, Request who-has 10.0.20.167 tell 10.0.20.3, length 28\n13:54:52.680927 ARP, Request who-has 10.0.20.171 tell 10.0.20.3, length 28\n13:54:52.680928 ARP, Request who-has 10.0.20.172 tell 10.0.20.3, length 28\n13:54:52.680929 ARP, Request who-has 10.0.20.176 tell 10.0.20.3, length 28\n13:54:52.680929 ARP, Request who-has 10.0.20.177 tell 10.0.20.3, length 28\n13:54:52.680930 ARP, Request who-has 10.0.20.182 tell 10.0.20.3, length 28\n13:54:52.680930 ARP, Request who-has 10.0.20.183 tell 10.0.20.3, length 28\n13:54:52.726900 IP 10.0.20.3.57450 > 10.0.20.4.http: Flags [S], seq 1057964882, win 64240, options [mss 1460,sackOK,TS val 230224585 ecr 0,nop,wscale 7], length 0\n13:54:52.726908 IP 10.0.20.4.http > 10.0.20.3.57450: Flags [R.], seq 0, ack 1057964883, win 0, length 0\n13:54:52.776920 ARP, Request who-has 10.0.20.212 tell 10.0.20.3, length 28\n13:54:52.776922 ARP, Request who-has 10.0.20.215 tell 10.0.20.3, length 28\n13:54:52.776922 ARP, Request who-has 10.0.20.218 tell 10.0.20.3, length 28\n13:54:52.776923 ARP, Request who-has 10.0.20.221 tell 10.0.20.3, length 28\n13:54:52.776924 ARP, Request who-has 10.0.20.224 tell 10.0.20.3, length 28\n13:54:52.776924 ARP, Request who-has 10.0.20.227 tell 10.0.20.3, length 28\n13:54:52.776925 ARP, Request who-has 10.0.20.230 tell 10.0.20.3, length 28\n13:54:52.776926 ARP, Request who-has 10.0.20.231 tell 10.0.20.3, length 28\n13:54:52.776926 ARP, Request who-has 10.0.20.234 tell 10.0.20.3, length 28\n13:54:52.776927 ARP, Request who-has 10.0.20.238 tell 10.0.20.3, length 28\n13:54:52.776927 ARP, Request who-has 10.0.20.242 tell 10.0.20.3, length 28\n13:54:52.776928 ARP, Request who-has 10.0.20.243 tell 10.0.20.3, length 28\n13:54:52.872924 ARP, Request who-has 10.0.20.18 tell 10.0.20.3, length 28\n13:54:52.872926 ARP, Request who-has 10.0.20.32 tell 10.0.20.3, length 28\n13:54:52.872927 ARP, Request who-has 10.0.20.35 tell 10.0.20.3, length 28\n13:54:52.872927 ARP, Request who-has 10.0.20.38 tell 10.0.20.3, length 28\n13:54:52.872928 ARP, Request who-has 10.0.20.41 tell 10.0.20.3, length 28\n13:54:52.872929 ARP, Request who-has 10.0.20.44 tell 10.0.20.3, length 28\n13:54:52.872929 ARP, Request who-has 10.0.20.48 tell 10.0.20.3, length 28\n13:54:52.872930 ARP, Request who-has 10.0.20.49 tell 10.0.20.3, length 28\n13:54:52.872930 ARP, Request who-has 10.0.20.52 tell 10.0.20.3, length 28\n13:54:52.872931 ARP, Request who-has 10.0.20.56 tell 10.0.20.3, length 28\n13:54:52.872932 ARP, Request who-has 10.0.20.59 tell 10.0.20.3, length 28\n13:54:52.872932 ARP, Request who-has 10.0.20.60 tell 10.0.20.3, length 28\n13:54:52.968919 ARP, Request who-has 10.0.20.83 tell 10.0.20.3, length 28\n13:54:52.968921 ARP, Request who-has 10.0.20.86 tell 10.0.20.3, length 28\n13:54:52.968922 ARP, Request who-has 10.0.20.89 tell 10.0.20.3, length 28\n13:54:52.968922 ARP, Request who-has 10.0.20.92 tell 10.0.20.3, length 28\n13:54:52.968923 ARP, Request who-has 10.0.20.95 tell 10.0.20.3, length 28\n13:54:52.968923 ARP, Request who-has 10.0.20.100 tell 10.0.20.3, length 28\n13:54:52.968924 ARP, Request who-has 10.0.20.108 tell 10.0.20.3, length 28\n13:54:52.968925 ARP, Request who-has 10.0.20.113 tell 10.0.20.3, length 28\n13:54:52.968925 ARP, Request who-has 10.0.20.117 tell 10.0.20.3, length 28\n13:54:52.968926 ARP, Request who-has 10.0.20.121 tell 10.0.20.3, length 28\n13:54:52.968927 ARP, Request who-has 10.0.20.124 tell 10.0.20.3, length 28\n13:54:52.968927 ARP, Request who-has 10.0.20.125 tell 10.0.20.3, length 28\n13:54:53.257044 ARP, Request who-has 10.0.20.11 tell 10.0.20.3, length 28\n13:54:53.257046 ARP, Request who-has 10.0.20.12 tell 10.0.20.3, length 28\n13:54:53.257047 ARP, Request who-has 10.0.20.17 tell 10.0.20.3, length 28\n13:54:53.257047 ARP, Request who-has 10.0.20.33 tell 10.0.20.3, length 28\n13:54:53.257048 ARP, Request who-has 10.0.20.36 tell 10.0.20.3, length 28\n13:54:53.257048 ARP, Request who-has 10.0.20.39 tell 10.0.20.3, length 28\n13:54:53.257049 ARP, Request who-has 10.0.20.42 tell 10.0.20.3, length 28\n13:54:53.257050 ARP, Request who-has 10.0.20.45 tell 10.0.20.3, length 28\n13:54:53.257050 ARP, Request who-has 10.0.20.53 tell 10.0.20.3, length 28\n13:54:53.257051 ARP, Request who-has 10.0.20.57 tell 10.0.20.3, length 28\n13:54:53.257052 ARP, Request who-has 10.0.20.61 tell 10.0.20.3, length 28\n13:54:53.257052 ARP, Request who-has 10.0.20.62 tell 10.0.20.3, length 28\n13:54:53.257053 ARP, Request who-has 10.0.20.63 tell 10.0.20.3, length 28\n13:54:53.257054 ARP, Request who-has 10.0.20.64 tell 10.0.20.3, length 28\n13:54:53.257055 ARP, Request who-has 10.0.20.65 tell 10.0.20.3, length 28\n13:54:53.257055 ARP, Request who-has 10.0.20.66 tell 10.0.20.3, length 28\n13:54:53.257056 ARP, Request who-has 10.0.20.67 tell 10.0.20.3, length 28\n13:54:53.257057 ARP, Request who-has 10.0.20.70 tell 10.0.20.3, length 28\n13:54:53.257057 ARP, Request who-has 10.0.20.71 tell 10.0.20.3, length 28\n13:54:53.257058 ARP, Request who-has 10.0.20.72 tell 10.0.20.3, length 28\n13:54:53.257059 ARP, Request who-has 10.0.20.73 tell 10.0.20.3, length 28\n13:54:53.257059 ARP, Request who-has 10.0.20.74 tell 10.0.20.3, length 28\n13:54:53.257060 ARP, Request who-has 10.0.20.75 tell 10.0.20.3, length 28\n13:54:53.257061 ARP, Request who-has 10.0.20.76 tell 10.0.20.3, length 28\n13:54:53.257061 ARP, Request who-has 10.0.20.77 tell 10.0.20.3, length 28\n13:54:53.257062 ARP, Request who-has 10.0.20.78 tell 10.0.20.3, length 28\n13:54:53.257063 ARP, Request who-has 10.0.20.79 tell 10.0.20.3, length 28\n13:54:53.257063 ARP, Request who-has 10.0.20.80 tell 10.0.20.3, length 28\n13:54:53.257064 ARP, Request who-has 10.0.20.81 tell 10.0.20.3, length 28\n13:54:53.257064 ARP, Request who-has 10.0.20.82 tell 10.0.20.3, length 28\n13:54:53.257065 ARP, Request who-has 10.0.20.84 tell 10.0.20.3, length 28\n13:54:53.257066 ARP, Request who-has 10.0.20.85 tell 10.0.20.3, length 28\n13:54:53.257067 ARP, Request who-has 10.0.20.88 tell 10.0.20.3, length 28\n13:54:53.257067 ARP, Request who-has 10.0.20.91 tell 10.0.20.3, length 28\n13:54:53.353028 ARP, Request who-has 10.0.20.126 tell 10.0.20.3, length 28\n13:54:53.353030 ARP, Request who-has 10.0.20.127 tell 10.0.20.3, length 28\n13:54:53.353031 ARP, Request who-has 10.0.20.130 tell 10.0.20.3, length 28\n13:54:53.353031 ARP, Request who-has 10.0.20.131 tell 10.0.20.3, length 28\n13:54:53.353032 ARP, Request who-has 10.0.20.132 tell 10.0.20.3, length 28\n13:54:53.353033 ARP, Request who-has 10.0.20.133 tell 10.0.20.3, length 28\n13:54:53.353033 ARP, Request who-has 10.0.20.134 tell 10.0.20.3, length 28\n13:54:53.353034 ARP, Request who-has 10.0.20.137 tell 10.0.20.3, length 28\n13:54:53.353035 ARP, Request who-has 10.0.20.138 tell 10.0.20.3, length 28\n13:54:53.353036 ARP, Request who-has 10.0.20.139 tell 10.0.20.3, length 28\n13:54:53.353036 ARP, Request who-has 10.0.20.140 tell 10.0.20.3, length 28\n13:54:53.353037 ARP, Request who-has 10.0.20.141 tell 10.0.20.3, length 28\n13:54:53.353037 ARP, Request who-has 10.0.20.142 tell 10.0.20.3, length 28\n13:54:53.353038 ARP, Request who-has 10.0.20.143 tell 10.0.20.3, length 28\n13:54:53.353039 ARP, Request who-has 10.0.20.144 tell 10.0.20.3, length 28\n13:54:53.353039 ARP, Request who-has 10.0.20.145 tell 10.0.20.3, length 28\n13:54:53.353040 ARP, Request who-has 10.0.20.146 tell 10.0.20.3, length 28\n13:54:53.353041 ARP, Request who-has 10.0.20.147 tell 10.0.20.3, length 28\n13:54:53.353041 ARP, Request who-has 10.0.20.148 tell 10.0.20.3, length 28\n13:54:53.353042 ARP, Request who-has 10.0.20.149 tell 10.0.20.3, length 28\n13:54:53.353043 ARP, Request who-has 10.0.20.150 tell 10.0.20.3, length 28\n13:54:53.353043 ARP, Request who-has 10.0.20.151 tell 10.0.20.3, length 28\n13:54:53.353044 ARP, Request who-has 10.0.20.154 tell 10.0.20.3, length 28\n13:54:53.353044 ARP, Request who-has 10.0.20.156 tell 10.0.20.3, length 28\n13:54:53.353045 ARP, Request who-has 10.0.20.157 tell 10.0.20.3, length 28\n13:54:53.353046 ARP, Request who-has 10.0.20.159 tell 10.0.20.3, length 28\n13:54:53.353046 ARP, Request who-has 10.0.20.160 tell 10.0.20.3, length 28\n13:54:53.353047 ARP, Request who-has 10.0.20.162 tell 10.0.20.3, length 28\n13:54:53.353047 ARP, Request who-has 10.0.20.165 tell 10.0.20.3, length 28\n13:54:53.353048 ARP, Request who-has 10.0.20.168 tell 10.0.20.3, length 28\n13:54:53.481257 ARP, Request who-has 10.0.20.199 tell 10.0.20.3, length 28\n13:54:53.481259 ARP, Request who-has 10.0.20.200 tell 10.0.20.3, length 28\n13:54:53.481259 ARP, Request who-has 10.0.20.203 tell 10.0.20.3, length 28\n13:54:53.481260 ARP, Request who-has 10.0.20.204 tell 10.0.20.3, length 28\n13:54:53.481261 ARP, Request who-has 10.0.20.205 tell 10.0.20.3, length 28\n13:54:53.481261 ARP, Request who-has 10.0.20.206 tell 10.0.20.3, length 28\n13:54:53.481262 ARP, Request who-has 10.0.20.207 tell 10.0.20.3, length 28\n13:54:53.481263 ARP, Request who-has 10.0.20.210 tell 10.0.20.3, length 28\n13:54:53.481263 ARP, Request who-has 10.0.20.211 tell 10.0.20.3, length 28\n13:54:53.481264 ARP, Request who-has 10.0.20.213 tell 10.0.20.3, length 28\n13:54:53.481265 ARP, Request who-has 10.0.20.214 tell 10.0.20.3, length 28\n13:54:53.481265 ARP, Request who-has 10.0.20.216 tell 10.0.20.3, length 28\n13:54:53.481266 ARP, Request who-has 10.0.20.217 tell 10.0.20.3, length 28\n13:54:53.481266 ARP, Request who-has 10.0.20.219 tell 10.0.20.3, length 28\n13:54:53.481267 ARP, Request who-has 10.0.20.220 tell 10.0.20.3, length 28\n13:54:53.481268 ARP, Request who-has 10.0.20.222 tell 10.0.20.3, length 28\n13:54:53.481268 ARP, Request who-has 10.0.20.225 tell 10.0.20.3, length 28\n13:54:53.481269 ARP, Request who-has 10.0.20.228 tell 10.0.20.3, length 28\n13:54:53.481270 ARP, Request who-has 10.0.20.233 tell 10.0.20.3, length 28\n13:54:53.481271 ARP, Request who-has 10.0.20.246 tell 10.0.20.3, length 28\n13:54:53.481271 ARP, Request who-has 10.0.20.247 tell 10.0.20.3, length 28\n13:54:53.481272 ARP, Request who-has 10.0.20.249 tell 10.0.20.3, length 28\n13:54:53.481273 ARP, Request who-has 10.0.20.250 tell 10.0.20.3, length 28\n13:54:53.481273 ARP, Request who-has 10.0.20.251 tell 10.0.20.3, length 28\n13:54:53.481274 ARP, Request who-has 10.0.20.252 tell 10.0.20.3, length 28\n13:54:53.481274 ARP, Request who-has 10.0.20.253 tell 10.0.20.3, length 28\n13:54:53.481275 ARP, Request who-has 10.0.20.254 tell 10.0.20.3, length 28\n13:54:53.481276 ARP, Request who-has 10.0.20.0 tell 10.0.20.3, length 28\n13:54:53.481276 ARP, Request who-has 10.0.20.68 tell 10.0.20.3, length 28\n13:54:53.481277 ARP, Request who-has 10.0.20.69 tell 10.0.20.3, length 28\n13:54:53.481278 ARP, Request who-has 10.0.20.114 tell 10.0.20.3, length 28\n13:54:53.481278 ARP, Request who-has 10.0.20.118 tell 10.0.20.3, length 28\n13:54:53.481279 ARP, Request who-has 10.0.20.122 tell 10.0.20.3, length 28\n13:54:53.481280 ARP, Request who-has 10.0.20.128 tell 10.0.20.3, length 28\n13:54:53.481280 ARP, Request who-has 10.0.20.129 tell 10.0.20.3, length 28\n13:54:53.481281 ARP, Request who-has 10.0.20.135 tell 10.0.20.3, length 28\n13:54:53.481281 ARP, Request who-has 10.0.20.136 tell 10.0.20.3, length 28\n13:54:53.481282 ARP, Request who-has 10.0.20.153 tell 10.0.20.3, length 28\n13:54:53.577103 ARP, Request who-has 10.0.20.239 tell 10.0.20.3, length 28\n13:54:53.577104 ARP, Request who-has 10.0.20.194 tell 10.0.20.3, length 28\n13:54:53.577105 ARP, Request who-has 10.0.20.197 tell 10.0.20.3, length 28\n13:54:53.577105 ARP, Request who-has 10.0.20.198 tell 10.0.20.3, length 28\n13:54:53.577106 ARP, Request who-has 10.0.20.201 tell 10.0.20.3, length 28\n13:54:53.577106 ARP, Request who-has 10.0.20.202 tell 10.0.20.3, length 28\n13:54:53.577107 ARP, Request who-has 10.0.20.208 tell 10.0.20.3, length 28\n13:54:53.577108 ARP, Request who-has 10.0.20.209 tell 10.0.20.3, length 28\n13:54:53.672917 ARP, Request who-has 10.0.20.186 tell 10.0.20.3, length 28\n13:54:53.672919 ARP, Request who-has 10.0.20.189 tell 10.0.20.3, length 28\n13:54:53.672920 ARP, Request who-has 10.0.20.192 tell 10.0.20.3, length 28\n13:54:53.672920 ARP, Request who-has 10.0.20.195 tell 10.0.20.3, length 28\n13:54:53.672921 ARP, Request who-has 10.0.20.185 tell 10.0.20.3, length 28\n13:54:53.672922 ARP, Request who-has 10.0.20.188 tell 10.0.20.3, length 28\n13:54:53.672922 ARP, Request who-has 10.0.20.191 tell 10.0.20.3, length 28\n13:54:53.672923 ARP, Request who-has 10.0.20.193 tell 10.0.20.3, length 28\n13:54:53.672924 ARP, Request who-has 10.0.20.187 tell 10.0.20.3, length 28\n13:54:53.672924 ARP, Request who-has 10.0.20.190 tell 10.0.20.3, length 28\n13:54:53.672925 ARP, Request who-has 10.0.20.196 tell 10.0.20.3, length 28\n13:54:55.048845 ARP, Request who-has 10.0.20.3 tell 10.0.20.4, length 28\n13:54:55.048960 ARP, Reply 10.0.20.3 is-at 00:50:56:16:30:c7 (oui Unknown), length 28\n^C\n769 packets captured\n769 packets received by filter\n0 packets dropped by kernel\n

    Another huge flurry of broadcast activity! My apologies for having you scroll through it all, but scanning such output, and even better\u2014analyzing what's going on\u2014is essential practice. Expect lots of output as part of these labs.

    So what did we see in all that? The network scan output reported that host3 and host4 were discovered; did you see where in the packet capture the ARP request and replies are? And speaking of packet captures, we left tcpdump running back on host2, so cancel that now and try to find any broadcasts involving 10.0.20.0/24.

    Assuming everything was done correctly, there should be nothing from that second subnet, as shown in the (heavily shortened) output below. Very good.

    (omitted)\n...\n13:54:05.768997 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:05.768997 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:05.897167 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:05.897170 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:05.993145 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:07.432845 ARP, Request who-has 10.0.10.1 tell 10.0.10.2, length 28\n13:54:07.432890 ARP, Request who-has 10.0.10.2 tell 10.0.10.1, length 28\n13:54:07.432893 ARP, Reply 10.0.10.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n13:54:07.432898 ARP, Reply 10.0.10.1 is-at 00:50:56:94:55:70 (oui Unknown), length 28\n^C\n769 packets captured\n769 packets received by filter\n0 packets dropped by kernel\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#conclusion-and-next-lab","title":"Conclusion and Next Lab","text":"

    So there you have it: use VLANs around your subnets to maintain full control over your broadcast domains and take advantage of all the other benefits of VLANs that I briefly mentioned in the beginning, which we'll dig into in new labs.

    Now isolating subnets against unwanted broadcast traffic is great, but what about unicast, multicast, or even anycast traffic that needs to be able to reach across subnets? It's time to bring in Layer 3 and the role of routing to enable subnets to communicate and full networks to function. But in order to do that, we'll need to add a router to our lab.

    In the next lab, Installing RouterOS on Proxmox, we'll learn how to install MikroTik's RouterOS, a fantastic network operating system (NOS), on Proxmox so we can use it as our router and firewall in future labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/","title":"Exploring Subnets, Broadcast Domains, and Bridges in Proxmox","text":"

    Based on our progress in the last lab, Connecting and Configuring Network Hosts in Proxmox, we know that our four hosts are somehow able to communicate within their subnet. But how exactly are the hosts connecting?

    Recall that each host is configured with a network device connected to the vmbr1 bridge and assigned an IPv4 address in the 10.0.1.0/24 subnet. These two factors are the key to understanding what is happening behind the scenes.

    In this lab, we're going to begin exploring the concepts of subnets, broadcasting domains, and bridges to allow our hosts to communicate (or not, in some cases). Along the way, we'll see how these fundamental concepts lay the foundation for us to build increasingly complex labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/#step-1-examining-the-state-of-our-network-hosts","title":"Step 1: Examining the State of Our Network Hosts","text":"

    The first thing we'll look at is the \"state\" of our network hosts. When host1 sent ping requests and an nmap scan to the other hosts, and received responses, it created records of how to reach them. But how did it find them?

    Remember the Address Resolution Protocol (ARP)? In IPv4, ARP is the first point of contact between hosts on the same subnet. Because host1 has already made contact with each of the other hosts, it should have ARP records accessible that map each host's IPv4 address with its MAC address, which is what is actually used to communicate here on Layer 2.

    When hosts are restarted, however, the ARP cache is flushed, so let's start out with a clean ARP cache here, too, and populate it again so you can visibly see what's happening. First flush host1's ARP cache:

    ip neighbor flush dev eth0\n

    Then perform the nmap network scan again:

    nmap -sn 10.0.1.0/24\n

    which should produce something similar to the following output:

    Starting Nmap 7.80 ( https://nmap.org ) at 2023-06-21 19:07 UTC\nNmap scan report for 10.0.1.1\nHost is up (0.00048s latency).\nNmap scan report for 10.0.1.2\nHost is up (0.00044s latency).\nNmap scan report for 10.0.1.3\nHost is up (0.00022s latency).\nNmap scan report for 10.0.1.4\nHost is up (0.00013s latency).\nNmap done: 256 IP addresses (4 hosts up) scanned in 16.61 seconds\n

    Now that we have a fresh network scan, let's look at host1's ARP cache using the ip tool, part of the iproute2 suite of tools we'll be using regularly in our labs:

    ip neighbor\n

    which should output the following:

    10.0.1.3 dev eth0 lladdr 00:50:56:16:30:c7 REACHABLE\n10.0.1.4 dev eth0 lladdr 00:50:56:ad:24:4a REACHABLE\n10.0.1.2 dev eth0 lladdr 00:50:56:ad:0e:33 REACHABLE\n

    Entries in a device's ARP cache are cached for a certain amount of time and then cleared out, with the \"soft\" limit being once 512 entries are reached and the \"hard\" limit being when there are 1,024 entries, at which point the cache is cleared.

    Check the ARP cache again:

    ip neighbor\n

    and you will see the status of the existing entries have changed, and now indicate they may be flushed if new MAC addresses continue actively populating the ARP cache:

    10.0.1.3 dev eth0 lladdr 00:50:56:16:30:c7 STALE\n10.0.1.4 dev eth0 lladdr 00:50:56:ad:24:4a STALE\n10.0.1.2 dev eth0 lladdr 00:50:56:ad:0e:33 STALE\n

    We won't go much deeper into the innerworkings of the ARP cache at this point, but we will study how the protocol works for neighbor discovery, so you can see what goes on when hosts attempt to reach each other and how it relates to the ARP cache.

    To do this, let's operate from host2, and observe its interactions with host1 at the protocol level during a ping test. To begin, clear out host2's ARP cache so we're starting fresh again:

    sudo ip neighbor flush dev eth0\n

    Return to host1, and begin a packet capture session using tcpdump, another crucial tool we'll be using constantly in our labs:

    sudo tcpdump\n

    Switch back to host2, where we're going to send host1 a single ping request:

    sudo ping -c 1 10.0.1.1\n

    which should produce the following output:

    PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.\n64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.148 ms\n\n--- 10.0.1.1 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 0.148/0.148/0.148/0.000 ms\n

    Here you can see that one request packet was sent from host1 to host2, and a reply packet from host2 to host1 was also successfully transferred, resulting in no packet loss. The two hosts successfully communicated, which means each should now have a record of the other in its ARP cache. Let's check host2's ARP cache:

    ip neighbor\n

    which shows a fresh entry for host2:

    10.0.1.1 dev eth0 lladdr 00:50:56:94:55:70 REACHABLE\n

    This means that not only was host2's ping request successful, but that host1 was properly captured in the ARP cache. The same is also true on the other side for host1. How did all of this happen exchanging just two packets? It didn't\u2014there were six packets involved.

    Let's return to host1, and cancel out (CTRL+C on Windows) of the packet capture. Your output should look very similar to this:

    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n19:21:42.310066 ARP, Request who-has 10.0.1.1 tell 10.0.1.2, length 28\n19:21:42.310088 ARP, Reply 10.0.1.1 is-at 00:50:56:94:55:70 (oui Unknown), length 28\n19:21:42.310132 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 21255, seq 1, length 64\n19:21:42.310140 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 21255, seq 1, length 64\n19:21:47.343328 ARP, Request who-has 10.0.1.2 tell 10.0.1.1, length 28\n19:21:47.343360 ARP, Reply 10.0.1.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n^C\n6 packets captured\n6 packets received by filter\n0 packets dropped by kernel\n

    We'll dig deep into analyzing packets in future labs, but knowing the basics is an invaluable skill from the beginning of your learning to enhance your ability to observe how protocols work and troubleshoot network issues that inevitably arise. So let's start with the packet capture from host2.

    On line 2, you see that tcpdump was listening on host1's eth0 interface, which is connected to host2 via bridge vmbr1 (again, think \"switch\"). That's obvious for this lab, as there's only one interface, but always check on devices with multiple ports.

    The next two lines, 3 and 4, are ARP packets. The first, at 19:21:42.310066, is a broadcast request from the bridge vmbr1 to all hosts on the subnet asking who is 10.0.1.1, as 10.0.1.2 needs to know. The next packet, at 19:21:42.310088, is the broadcast reply from 10.0.1.1 letting the bridge and 10.0.1.2 that it has that IP address, and its MAC address is 00:50:56:94:55:70 (we'll discuss OUIs later).

    The bridge, like any switch, then sends the 3rd packet, at 19:21:42.310132, which is the ICMP echo request (the formal term for the protocol used by ping), to host1, now knowing who it is. host1 responds with the proper ICMP echo reply in the packet at 19:21:42.310140, addressed to 10.0.1.2, but not sure which host that is.

    As a result, host1 also utilizes ARP in packet 5, at 19:21:47.343328, broadcasting a request asking who has 10.0.1.2, as 10.0.1.1 needs to know. The sixth packet, at 19:21:47.343360, is the broadcast reply from 10.0.1.2 letting the bridge and 10.0.1.2 that it has that IP address, and its MAC address is 00:50:56:ad:0e:33.

    When the packet capture was stopped, it completed its job by reporting the number of packets captured, filtered, and dropped. We didn't have a filter defined, such as filtering out ARP packets, and no packets were dropped because of other transmission issues, so it was a successful job.

    One last point about ARP before we move on. Once host1 and host2 know each other, is ARP no longer necessary, since they can simply address each other directly during communication? As with anything in our labs, let's test it out.

    Just like before, put host1 into a packet capture mode:

    sudo tcpdump\n

    and have host2 ping host1. This time, however, have host2 flood ping host1 25 times:

    sudo ping -f -c 25 10.0.1.1\n

    This should result in something like the following:

    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n02:14:34.087556 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 1, length 64\n02:14:34.087576 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 1, length 64\n02:14:34.087644 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 2, length 64\n02:14:34.087647 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 2, length 64\n02:14:34.087702 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 3, length 64\n02:14:34.087705 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 3, length 64\n02:14:34.087740 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 4, length 64\n02:14:34.087743 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 4, length 64\n02:14:34.087769 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 5, length 64\n02:14:34.087772 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 5, length 64\n02:14:34.087797 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 6, length 64\n02:14:34.087800 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 6, length 64\n02:14:34.087845 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 7, length 64\n02:14:34.087848 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 7, length 64\n02:14:34.087897 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 8, length 64\n02:14:34.087900 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 8, length 64\n02:14:34.087933 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 9, length 64\n02:14:34.087936 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 9, length 64\n02:14:34.087962 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 10, length 64\n02:14:34.087964 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 10, length 64\n02:14:34.087997 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 11, length 64\n02:14:34.088000 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 11, length 64\n02:14:34.088033 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 12, length 64\n02:14:34.088036 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 12, length 64\n02:14:34.088078 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 13, length 64\n02:14:34.088081 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 13, length 64\n02:14:34.088105 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 14, length 64\n02:14:34.088108 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 14, length 64\n02:14:34.088141 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 15, length 64\n02:14:34.088144 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 15, length 64\n02:14:34.088178 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 16, length 64\n02:14:34.088180 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 16, length 64\n02:14:34.088221 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 17, length 64\n02:14:34.088224 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 17, length 64\n02:14:34.088255 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 18, length 64\n02:14:34.088257 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 18, length 64\n02:14:34.088295 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 19, length 64\n02:14:34.088298 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 19, length 64\n02:14:34.088329 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 20, length 64\n02:14:34.088331 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 20, length 64\n02:14:34.088373 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 21, length 64\n02:14:34.088375 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 21, length 64\n02:14:34.088414 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 22, length 64\n02:14:34.088417 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 22, length 64\n02:14:34.088448 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 23, length 64\n02:14:34.088450 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 23, length 64\n02:14:34.088475 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 24, length 64\n02:14:34.088478 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 24, length 64\n02:14:34.088502 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 25, length 64\n02:14:34.088504 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 25, length 64\n02:14:39.183337 ARP, Request who-has 10.0.1.2 tell 10.0.1.1, length 28\n02:14:39.183380 ARP, Reply 10.0.1.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n^C\n52 packets captured\n52 packets received by filter\n0 packets dropped by kernel\n

    So the basic answer is that, for the most part, once hosts have cached their addresses in the ARP cache, they can communicate via unicast transmission. Every so often, however, ARP checks are sent to verify host addressing, thus the two extra packets in addition to the 25 pairs of ICMP request/reply pairs.

    Question

    Wondering how often ARP is part of the transmissions between known hosts? Modify the ping command above to use higher count flood pings and see what happens. If it's too many, does the kernel drop packets?

    As we saw with the ARP process, communication between hosts begins with broadcasts across their subnet to determine which hosts have which MAC and IP addresses. Let's move on and learn more about the role of subnets and broadcast domains.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/#step-2-digging-into-ipv4-subnets-and-broadcast-domains","title":"Step 2: Digging into IPv4 Subnets and Broadcast Domains","text":"

    Currently our network consists of four hosts all assigned IPv4 addresses in the same subnet of 10.0.1.0/24, all contained in the same Layer 2 bridge vmbr1. Because they are in the same subnet, and on the same bridge, they should always be able to communicate. We've verifed this using both ping and nmap tests.

    Performing a packet capture, we've also seen what happens during communication at the protocol layer, with hosts broadcasting ARP requests/replies to all hosts when identifying each other. How does broadcasting work within a subnet?

    As we know, a subnet is a defined IP space assigned to hosts. So far, we have assigned the IPs

    • 10.0.1.1 to host1
    • 10.0.1.2 to host2
    • 10.0.1.3 to host3
    • 10.0.1.4 to host4

    Note

    You might have noticed that the last \"octet\" of each host matches the number in each host name. IP addressing is generally arbitrary, but we'll do things like this in some cases to help you follow along in these early labs.

    How many hosts can we have in this address space? You probably have seen many ways to calculate subnet sizes, but let's make it easy by using another handy tool on our Linux hosts: ipcalc.

    Ask ipcalc to calculate the details of our 10.0.1.0/24 subnet from host1:

    ipcalc 10.0.1.0/24\n

    which reports back the following:

    Address:   10.0.1.0             00001010.00000000.00000001. 00000000\nNetmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000\nWildcard:  0.0.0.255            00000000.00000000.00000000. 11111111\n=>\nNetwork:   10.0.1.0/24          00001010.00000000.00000001. 00000000\nHostMin:   10.0.1.1             00001010.00000000.00000001. 00000001\nHostMax:   10.0.1.254           00001010.00000000.00000001. 11111110\nBroadcast: 10.0.1.255           00001010.00000000.00000001. 11111111\nHosts/Net: 254                   Class A, Private Internet\n

    ipcalc has provided us everything we need to know about our subnet in a very nice format. On the left is the name of each calculation, followed by the value in IPv4 integer octets, then the value again formatted as binary octets (for all IP-related data). The last line is a bit different, which we'll also cover below.

    • The Address line shows the address that we submitted in the command
    • The Netmask line shows the netmask that we submitted in the command, both in octet and CIDR format
    • The Wildcard line shows the usable portion of the address within the subnet while everything in the first three octets remains fixed
    • The Network line shows the network ID for this subnet, which you'll recall we used in our nmap network discovery scans
    • The HostMin line shows the first address in this subnet available for host assignment; and we've assigned this value to host1
    • The HostMax line shows the last address in this subnet available for host assignment, and we haven't assigned this value to any host yet
    • The Broadcast line shows the broadcast address in this subnet
    • The Hosts/Net line shows the total number of hosts available in this subnet, which is 256 in our case

    The Network address cannot be assigned to a host, thus it cannot respond to ping requests, either. Let's verify this with a test from host1:

    sudo ping -c 4 10.0.1.0\n

    which results in no replies, as expected:

    PING 10.0.1.0 (10.0.1.0) 56(84) bytes of data.\nFrom 10.0.1.1 icmp_seq=1 Destination Host Unreachable\nFrom 10.0.1.1 icmp_seq=2 Destination Host Unreachable\nFrom 10.0.1.1 icmp_seq=3 Destination Host Unreachable\nFrom 10.0.1.1 icmp_seq=4 Destination Host Unreachable\n\n--- 10.0.1.0 ping statistics ---\n4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3077ms\n

    Tip

    Before we move on, bring up a detached console window for each host in Proxmox by clicking the Console button near the top-right of each guest view, and arrange them on your screen so they're all visible. Depending on your desktop, there are \"quarter tile\" features built-in, such as in Windows or KDE, or extentions available, such as Rectangle for macOS or WinTile for GNOME.

    We already know we can ping 10.0.1.1 through 10.0.1.4, and anything up to 10.0.1.254 if we had hosts assigned to those IP addresses. But what about the broadcast address? Don't hosts use that for ARP request/replies? Let's try to ping it from host1:

    sudo ping 10.0.1.255\n

    and we get an interesting response:

    ping: Do you want to ping broadcast? Then -b. If not, check your local firewall rules\n

    The ping command is giving us a helpful tip: if we want to ping the broadcast address, we need to add the -c flag to the command. Let's try again from host1:

    sudo ping -b 10.0.1.255\n

    and now we get the following output:

    WARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n

    At this point ping is sending ICMP requests, but nothing is visible in the output like it would a normal ping test. How can we observe what's happening? Let's check our other hosts.

    On host2, host3, and host4, run the following command:

    sudo tcpdump\n

    Upon doing this, you should see something similar to the following:

    01:15:56.463377 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 29, length 64\n01:15:57.487378 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 30, length 64\n01:15:58.515390 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 31, length 64\n01:15:59.535379 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 32, length 64\n01:16:00.559384 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 33, length 64\n

    In these packet captures, you're seeing broadcast requests from host1 at 10.0.1.1 to the broadcast address for this subnet at 10.0.1.255. In this case, there are two key things to notice:

    1. Each packet is an ICMP echo request, with no ICMP echo reply being returned
    2. Within each host's console, the seq count matches, showing that every host is receiving the broadcasts simultaneously

    Return to host1 and cancel the broadcast pings with Ctrl+C, and look at the results:

    WARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n^C\n--- 10.0.1.255 ping statistics ---\n33 packets transmitted, 0 received, 100% packet loss, time 32757ms\n

    In this case, 33 packets (here in my case, for example) were broadcasted, but host1 believes none were received resulting in 100% packet loss. However, as we saw using tcpdump, the packets were delivered, but no protocol, such as ARP, was targeted for a reply.

    Note

    There are times where hosts may reply to broadcast pings using approaches such as nmap --script broadcast-ping, but it is not a reliable method depending on the host configuration.

    Now that we've experimented with broadcasts a bit, let's consider the broadcast domain itself. So far, we've observed that all hosts in the subnet can be reached via unicast and broadcast communication. Does this mean the subnet and broadcast domain are contiguous? Let's test this by making a change.

    From Proxmox's UI, change host2's IPv4 address to 10.0.2.2/24. By doing this, we create a second subnet within the same bridge vmbr1. Next, calculate host2's subnet details using the ipcalc tool:

    ipcalc 10.0.2.2/24\n

    and we can see from the results that host2 is now in a completely different subnet:

    Address:   10.0.2.2             00001010.00000000.00000010. 00000010\nNetmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000\nWildcard:  0.0.0.255            00000000.00000000.00000000. 11111111\n=>\nNetwork:   10.0.2.0/24          00001010.00000000.00000010. 00000000\nHostMin:   10.0.2.1             00001010.00000000.00000010. 00000001\nHostMax:   10.0.2.254           00001010.00000000.00000010. 11111110\nBroadcast: 10.0.2.255           00001010.00000000.00000010. 11111111\nHosts/Net: 254                   Class A, Private Internet\n
    • The Network is now 10.0.2.0/24, not 10.0.1.0/24
    • The HostMin is now 10.0.2.1 and the HostMax is now 10.0.2.254
    • The Broadcast is now 10.0.2.255

    Going back to host1, try to ping host2:

    sudo ping 10.0.2.2\n

    Doing this will issue an error:

    ping: connect: Network is unreachable\n

    Try the same from host2, and try to ping host1:

    sudo ping 10.0.1.1\n

    Again, the other subnet is unreachable:

    ping: connect: Network is unreachable\n

    It appears both subnets are isolated from each other, and for subnets on the same switch, this is generally what you want. But are they? Let's try a broadcast from host1 to its subnet's broadcast address. First start the broadcasting from host1:

    sudo ping -b 10.0.1.255\n

    Next, start a packet capture on host2:

    sudo tcpdump\n

    Did you end up with something similar to the output displayed below? What are you now seeing on host2? ICMP requests from host1 on the other network? Apparently broadcast domains are larger in scope than subnets.

    18:05:12.216806 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 1, length 64\n18:05:13.231371 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 2, length 64\n18:05:14.255380 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 3, length 64\n18:05:15.279377 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 4, length 64\n18:05:16.303372 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 5, length 64\n18:05:17.327376 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 6, length 64\n

    It appears that hosts on different subnets cannot directly communicate with each other at Layer 3, but communication is still possible at Layer 2. This is because there is a difference between a Layer 3 broadcast address and a Layer 2 broadcast domain.

    These are the next questions we need to explore with our labs:

    1. How would we prevent communication between subnets at Layer 2
    2. How would we allow communication between subnets at Layer 3

    Before we wrap up this lab, let's consider the role of bridging in this situation.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/#step-3-dipping-our-toes-into-bridging-details","title":"Step 3: Dipping Our Toes into Bridging Details","text":"

    Recall the differences between hubs and switches. Hubs broadcast all frames out to all connected hosts, and not those destined for the broadcast address. All connected hosts are also in the same collision domain, causing packets to collide when hosts attempt to communicate at the same time.

    Switches, however, can enable unicast communication between hosts while limiting broadcasts to all hosts. Each port on a switch is a separate collision domain, as well, preventing packet transmissions among hosts from interfering with each other.

    What about our Linux bridge? In an earlier lab I stated bridges are basically switches, especially in eliminating the impact of collision domains, but they share other characteristics, too. Let's make some more changes to our network to experiment with the impact of bridges on subnets and broadcast domains.

    The first thing we need to do is create another Linux bridge on our Proxmox hypervisor:

    1. At the top of the Proxmox resource tree, select the Proxmox node your lab is running within and then select the System > Network view of the content panel.
    2. At the top-left of the network device table, click the Create dropdown button and select Linux Bridge.
    3. In the dialog box, ensure the Name is vmbr2 and Autostart is checked, then click the Create button.
    4. At the top of the network device table, click the Apply Configuration button and the new bridge will be enabled.

    Next, edit host2s network configuration in Proxmox by setting the eth0 network device's bridge to vmbr2. Be sure to keep the IPv4 address the same, however.

    Now, again start pinging from host1 to its broadcast address:

    sudo ping -b 10.0.1.255\n

    Then start another packet capture on host2:

    sudo tcpdump\n

    What happened this time? Let's look at the results of host1's and host2's output together:

    WARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n^C\n--- 10.0.1.255 ping statistics ---\n145 packets transmitted, 0 received, 100% packet loss, time 147437ms\n
    listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n^C\n0 packets captured\n0 packets received by filter\n0 packets dropped by kernel\n

    In this case, host1 transmitted 145 packets, but host2 captured none of them. Now Layer 2 communication is blocked by creating a second bridge, thus creating two broadcast domains. Bridging seems key to answering the question about preventing communication between subnets at Layer 2.

    Before we wrap up, let's perform a larger test of both unicast and broadcast communication. Like host2, change host4's Bridge to vmbr2, but keep its IPv4 address 10.0.1.4/24. Then arrange the console windows for all four hosts in a quarter tile layout so they're all visible.

    Start a packet capture again on host2:

    sudo tcpdump\n

    and start a ping test on host4 to that subnet's broadcast address:

    sudo ping -b -c 4 10.0.1.255\n

    Next, start a packet capture on host1:

    sudo tcpdump\n

    and start a ping test on host3:

    sudo ping -b -c 4 10.0.1.255\n

    Let's review the results for each host, grouped by bridge.

    host3 sent four ICMP echo requests, which were detected (but not replied to) by host1 within bridge vmbr1:

    eron@host3:~$ sudo ping -b -c 4 10.0.1.255\nWARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n\n--- 10.0.1.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3072ms\n
    eron@host1:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n11:23:16.591449 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 1, length 64\n11:23:17.615374 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 2, length 64\n11:23:18.639371 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 3, length 64\n11:23:19.663375 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 4, length 64\n^C\n4 packets captured\n4 packets received by filter\n0 packets dropped by kernel\n

    Just as above, host4 sent four ICMP echo requests, which were detected (but not replied to) by host2 within bridge vmbr2:

    eron@host4:~$ sudo ping -b -c 4 10.0.1.255\nWARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n\n--- 10.0.1.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3064ms\n
    eron@host2:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n11:22:47.191030 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 1, length 64\n11:22:48.207371 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 2, length 64\n11:22:49.231376 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 3, length 64\n11:22:50.255377 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 4, length 64\n^C\n4 packets captured\n4 packets received by filter\n0 packets dropped by kernel\n

    Within bridge vmbr1, the two hosts were in the same subnet, and the broadcasts were captured as expected. Within bridge vmbr2, the two hosts were not in the same subnet, but the broadcasts were still captured.

    Remember that this was also expected, because regardless of the subnet, broadcasts are being transmitted across the entire Layer 2 broadcast domain, which right now is the entire bridge.

    So we see that bridges can isolate broadcast domains, but only when there is one subnet per bridge. But that essentially means having to restrict an entire switch to only one subnet, which is unrealistic in nearly any network with multiple subnets. In a physical network, this would require a switch for each subnet.

    As our final experiment, let's move host2 and host4 back to vmbr1, and change host4's IPv4 address to 10.0.2.4/24, so it's in the same subnet as host2. With those configuration changes made, we now have two subnets, each with two hosts, on one bridge. What happens when they start communicating?

    Start a packet capture on host1:

    sudo tcpdump\n

    and start a ping test to 10.0.1.0/24 network's broadcast address from host3:

    sudo ping -b -c 4 10.0.1.255\n

    Next start a packet capture on host2:

    sudo tcpdump\n

    and start a ping test to 10.0.2.0/24 network's broadcast address from host4:

    sudo ping -b -c 4 10.0.2.255\n

    Again we'll review the results for each host, grouped by bridge.

    host3 sent four ICMP echo requests, which were detected (but not replied to) by host1 within bridge vmbr1:

    eron@host3:~$ sudo ping -b -c 4 10.0.1.255\nWARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n\n--- 10.0.1.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3065ms\n
    eron@host1:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n15:07:12.790897 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 1, length 64\n15:07:13.807380 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 2, length 64\n15:07:14.831382 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 3, length 64\n15:07:15.855384 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 4, length 64\n15:07:44.485779 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 1, length 64\n15:07:45.487366 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 2, length 64\n15:07:46.511402 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 3, length 64\n15:07:47.535375 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 4, length 64\n^C\n8 packets captured\n8 packets received by filter\n0 packets dropped by kernel\n

    But wait, there are four broadcast packets from host4 here as well! All host4 did was send four ICMP echo requests on its own subnet, which were detected (but not replied to) by host2 within bridge vmbr1:

    eron@host4:~$ sudo ping -b -c 4 10.0.2.255\nWARNING: pinging broadcast address\nPING 10.0.2.255 (10.0.2.255) 56(84) bytes of data.\n\n--- 10.0.2.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3050ms\n
    eron@host2:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n15:07:12.790892 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 1, length 64\n15:07:13.807374 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 2, length 64\n15:07:14.831376 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 3, length 64\n15:07:15.855379 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 4, length 64\n15:07:44.485776 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 1, length 64\n15:07:45.487364 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 2, length 64\n15:07:46.511399 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 3, length 64\n15:07:47.535372 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 4, length 64\n^C\n8 packets captured\n8 packets received by filter\n0 packets dropped by kernel\n

    The packet capture from host2 shows packets from host4 along with those from host3 as well! So now we really see the problem: how can we restrict broadcast domains within the same bridge or switch containing multiple subnets?

    We'll figure that out in the next lab, Exploring Subnets and VLANs in Proxmox. Great work today; I know this was a long lab, but hopefully these concepts are starting to make sense.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/initial-proxmox-network-configuration/","title":"Initial Proxmox Network Configuration","text":"

    In this lab we'll review Proxmox's initial configuration and discuss some preparatory changes to support our lab activities.

    Warning

    Be sure to review the following recommendations before beginning the labs to ensure your setup is configured properly and help you avoid conflicts or downtime on your home LAN.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#default-network-configuration","title":"Default Network Configuration","text":"

    Out of the box, Proxmox detects all compatible network interface cards (NICs) on each node and adds them to the node's list of network devices in the \"System\" > \"Network\" panel. The Proxmox installation will also create a Linux Bridge called vmbr0 that maps to one of the hardware NICs for LAN connectivity.

    This bridge will be configured with IP addressing for the node itself and the default gateway for the LAN the node is connected to. The IP addresses for vmbr0 will be used for accessing the node via the Web and SSH, and also will provide connectivity for clustering with other nodes.

    I recommend considering vmbr0 to be the node's management network, and restricted for these roles. Depending on the setup, it may also be used for LAN access for production VMs and CTs (often on separate VLANs).

    For our labs, however, we'll create separate bridges that allow us to create self-contained networks, and eventually we'll implement functionality to extend our networks to additional hardware and the Internet.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#lab-preparation-changes","title":"Lab Preparation Changes","text":""},{"location":"labs/networks/general/initial-proxmox-network-configuration/#ip-addressing-recommendations","title":"IP Addressing Recommendations","text":"

    There are many ways to plan out your home lab's IP addressing, and as your skills improve your preferences will evolve along with your lab's needs. However, at the very least I strongly suggest having a separate address space from your home LAN and isolate your home lab activities from taking down the LAN that others in your home depend on.

    My personal IPv4 address plan is the following:

    • 192.168.0.0/16 for my home's LAN, split into separate subnets for secure Wi-Fi, guest Wi-Fi, IoT, etc.
    • 172.16.0.0/12 for my home's management network, also split into separate subnets for network equipment, server/storage equipment, security devices, production VMs/CTs, etc.
    • 10.0.0.0/8 for my home lab subnets, as necessary. We'll be using this address space here in the documentation, as well, so you're aware.
    • In addition to the 10/8 prefix, we'll also be using some non-RFC 1918 prefixes reserved for private use to represent public address space in our labs. This includes the TEST-NET prefixes 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, and the non-allocated prefix 128.66.0.0/16.

    Not included yet is a IPv6 address plan, which should also be considered an essential discipline for network training. Mastering IPv6 through my home labs is a personal priority of mine, so stay tuned for more on that.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#hardware-recommendations","title":"Hardware Recommendations","text":"

    The device used to install Proxmox should have at least two NICs:

    • One for vmbr0 and the management network roles described above
    • Another for lab VM access to your LAN

    Ideally, it would be better to have at least four NICs:

    • One for vmbr0
    • One for cluster communication
    • One for production VMs and CTs to access your LAN
    • One for lab VMs and CTs to access your LAN

    We'll expand on this setup in future labs, as well as upgrading your node with the necessary hardware, but for now we'll focus on a two NIC configuration.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#custom-mac-address-prefix","title":"Custom MAC Address Prefix","text":"

    By default, Proxmox uses unregistered and randomized MAC addresses for the virtual network devices for VMs and CTs, which are listed within the \"Hardware\" view for VMs and the \"Network\" view for CTs. There are called Locally Administered Addresses (LAAs).

    Used for server VMs and CTs, this doesn't seem to be an issue. However, I ran into and issue when installing VyOS on Proxmox where it wouldn't add all detected interfaces to the configuration because the the MAC addresses weren't Universally Administered Address (UAAs). It may also affect other network operating systems (NOSs) as well, but I haven't yet verified that.

    It won't prevent you from configuring and using VyOS on Proxmox, but it can help new users to have this functionality in place and the fix is easy: instead of using LAA MAC addresses, set a custom prefix that Promox will use as a UAA OUI for all network devices.

    To do this, click on the \"Datacenter\" your node is in, then click on \"Options\" and edit the \"MAC address prefix\" to be 00:50:56. This is the VMWare OUI used for network devices within their virtualization platforms, and VyOS (or any other OS) should properly recognize it.

    From now on all virtual network devices will be issued a UAA MAC address with the 00:50:56 OUI and a random suffix. For some labs I may have you configure specific MAC addresses for lab tasks, so maintaining consistency will be helpful.

    "},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/","title":"Initial Junos OS Configuration on a vSRX","text":"

    After installing vSRX in a VM, we\u2019re ready to perform the initial configuration. Log in as user root (no password required), and enter configuration mode with configure.

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-root-password","title":"Set root password","text":"

    Before making any changes to the factory-installed configuration, you will need to first set a password for the root user. Let\u2019s do that before making any other changes:

    1. set system root-authentication plain-text-password
    2. Enter secure password twice when prompted
    3. commit and-quit
    4. quit
    5. Log back into Junos OS using the new account credentials to verify
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#create-a-non-root-user","title":"Create a non-root user","text":"

    Using the root account for device operation is almost never a good idea, so next let\u2019s create a non-root user with all privileges using the local database:

    1. set system login user <user_name> full-name \"<full_name>\"
    2. set system login user <user_name> class super-user
    3. set system login user <user_name> authentication plain-text-password
    4. Enter secure password twice when prompted
    5. commit and-quit
    6. quit
    7. Log back into Junos OS using the new account credentials to verify
    8. Re-enter configuration mode with configure
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-management-interface","title":"Set management interface","text":"

    Every network device should have a management interface, ideally out-band-band from the rest of the interfaces, to securely operate the device. For the vSRX, it\u2019s the fxp0 interface. For now, let\u2019s have it get an address via DCHP so we can use that address to access the device from here via SSH:

    1. set interfaces fxp0 unit 0 family inet dhcp
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#enable-ssh-access","title":"Enable SSH access","text":"

    Instead of accessing vSRX using a console connection or hypervisor virtual terminal, we can now use SSH through the management interface. Enable it with:

    1. set system services ssh
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-host-name","title":"Set host name","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-domain-name","title":"Set domain name","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-dns-servers","title":"Set DNS servers","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-static-default-route-with-no-readvertise-option","title":"Set static default route with no-readvertise option","text":"

    You should be as specific about the route as possible. You can also use the no-readvertise option for the static route used for management traffic. This marks the route ineligible for readvertisement through routing policy.

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-time-zone","title":"Set time zone","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-ntp-servers","title":"Set NTP servers","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-rescue-configuration","title":"Set rescue configuration","text":"

    You can configure a single logical unit for the lo0 interface for each routing instance, and each logical unit associated with a given routing instance can have multiple configured IP addresses.

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#commit-changes","title":"Commit changes","text":"

    commit comment \"Initial configuration performed\"

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#verification","title":"Verification","text":"
    • Using the Proxmox console, check the management network interface IP address with run show dhcp client binding fxp0.0.

      eron@vsrx-r1> show dhcp client binding fxp0.0 IP address Hardware address Expires State Interface 172.16.0.110 a2:2f:9d:45:aa:2a 263 BOUND fxp0.0

    • Using the IP address above, log into the router with the new non-root user via an SSH client with ssh <user_name>@<ip_address>.

      PS C:\\Users\\eronl> ssh eron@172.16.0.110 Password: Last login: Tue Jun 6 02:16:18 2023 from 172.16.0.53 --- JUNOS 20.3R1.8 Kernel 64-bit XEN JNPR-11.0-20200908.87c9d89_buil eron@vsrx-r1>

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/","title":"Installing Juniper vSRX on Proxmox","text":"","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-1-download-a-vsrx-image-from-juniper","title":"Step 1: Download a vSRX Image From Juniper","text":"

    Unless you have a licensed copy of vSRX, you will need to download the trial version for home lab use from Juniper's website. And in order to do that, you must have an account and authorization to download trial software.

    If you already can do this, skip ahead to step two. Otherwise, perform the following tasks:

    • Log into or register for your Juniper account.
    • Request access to the trial version of vSRX by following these instructions.
    • Once your account is authorized by JTAC, download the trial version of vSRX here. For Proxmox VE, choose the vSRX KVM Appliance.
    • Download and save your trial license, but just hold onto this for now. It shouldn't be necessary for most functionality.
    ","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-2-upload-the-vsrx-image-to-a-proxmox-ve","title":"Step 2: Upload the vSRX Image to a Proxmox VE","text":"

    Next you'll need to upload the vSRX trial image to a Proxmox VE machine in preparation for installation. In this case I did scp junos-vsrx3-x86-64-20.3R1.8.qcow2 <user>@<pve>:~ to copy the file to my Proxmox VE user's home folder, which is good enough for this step.

    Verify the file was successfully transferred, and we'll revisit this again after the next step.

    ","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-3-create-the-virtual-machine","title":"Step 3: Create the Virtual Machine","text":"

    vSRX will run as a VM on Proxmox VE, but it's not ready out of the box. You'll first have to create the VM configuration within Proxmox VE, including naming and hardware settings.

    The minimum requirements for running vSRX in KVM are

    • 2 CPUs
    • 4 GB RAM
    • 20 GB storage

    qm importdisk <vm-id> junos-vsrx3-x86-64-20.3R1.8.qcow2 local-lvm

    ","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-4-verify-vm-bootup-and-initial-login","title":"Step 4: Verify VM Bootup and Initial Login","text":"","tags":["Juniper","Proxmox"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/","title":"Initial RouterOS Configuration Best Practices [DRAFT]","text":"

    After installing RouterOS in a VM, we\u2019re ready to perform the initial configuration.

    Log in as the user admin, without a password.

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#secure-the-admin-user","title":"Secure the Admin User","text":"

    Using the default account for device operation is almost never a good idea, so let\u2019s create a new admin user with all privileges and remove the vyos account.

    1. set system login user <user_name> full-name \"<full_name>\"
    2. set system login user <user_name> class super-user
    3. set system login user <user_name> authentication plain-text-password
    4. Enter secure password twice when prompted
    5. commit
    6. quit
    7. Log back into VyOS using the new account credentials to verify
    8. Re-enter configuration mode with configure
    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#configure-a-management-interface","title":"Configure a Management Interface","text":"

    Every network device should have a management interface, ideally out-band-band from the rest of the interfaces, to securely operate the device. For VyOS, let's standardize on the eth0 interface and have it get an address via DCHP so we can use that address to access the device via SSH.

    set interfaces fxp0 unit 0 family inet dhcp\n
    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#enable-ssh-access","title":"Enable SSH access","text":"

    Instead of accessing vSRX using a console connection or hypervisor virtual terminal, we can now use SSH through the management interface. Enable it with:

    1. set system services ssh
    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-host-name","title":"Set host name","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-domain-name","title":"Set domain name","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-dns-servers","title":"Set DNS servers","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-static-default-route-with-no-readvertise-option","title":"Set static default route with no-readvertise option","text":"

    You should be as specific about the route as possible. You can also use the no-readvertise option for the static route used for management traffic. This marks the route ineligible for readvertisement through routing policy.

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-time-zone","title":"Set time zone","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-ntp-servers","title":"Set NTP servers","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-rescue-configuration","title":"Set rescue configuration","text":"

    You can configure a single logical unit for the lo0 interface for each routing instance, and each logical unit associated with a given routing instance can have multiple configured IP addresses.

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#commit-changes","title":"Commit changes","text":"

    commit comment \"Initial configuration performed\"

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#verification","title":"Verification","text":"
    • Using the Proxmox console, check the management network interface IP address with run show dhcp client binding fxp0.0.

      eron@vsrx-r1> show dhcp client binding fxp0.0 IP address Hardware address Expires State Interface 172.16.0.110 a2:2f:9d:45:aa:2a 263 BOUND fxp0.0

    • Using the IP address above, log into the router with the new non-root user via an SSH client with ssh <user_name>@<ip_address>.

      PS C:\\Users\\eronl> ssh eron@172.16.0.110 Password: Last login: Tue Jun 6 02:16:18 2023 from 172.16.0.53 --- JUNOS 20.3R1.8 Kernel 64-bit XEN JNPR-11.0-20200908.87c9d89_buil eron@vsrx-r1>

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/","title":"Installing MikroTik RouterOS on Proxmox [DRAFT]","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#introduction","title":"Introduction","text":"

    To enable our subnets on Linux bridges to communicate within our labs across increasingly complex network topologies, we have to add Layer 3 and 4 capabilities to our setup. To do this, we're going incorporate MikroTik's RouterOS into Proxmox and serve in this capacity.

    If you're not familiar with RouterOS and why it's a fantastic platform to learn and use in your networks, check out this blog post where we cover what it is, its background and architecture, and its advantages for both practice labs and production networks.

    In this lab, we're going to cover the process to install a RouterOS virtual machine (VM) in Proxmox and prepare it for use as a full-featured router/firewall/vpn in our networks.

    ","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#step-1-create-a-mikrotik-account","title":"Step 1: Create a MikroTik Account","text":"

    RouterOS is available to use for free, but with several caveats that you must be aware of:

    1. Every instance of RouterOS you use must still be registered via a MikroTik account, even the free version.

    2. The free version is limited to

    ","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#step-2-adding-routeros-as-an-image-in-proxmox","title":"Step 2: Adding RouterOS as an Image in Proxmox","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#option-a-use","title":"Option A: Use","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#step-3-creating-and-configuring-a-vm-for-routeros","title":"Step 3: Creating and Configuring a VM for RouterOS","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#step-3-installing-the-routeros-image-on-a-vm","title":"Step 3: Installing the RouterOS Image on a VM","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#conclusion-and-next-lab","title":"Conclusion and Next Lab","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/static-routing-between-subnets-with-routeros/","title":"Static Routing Between Subnets with RouterOS [DRAFT]","text":"","tags":["MikroTik","RouterOS","Linux","Proxmox"]},{"location":"labs/networks/mikrotik/static-routing-between-subnets-with-routeros/#lab-setup","title":"Lab Setup","text":"

    For this lab, we'll need the following to be pre-configured:

    • host1 is on vmbr1 and has an IPv4 address of 10.0.1.10/24
    • host2 is on vmbr1 and has an IPv4 address of 10.0.1.11/24
    • host3 is on vmbr1 and has an IPv4 address of 10.0.2.10/24
    • host4 is on vmbr1 and has an IPv4 address of 10.0.2.11/24
    • routeros-r1 is on vmbr1 and has an IPv4 address on ether1 of 10.0.1.1/24
    • routeros-r2 is on vmbr1 and has an IPv4 address on ether1 of 10.0.2.1/24
    ","tags":["MikroTik","RouterOS","Linux","Proxmox"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/","title":"Initial VyOS Configuration Best Practices [DRAFT]","text":"

    After installing VyOS in a VM, we\u2019re ready to perform the initial configuration.

    Log in as the user vyos and the password you created during installation (default is vyos), and enter configuration mode with configure.

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#create-a-unique-admin-user","title":"Create a Unique Admin User","text":"

    Using the default account for device operation is almost never a good idea, so let\u2019s create a new admin user with all privileges and remove the vyos account.

    1. set system login user <user_name> full-name \"<full_name>\"
    2. set system login user <user_name> class super-user
    3. set system login user <user_name> authentication plain-text-password
    4. Enter secure password twice when prompted
    5. commit
    6. quit
    7. Log back into VyOS using the new account credentials to verify
    8. Re-enter configuration mode with configure
    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#configure-a-management-interface","title":"Configure a Management Interface","text":"

    Every network device should have a management interface, ideally out-band-band from the rest of the interfaces, to securely operate the device. For VyOS, let's standardize on the eth0 interface and have it get an address via DCHP so we can use that address to access the device via SSH.

    set interfaces fxp0 unit 0 family inet dhcp\n
    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#enable-ssh-access","title":"Enable SSH access","text":"

    Instead of accessing vSRX using a console connection or hypervisor virtual terminal, we can now use SSH through the management interface. Enable it with:

    1. set system services ssh
    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-host-name","title":"Set host name","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-domain-name","title":"Set domain name","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-dns-servers","title":"Set DNS servers","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-static-default-route-with-no-readvertise-option","title":"Set static default route with no-readvertise option","text":"

    You should be as specific about the route as possible. You can also use the no-readvertise option for the static route used for management traffic. This marks the route ineligible for readvertisement through routing policy.

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-time-zone","title":"Set time zone","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-ntp-servers","title":"Set NTP servers","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-rescue-configuration","title":"Set rescue configuration","text":"

    You can configure a single logical unit for the lo0 interface for each routing instance, and each logical unit associated with a given routing instance can have multiple configured IP addresses.

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#commit-changes","title":"Commit changes","text":"

    commit comment \"Initial configuration performed\"

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#verification","title":"Verification","text":"
    • Using the Proxmox console, check the management network interface IP address with run show dhcp client binding fxp0.0.

      eron@vsrx-r1> show dhcp client binding fxp0.0 IP address Hardware address Expires State Interface 172.16.0.110 a2:2f:9d:45:aa:2a 263 BOUND fxp0.0

    • Using the IP address above, log into the router with the new non-root user via an SSH client with ssh <user_name>@<ip_address>.

      PS C:\\Users\\eronl> ssh eron@172.16.0.110 Password: Last login: Tue Jun 6 02:16:18 2023 from 172.16.0.53 --- JUNOS 20.3R1.8 Kernel 64-bit XEN JNPR-11.0-20200908.87c9d89_buil eron@vsrx-r1>

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/","title":"Installing VyOS on Proxmox","text":"","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#introduction","title":"Introduction","text":"

    To enable our subnets on Linux bridges to communicate within our labs across increasingly complex network topologies, we have to add Layer 3 and 4 capabilities to our setup. To do this, we're going incorporate VyOS into Proxmox and serve in this capacity.

    If you're not familiar with VyOS and why it's a fantastic platform to learn and use in your networks, check out this blog post where we cover what it is, its background and architecture, and its advantages for both practice labs and production networks.

    In this lab, we're going to cover the process to install a VyOS virtual machine (VM) in Proxmox and prepare it for use as a full-featured router/firewall/vpn in our networks.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#step-1-adding-vyos-as-an-image-in-proxmox","title":"Step 1: Adding VyOS as an Image in Proxmox","text":"

    To create a VM in Proxmox, you'll first need an \"image\" file of the software that will run as the operating system for your VM. This can come in different formats, but it often has a .iso file extension. Let's get the VyOS image we'll use for our router/firewall VMs.

    Go to https://vyos.io and look for the \"Download\" link in the main menu. Select \u201cFree Download\u201d from the dropdown menu, and look for the list item that says \u201cvyos-rolling-latest.iso.\u201d Instead of downloading it, however, just copy the link URL.

    Info

    A quick explanation on the VyOS release models, excerpted from the project's FAQs:

    VyOS is split into two branches: long term support and rolling release.

    • The rolling release branch (git branch \u201ccurrent\u201d) includes the latest code from maintainers and all contributions from community members are merged into it. It\u2019s meant for testing and home lab/non-critical router use and is not guaranteed to be stable.

    • Long term support branches are periodically split from the current branch. They are stable, and only proven, strictly compatible changes are merged or backported into it. Use this for production networks.

    For our home lab use, we will be using the rolling releases, and in a later video, we'll cover how to regularly update to the latest rolling release as new features become available.

    Go to the \u201clocal\u201d storage view of your Proxmox hypervisor and click on \"ISO Images\". Click on the \u201cDownload from URL\u201d button and paste the link URL we just copied into the \"URL\" field of the dialog box.

    Click the \u201cQuery URL\u201d button to verify the file exists and click the \u201cDownload\u201d button to save the latest VyOS rolling release ISO file locally on your hypervisor. Keep the file name the same.

    Whenever we need to create a new VyOS VM, we'll be able to easily use this local image already stored in Proxmox. Let's do that now.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#step-2-creating-and-configuring-a-vm-for-vyos","title":"Step 2: Creating and Configuring a VM for VyOS","text":"

    The next step is to create and configure the actual VM that VyOS will run within. For this we'll model the VM after a physical router device with five ports.

    On the top-right of the Proxmox UI, click the \u201cCreate VM\u201d button to set up a blank VM configuration. This will bring up a dialog box and walk you through the initial VM setup process:

    • On the \"General\" tab, name your VM vyos-r1 in the \"Name\" field, then click the \"Next\" button.

    • On the \"OS\" tab, select Use CD/DVD disc image file (iso) with \"Storage\" as local and \"ISO Image\" as vyos-rolling-latest.iso. Click the \"Next\" button.

    • On the \"System\" tab, select VirtIO SCSI single for \"SCSI Controller\" if available (use default otherwise) and check the \"Qemu Agent\". Click the \"Next\" button.

    • On the \"Disks\" tab, change \u201cDisk size (GiB)\u201d to 10, and leave the rest as the defaults. Click the \"Next\" button.

    • On the \"CPU\" tab, use 1 for the \"Sockets and Cores\" fields. Click the \"Next\" button.

    • On the \"Memory\" tab, use 1024 for the \u201cMemory (MiB)\u201d field. Click the \"Next\" button.

    • On the \"Network\" tab, ensure \u201cNo network device\u201d is unchecked, select vmbr0 for Bridge, uncheck \"Firewall\", select VirtIO (paravirtualized) for \"Model\", and use auto for \"MAC address\". Click the \"Next\" button.

    • On the \"Confirm\" tab, review all your settings and click the \"Finish\" button to close the dialog box. The VM is now created, but there's more configuration to complete.

    Select the vyos-r1 VM and open the \"Hardware\" configuration. A router isn\u2019t very useful with just one interface, so let\u2019s add four more. Within the hardware list, click the \"Add\" drop-down button and select \u201cNetwork Device.\u201d

    Using the same configuration as before on the \"Network\" tab above, create four additional network devices, so our router will have five total ports to work with.

    Well done; you've just modeled a real-world router as a VM!

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#step-3-installing-the-vyos-image-on-a-vm","title":"Step 3: Installing the VyOS Image on a VM","text":"

    Now we\u2019re ready to install VyOS onto our VM. Click the \u201cStart\u201d button to power on the VM and boot up the VyOS installer. When VyOS is finished booting, enter the username vyos and password vyos to log in.

    The VyOS installer is also a live demo instance of a running router, but we want to get it installed in our VM. At the command prompt, type install image to begin the installation.

    The installation script will begin prompting you to for each step of the process. The options will be in parenthesis and separated with a slash, such as (Yes/No), and the default choice will also appear in square brackets, such as [Yes]. To accept the default choice, simply press the \"Enter\" key, or type out another option then press \"Enter\". At the first question prompt, press \"Enter\" to continue.

    The next prompt asks how to partition the VM drive used to store VyOS. Press \"Enter\" to accept the \"Auto\" method.

    There will only be one drive available, so press \"Enter\" to select this drive to install VyOS on. You will again be prompted to confirm any existing data on the drive could be destroyed. This time, type Yes and press \"Enter\" to continue.

    Next you will be asked what size the root partition should be. Press \"Enter\" to accept the default size.

    The VyOS filesystem will be created on the disk, then you will be prompted on what to name this VyOS installation. Press \"Enter\" to accept the default name.

    Next, you will be prompted to select which configuration template to start with. Press \"Enter\" to accept the default configuration.

    The next two prompts will be to create and confirm the password for the initial administrator user, vyos. Select something secure and document it somewhere safe, as you\u2019ll need this to log into VyOS each time, then press \"Enter\" to continue.

    Finally, the last prompt will ask which drive should be modified for the boot partition. Press \"Enter\" to access the default drive.

    At this point, VyOS is now installed. Type reboot and confirm to proceed with rebooting the VM by typing y and pressing \"Enter\". When the VM reboots, you'll be ready to perform the initial configuration.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#conclusion-and-next-lab","title":"Conclusion and Next Lab","text":"

    In this lab we created a VM and installed an operating system on it. Well done!

    You probably noticed there were a lot more steps to do this compared to creating the CTs we used for our network hosts. We'll detail the differences in the server labs section later, but for now, this process is enough to get good at.

    We'll be creating many router VMs, so be sure to become comfortable with this process. Feel free to practice performing the process multiple times, deleting the VM after each installation.

    We've still got work to do on our router VM before we can use it in our network, so once you're ready to move on, head over to the Initial VyOS Configuration Best Practices lab.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/servers/overview/","title":"Server Labs Overview","text":""},{"location":"tags/","title":"Content Index","text":"

    Use this page to find content by tag. Note that content may be marked with multiple tags.

    "},{"location":"tags/#juniper","title":"Juniper","text":"
    • Initial Junos OS Configuration on a vSRX
    • Installing Juniper vSRX on Proxmox
    "},{"location":"tags/#linux","title":"Linux","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#mikrotik","title":"MikroTik","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#proxmox","title":"Proxmox","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Installing Juniper vSRX on Proxmox
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    • Installing VyOS on Proxmox
    "},{"location":"tags/#routeros","title":"RouterOS","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#vyos","title":"VyOS","text":"
    • Initial VyOS Configuration Best Practices
    • Installing VyOS on Proxmox
    "},{"location":"blog/archive/2023/","title":"2023","text":""},{"location":"blog/category/announcements/","title":"Announcements","text":""}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Welcome to Our Home Labs!","text":"

    There isn't too much to see here yet, but head over to the network labs to check out what we've developed so far or read a few articles on our blog to learn more about this site and what we have planned.

    "},{"location":"about/","title":"About This Site","text":"

    This website is dedicated to documenting our home labs. When we started planning out our home labs and making content, we thought it'd be great to have a place we could organize and share our materials in a way that made it easy for our audience to follow along, at their own pace.

    "},{"location":"tags/","title":"Content Index","text":"

    Use this page to find content by tag. Note that content may be marked with multiple tags.

    "},{"location":"tags/#juniper","title":"Juniper","text":"
    • Initial Junos OS Configuration on a vSRX
    • Installing Juniper vSRX on Proxmox
    "},{"location":"tags/#linux","title":"Linux","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#mikrotik","title":"MikroTik","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#proxmox","title":"Proxmox","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Installing Juniper vSRX on Proxmox
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    • Installing VyOS on Proxmox
    "},{"location":"tags/#routeros","title":"RouterOS","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#vyos","title":"VyOS","text":"
    • Initial VyOS Configuration Best Practices
    • Installing VyOS on Proxmox
    "},{"location":"blog/the-telecom-craft-homelabs-site-has-launched/","title":"The Telecom Craft Homelabs Site has Launched!","text":"

    Over the past few months, starting with our fiber optic home lab, we've been slowly making plans and laying the foundation for a broad collection of ICT home lab content. We wanted a place to organize our own learning materials and make that content available as a contribution back to the home lab community that we've learned so much from.

    We're pleased to share the first attempt at this goal with you here at labs.telecomcraft.com, where we practice the discipline of learning in public.

    On this site, we'll publish step-by-step lab exercises on topics such as fiber optics, networks, servers, and security, as well as quick references on common knowledge that we like to have handy and think you may, too. All content will be open, licensed under the Creative Commons, and we'll be planning and publishing new material with ideas and feedback from you, our audience.

    The primary goal of this site is to provide high-quality content that is both technically accurate and accessible so that you can follow along and replicate the steps without struggling too much. We always appreciate great documentation and tutorials and want to provide that level of positive experience to you, too.

    Be sure to check our blog regularly for announcements and updates, and subscribe to our YouTube channel and LinkedIn page for related content and activities.

    "},{"location":"diagrams/notes/","title":"Notes","text":"

    Diagram notes

    "},{"location":"labs/fiber/patch-cords-and-connectors/","title":"Fiber Optic Patch Cords and Connectors","text":""},{"location":"labs/fiber/patch-cords-and-connectors/#introduction","title":"Introduction","text":"

    So the role of any network cable is to connect devices, right? They transmit data to allow the devices to communicate, and more and more often, they also transmit electricity to power the device as well.

    Patch cords, specifically, provide a temporary link between multiple devices or other cables It\u2019s considered temporary because it can easily connected and disconnected (REMOVE UTP CABLE), which no one appreciates.

    In this lab we\u2019re going to take a close look at patch cords and their connectors. As we saw in the previous episode, they can be used to build simple\u2014but complete\u2014fiber optic networks. So this is a great place to start as we develop the lab.

    !!! tip\n\nAddress term cord vs cable\n
    "},{"location":"labs/fiber/patch-cords-and-connectors/#tools-and-materials-needed","title":"Tools and Materials Needed","text":"
    • Simplex and duplex LC-UPC OS2 cords
    • Short UTP cables from E1
    • New duplex LC-UPC cord
    • Duplex LC-UPC OM4 cord
    • Duplex LC-UPC OM5 cord
    • Simplex SC-UPC OS2 cord
    • Simplex SC-APC OS2 cord
    • Simplex LC-UPC to ST-UPC OS2 cord
    • Simplex LC-UPC to FC-UPC OS2 cord
    • VFL
    "},{"location":"labs/fiber/patch-cords-and-connectors/#step-1-examine-the-utp-patch-cord","title":"Step 1: Examine the UTP Patch Cord","text":"
    • I had to take our tiny network here offline to talk about patch cords we\u2019ve been using to enable my laptop to connect to the router.

    • Examine the UTP patch cord from E1, and review its components and common roles in networks.

      • Components
        • Copper strands
        • Coating (color-coded)
        • Boot
        • Crimping
      • Roles
        • Internet WAN link
        • Switch links to PCs, cameras, or Wi-Fi radios
        • PoE delivery
    "},{"location":"labs/fiber/patch-cords-and-connectors/#step-2-examine-the-fiber-optic-patch-cords","title":"Step 2: Examine the Fiber Optic Patch Cords","text":"

    Review its components and compare/contrast to the UTP patch cord. - Review components - 9um SM fiber and 125um cladding - 250um primary buffer coating - 900um tight buffer coating - PVC jacket and labeling - Ferrule - Crimp - Boot - Review roles - Internet WAN link - Switch links to PCs, cameras, or Wi-Fi radios - Non-conductive, so no PoE, but dielectric nature has advantages too - There are composite cables that can carry electric with fiber. - Discuss durability and damage prevention

    "},{"location":"labs/fiber/patch-cords-and-connectors/#step-3-identify-and-examine-the-types-of-optical-fibers-and-connectors","title":"Step 3: Identify and Examine the Types of Optical Fibers and Connectors","text":"
    • Duplex LC-UPC OM4 cords
    • Although it looks similar to the previous cord and has the same LC-UPC connector, it\u2019s using MM fiber instead of SM. For a variety of reasons, I prefer SM over MM, but we\u2019ll get to that in a minute.
    • Duplex LC-UPC OM5 cords
    • MM colors for boots and connectors (mention FOCIS), speeds
    • Simplex SC-UPC OS2 cords
    • Simplex SC-APC OS2 cords
    • Simplex LC-UPC to ST-UPC OS2 cords
    • Simplex LC-UPC to FC-UPC OS2 cords
    • Now that we\u2019ve covered the general role of patch cords, as well as the common types of cables and connectors used, we\u2019ll wrap things up with a few considerations for deciding which patch cords to use.
    "},{"location":"labs/fiber/patch-cords-and-connectors/#step-4-consider-singlemode-vs-multimode-tradeoffs","title":"Step 4: Consider Singlemode vs Multimode Tradeoffs","text":"

    One of the first things to consider is which type of fiber to use for each cable: singlemode or multimode?

    As you build out your lab, this becomes an increasingly important question. I\u2019ll cover this topic more in-depth in a later episode, but for now, here are some rules of thumb.

    • Rule #1: Determine your distance requirements.** Both SM and MM can go further than TP, but SM can go way further than MM. In your lab, this is generally not a problem, but if you plan to simulate cable plants over 1Km, like I will, SM is needed. Be careful because there are multiple versions of both MM and SM, each with important characteristics!

    • Rule #2: Determine your device requirements.** Devices can also define constraints on your cabling decisions based on their transceiver specifications. Historically, because most ISP and DC cabling is shorter and MM fiber and transceivers were cheaper, devices standardized on MM. That\u2019s beginning to change as device costs come down while speeds are increasing, and now network designers see long-term advantage of SM cable plants, however. You can find transceivers that will operate with both MM and SM fiber, giving you flexibility. But as always, study your tech specs carefully!

    • Rule #3: Determine your fiber application requirements.** Depending on your overall lab plans and network needs, which fiber you use will constrain how you can then use it. If you\u2019re experimenting with attenuation, for example, SM generally has lower loss than MM. One of my objectives is to study WDM with my lab, and for that, SM\u2014specifically G652\u2014is the best choice.

    "},{"location":"labs/fiber/patch-cords-and-connectors/#step-5-consider-connector-choice-tradeoffs","title":"Step 5: Consider Connector Choice Tradeoffs","text":"
    • Next up is considering which type of connector to use for your cable. We\u2019ve reviewed some of the most common options in this episode: an SC or LC form factor, and a UPC or APC polish. Here the options can get a bit more complicated, but the same evaluation process for fiber is useful.
    • In this case, distance isn\u2019t really an factor, but your device and application requirements still define your constraints.
    • Transceivers in ISP and DC environments are still generally LC-UPC, so that is straightforward. Between devices, however, such as in patch panels, you might want to consider your port density and rack space constraints, as well as overall cable management standards.
    • PON networks, however, utilize SC-APC for much of the ISP and OSP. APC has reduced attenuation, and SC form factors are easier to handle, so the application determines the connector.
    • In any case, remember that you have flexibility through the use of mixed-connector cables as well as adapters within the cable plant to implement the right connector at each termination point.
    • As a note, there are many other specialized connectors that have their advantages, such as multi-fiber MPOs and highly compact MDCs. I plan to cover some of these later in the lab.
    "},{"location":"labs/fiber/patch-cords-and-connectors/#step-6-consider-buy-vs-build-tradeoffs-of-patch-cords","title":"Step 6: Consider Buy-vs-Build Tradeoffs of Patch Cords","text":"

    Before we wrap up, I wanted to quickly talk about the question of \u201cbuy vs build.\u201d Going back to our original UTP patch cords, many people are comfortable making these out of the components: bulk UTP cable, connector boots, and RJ-45s. They can be made on-demand, can be more economical, and made to the exact lengths you need. - So what about fiber? At a high-level, all of those advantages for making your own patch cords apply. But it is more complicated due to skills, tools, and materials needed for preparing and terminating the cables. As a result, most experienced technicians would not recommend it. - There are impressive advances in mechanical connectors and splice-on-connectors, and I\u2019d like to explore this later in the lab, but I personally recommend you purchase your patch cords whenever possible. I certainly do!

    "},{"location":"labs/fiber/patch-cords-and-connectors/#conclusion","title":"Conclusion","text":"

    We now covered the roles, types, and tradeoffs of fiber patch cords. In some cases there are no easy or right answers on what option to use. In each case, research your requirements; understand your distance, device, and application constraints; and be consistent in your design. And above all, use your lab to experiment and learn all you can. That\u2019s what it\u2019s for!

    !!! question\n\nSo what patch cords do you use and why?\n

    In the next lab in this series, we\u2019ll take a look at fiber optic connectors and adapters, which will allow us to interconnect patch cords between our devices. This is where the fun really begins.

    Again, if you\u2019re new to fiber optics and like what you saw here, head over to the FOA website and check out their Fiber U courses and textbooks.

    "},{"location":"labs/fiber/safety-tips/","title":"Safety Tips","text":"

    You should always be careful when working with fiber optics. Before you get started in the lab, here are some important safety tips:

    • Wear eye protection when necessary,
    • Never look into powered cables or optical equipment,
    • Do not eat or drink while working,
    • Properly dispose of all fiber scraps, and
    • Clean your work area thoroughly when finished.

    Even in your home lab, remember to play it safe to keep working with fiber fun.

    "},{"location":"labs/networks/overview/","title":"Network Labs Overview","text":"

    Welcome to the Telecom Craft Network Labs! We're only just getting started, but there are already some labs available in the General section, beginning with Initial Proxmox Network Configuration.

    "},{"location":"labs/networks/apnic/routing-labs/","title":"Overview","text":""},{"location":"labs/networks/apnic/mikrotik/overview/","title":"MikroTik Hands-On Exercises","text":""},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/","title":"Cloning a Network Host Template","text":"

    In the Creating a Network Host Template in Proxmox lab, you learned how to create a custom template of Ubuntu Linux to use as a network host for labs.

    In this lab, you'll learn how to clone and configure that template so it's ready to easily deploy new network hosts in your labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/#step-1-create-the-cloned-network-host","title":"Step 1: Create the Cloned Network Host","text":"
    • To clone the template, select the host0 CT template in the list to bring up that CT's views.
    • Click the More drop-down button at the top-right of the Proxmox VE window, then click Clone.
    • Select the target node (if you have a Proxmox VE cluster), otherwise leave the default selected.
    • Type host1 as the Hostname to identify this node.
    • Select Full Clone as the Mode to create a full and unlinked copy of the template.
    • Click the Clone button to proceed.

    Clone Dialog

    Once the cloning is done, you will see a new CT named host1 in the list.

    • Select the host1 CT and start it up.
    • Using the Console view, log in with the same non-root administrator account as you used for host0.
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/#step-2-configure-the-cloned-network-host","title":"Step 2: Configure the Cloned Network Host","text":"

    Before using the new network host in labs, there are several changes that have to be made to make it different from the template. The hostname, machine ID, and network interface's MAC address are changed as part of the cloning process itself.

    However there is one crucial change that you'll have to manually make for each new host after the clone is created: generating new SSH keys. This is an essential step for any VM or CT, so always verify this was properly done.

    First ensure no files starting with ssh_host exist:

    ls /etc/ssh\n

    Then generate new key pairs:

    sudo dpkg-reconfigure openssh-server\n

    Check again to confirm the creation of the new key pairs:

    ls /etc/ssh\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/cloning-a-network-host-template-in-proxmox/#step-3-create-three-more-cloned-network-hosts","title":"Step 3: Create Three More Cloned Network Hosts","text":"

    Now your network host is ready for use. Remember to always complete the steps above when creating new hosts. Before we wrap this lab up, you'll get some more practice.

    Use the steps above to create three more hosts named host2, host3, and host4, which we'll be using in the next lab, Connecting and Configuring Network Hosts.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/","title":"Connecting and Configuring Network Hosts in Proxmox","text":"

    Imagine having two physical Linux servers, each with a single network adapter. If you interconnect the two servers with a patch cord, and configure the network adapters so they can communicate, what will you have?

    A simple, but fully-functional network. And that's where you'll begin your learning on building networks, which is all about connecting hosts together.

    In this lab, we're going to directly connect our network hosts together virtually by adding them to a Linux bridge and configuring them with basic network settings. No additional routers, switches, or firewalls will be necessary at this point; just the built-in functionality of Linux and Proxmox.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-1-create-a-linux-bridge-for-lab-connectivity","title":"Step 1: Create a Linux Bridge for Lab Connectivity","text":"

    A Linux bridge is like a basic switch integrated into the operating system that supports things like STP and VLAN trunking, and allows virtual machines and containers to communicate within hypervisors, like Proxmox.

    When installing Proxmox, a Linux bridge named vmbr0 will be created to connect the hypervisor to the outside world. In my own lab setup, I use vmbr0 to connect the Proxmox cluster and all VMs and CTs to my management subnet. By default, your CTs and Proxmox itself are running on that bridge.

    For our labs at this point, however, we have no need for our CTs to reach outside the lab subnet we'll be creating, so we'll create a second bridge just for our hosts to connect and communicate across. This provides a self-contained Layer 2 broadcast domain we can completely control, just like having a dedicated hardware switch with only your lab links connected.

    1. At the top of the Proxmox resource tree, select the Proxmox node your lab is running within and then select the System > Network view of the content panel.
    2. At the top-left of the network device table, click the Create dropdown button and select Linux Bridge.
    3. In the dialog box, ensure the Name is vmbr1 and Autostart is checked, then click the Create button.
    4. At the top of the network device table, click the Apply Configuration button and the new bridge will be enabled.
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-2-connecting-hosts-to-the-lab-bridge","title":"Step 2: Connecting Hosts to the Lab Bridge","text":"

    With our lab bridge created, we'll need to now change the bridge setting on each host's interface from vmbr0 to vmbr1. Think of this like moving a host's patch cord from one hardware switch to another.

    We'll also be changing each host's MAC address on its interface to match up with the interfaces used in our labs. This helps to ensure your results are consistent with the lab instructions. Use the table below for the MAC address assignments:

    Host MAC Address host1 00:50:56:94:55:70 host2 00:50:56:AD:0E:33 host3 00:50:56:16:30:C7 host4 00:50:56:AD:24:4A

    For each host, perform the following:

    1. From the Proxmox Web UI, select the CT in the resource tree and select the Network content panel.
    2. Select the network device
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-3-configuring-hosts-to-communicate-across-the-bridge","title":"Step 3: Configuring Hosts to Communicate Across the Bridge","text":"

    With our hosts all added to the same bridge, which by default is also the same broadcast domain, they will be able to communicate once they obtain IP address configurations.

    For this lab, we will be using the 10.0.1.0/24 IPv4 subnet for the lab network. Because our network devices are set to static addresses, we'll have to manually assign the right address to the right host. Use the table below for the IP address assignments:

    Host IPv4 Address host1 10.0.1.1/24 host2 10.0.1.2/24 host3 10.0.1.3/24 host4 10.0.1.4/24

    Within each host's Network settings in Proxmox, configure the eth0 network device's IPv4 setting to the respective address in the table above and verify the correct assigned address has been configured:

    sudo ip addr show eth0\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/#step-3-confirm-host-communication-across-the-bridge","title":"Step 3: Confirm Host Communication Across the Bridge","text":"

    At this point, all hosts should be connected and reachable, or \"up.\" As a best practice, always verify this.

    The most common method is to use the ping command, so let's use host1 to test connectivity to the other three hosts. From host1, check to see if host2 is available:

    sudo ping -c4 10.0.1.2\n

    Our ping response should be:

    PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.\n64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.069 ms\n64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.035 ms\n64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=0.035 ms\n64 bytes from 10.0.1.2: icmp_seq=4 ttl=64 time=0.036 ms\n\n--- 10.0.1.2 ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 3071ms\nrtt min/avg/max/mdev = 0.035/0.043/0.069/0.014 ms\n

    Again from host1, check to see if host3 is available:

    sudo ping -c4 10.0.1.3\n

    Our ping response should be:

    PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.\n64 bytes from 10.0.1.3: icmp_seq=1 ttl=64 time=0.118 ms\n64 bytes from 10.0.1.3: icmp_seq=2 ttl=64 time=0.038 ms\n64 bytes from 10.0.1.3: icmp_seq=3 ttl=64 time=0.037 ms\n64 bytes from 10.0.1.3: icmp_seq=4 ttl=64 time=0.036 ms\n\n--- 10.0.1.3 ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 3077ms\nrtt min/avg/max/mdev = 0.036/0.057/0.118/0.035 ms\n

    Again from host1, check to see if host4 is available:

    sudo ping -c4 10.0.1.4\n

    Our ping response should be:

    PING 10.0.1.4 (10.0.1.4) 56(84) bytes of data.\n64 bytes from 10.0.1.4: icmp_seq=1 ttl=64 time=0.099 ms\n64 bytes from 10.0.1.4: icmp_seq=2 ttl=64 time=0.029 ms\n64 bytes from 10.0.1.4: icmp_seq=3 ttl=64 time=0.034 ms\n64 bytes from 10.0.1.4: icmp_seq=4 ttl=64 time=0.026 ms\n\n--- 10.0.1.4 ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 3068ms\nrtt min/avg/max/mdev = 0.026/0.047/0.099/0.030 ms\n

    While ping is an essential tool for network testing, when you are scanning subnets or looking for more information from hosts (such as what ports are open), use nmap. Let's test host connectivity again from host1, using nmap this time:

    nmap -sn 10.0.1.0/24\n

    Our network scan should be:

    Starting Nmap 7.80 ( https://nmap.org ) at 2023-06-21 11:15 UTC\nNmap scan report for 10.0.1.1\nHost is up (0.00034s latency).\nNmap scan report for 10.0.1.2\nHost is up (0.00031s latency).\nNmap scan report for 10.0.1.3\nHost is up (0.00021s latency).\nNmap scan report for 10.0.1.4\nHost is up (0.00016s latency).\nNmap done: 256 IP addresses (4 hosts up) scanned in 15.91 seconds\n

    With one command, we can tell nmap to scan the entire /24 subnet and report back the status of every host, including host1.

    Question

    Practice performing ping and nmap tests between the four hosts to get comfortable with these essential tools. Which approach for network discovery do you think is better?

    Well done! We have built an entire network of Linux hosts that can communicate with each other. In the next lab, Exploring Bridges, Subnets, and Broadcast Domains in Proxmox, we will begin exploring our network to better understand how everything works together.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/","title":"Creating a Network Host Template in Proxmox","text":"

    For a long time, network simulators like Packet Tracer and GNS3 would provide a very basic network host such as VPCS, which could only do a very limited subset of network functions such as serving as a DHCP client and responding to pings.

    But the role of network hosts in your labs can become capable of so much more functionality by using real operating systems such as Linux. Using them offers an opportunity to not only become more familiar with real hosts, but gain a deeper understanding into networking fundamentals as well.

    In addition, because nearly every network operating system (NOS) is built on Linux, understanding the underlying networking capabilities of the Linux kernel and all the included tools in a Linux host provide insights into how routers, switches, and firewalls work.

    In this lab we're going to create an Ubuntu Linux \"template\" inside Proxmox VE that can be cloned and used as powerful network hosts to interact with inside our network labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-1-download-ubuntu-2204-lxc-template-onto-a-proxmox-ve-node","title":"Step 1: Download Ubuntu 22.04 LXC Template Onto a Proxmox VE Node","text":"

    A big advantage of Proxmox for creating labs is the availability of Linux Containers (LXC), a lightweight way to create isolated instances of Linux that are much more efficient than using full virtual machines. The Proxmox UI makes it extremely easy to install and manage containers, so that's what we'll do here.

    • In the Proxmox VE tree, select the local storage view, and select the CT Templates submenu item.
    • At the top of the view, click the Templates button and search for ubuntu-22.04-standard in the search box.
    • Select that item in the list and click the Download button to save that template to your Proxmox VE storage.

    Screenshot

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-2-create-a-proxmox-ct-using-the-ubuntu-lxc-template","title":"Step 2: Create a Proxmox CT Using the Ubuntu LXC Template","text":"

    With the Ubuntu 22.04 LXC template downloaded, we can now create a container in Proxmox (abbreviated to CT) using this template. Click the Create CT button at the top-right of the Proxmox VE window to get started.

    • On the General tab, make sure the correct node (if you have a Proxmox VE cluster) that you saved the Ubuntu LXC template to is selected.
    • Set the hostname to host0.
    • Set and confirm the root password for the CT.

    Screenshot of General

    • On the Template tab, make sure Storage is set to local, and select ubuntu-22.04-1-standard_22.04-1_amd64.tar.zst (or your equivalent based on the platform) for Template.

    Screenshot of Template

    • One the Disks tab, leave all default configurations in place.

    Screenshot of Disks

    • One the CPU tab, leave all default configurations in place.

    Screenshot of CPU

    • One the Memory tab, leave all default configurations in place.

    Screenshot of Memory

    • One the Network tab, change the IPv4 to DHCP. Note that this assumes the default bridge vmbr0 is connected to a gateway that can respond to DHCP requests on an Internet-connected LAN subnet.

    Screenshot of Network

    • One the DNS tab, leave all default configurations in place.

    Screenshot of DNS

    • One the Confirm tab, review all your settings and when complete, click the Finish button.

    Screenshot of Confirm

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-3-update-and-configure-the-ubuntu-linux-ct-for-use-as-a-network-host","title":"Step 3: Update and Configure the Ubuntu Linux CT for Use as a Network Host","text":"

    Before this CT can become a custom template for cloning, there is some configuration to it that must be done. Select the newly-created host0 CT from the list, then select the Console tab and click the Start Now button to run the CT.

    From there, log into the CT's root account using the password entered in Step 2 above, and perform the following configuration tasks.

    Add a non-root administrator account and fill out the proceeding prompts:

    adduser admin\n

    Add the newly-created account to the sudo group to use administrator priveleges:

    addgroup admin sudo\n

    Log out of the root account then log in again using your new user name and password:

    logout\n

    Tip

    Upon login, you should see the following message confirming sudo priveleges:

    To run a command as administrator (user \"root\"), use \"sudo \". See \"man sudo_root\" for details.

    Upgrade all existing packages:

    sudo apt update && sudo apt dist-upgrade\n

    Install several additional packages:

    sudo apt install network-manager nmap ipcalc\n

    Clean up the package database:

    sudo apt clean\n

    Clean up unnecessary packages:

    sudo apt autoremove\n

    Remove the current SSH host keys so each clone regenerates new keys:

    sudo rm /etc/ssh/ssh_host_*\n

    Remove the current machine ID so each clone regenerates a new ID:

    sudo truncate -s 0 /etc/machine-id\n

    Shut down the CT:

    sudo systemctl poweroff\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/creating-a-network-host-template-in-proxmox/#step-4-convert-the-ubuntu-linux-ct-into-a-custom-container-template","title":"Step 4: Convert the Ubuntu Linux CT into a Custom Container Template","text":"

    You're now ready to convert this CT into a custom template.

    • With the CT powered down, click the More drop-down button at the top-right of the Proxmox VE window, then click Convert to template.
    • Click the Yes button to proceed, and the CT will be converted into a template.

    Your network host template is now ready. Complete the Cloning a Network Host Template in Proxmox lab to practice creating Ubuntu Linux network hosts for use in upcoming labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/","title":"Exploring Subnets and VLANs in Proxmox","text":"","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#introduction","title":"Introduction","text":"

    In this lab we're going to continue exploring subnets and begin to look at the role of VLANs in addressing the broadcast domain issue we observed in the previous lab. Recall from that lab that we ended up with two subnets on the same bridge and shared the same broadcast domain.

    VLANs are a way to logically separate broadcast domains within the same Layer 2 network, such as a bridge or switch. This allows us to reduce broadcasts and flooding, which improves network performance. VLANs also:

    • increase network security by segmenting Layer 2 networks and enabling fine-grained control of inter-VLAN communication between hosts via routing and firewalls,
    • provide management flexibility in organizing and controlling traffic based on each host or subnet's role, functions, or priority (quality of service [QoS]) and
    • maximize hardware utilization by enabling multiple VLANs to either exist on the same bridge or switch as well as connecting across multiple bridges or switches.

    In this lab we're going to concentrate on segmenting broadcast domains using VLANs, but we'll be addressing the other applications of VLANs in future labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#step-1-configure-the-bridge-to-be-vlan-aware","title":"Step 1: Configure the Bridge to Be VLAN Aware","text":"

    Before we begin experimenting with VLANS, we have to make a change to bridge vmbr1 in order to allow VLANs on the hosts. On the Networks view of the Proxmox node, edit vmbr1 and check \"VLAN aware.\" Then click the Apply Configuration button and you're ready to use VLANs on the bridge.

    Warning

    Ensure this configuration is performed before attempting to apply VLAN settings to hosts on a bridge. Otherwise, you'll get errors.

    The same is true for attempting to disable VLAN settings on a bridge. In this case, if hosts are configured with VLANs, and you try to uncheck \"VLAN aware\" on the bridge, you will get errors here, as well.

    There are other VLAN configuration options within Proxmox, but this is simplest and most consistent way to configure them at this point. We'll dig into advanced Proxmox networking in future labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#step-2-assign-subnets-to-vlans","title":"Step 2: Assign Subnets to VLANs","text":"

    With the bridge now VLAN aware, it's time to assign VLANS to each subnet in order to separate each subnet's broadcast domain. To do this, we'll use a common VLAN to subnet numbering convention that is helpful while learning these concepts.

    Tip

    Using one VLAN per subnet is the recommended best practice.

    We're going to create two new subnets: 10.0.10.0/24 and 10.0.20.0/24, and assign VLAN 10 to the first subnet and VLAN 20 to the second subnet. Using this convention, the third octet of the subnet matches the VLAN ID.

    Warning

    This numbering convention is helpful for learning purposes, but will often break down or not scale in production networks, and also should not be used as a substitute for good documentation.

    We'll cover both network address planning and documentation in future labs.

    host1 and host2 are going to be assigned to the 10.0.10.0/24 subnet, and host3 and host4 are going to be assigned to the 10.0.20.0/24 subnet. Here's the new addressing plan for our four hosts:

    Host IPv4 Address VLAN host1 10.0.10.1/24 10 host2 10.0.10.2/24 10 host3 10.0.20.3/24 20 host4 10.0.20.4/24 20

    Make these changes by updating the IPv4 address and VLAN ID settings within the network configurations for each host in Proxmox. Verify each host has the right IPv4 address by running an ip command that displays host addressing and reviewing the output:

    ip a\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#step-3-verify-broadcast-domain-isolation-for-each-subnet","title":"Step 3: Verify Broadcast Domain Isolation for Each Subnet","text":"

    Once all configuration changes are made, we'll be ready to verify that the VLANs now isolate the two broadcast domains, as expected. To test, we're going to use nmap again, but this time, we'll also see how it works behind the scenes so you understand why it's a good choice for this test.

    Open up all four hosts in the quarter tile layout so they're all visible, and begin packet captures on host2 and host4:

    sudo tcpdump\n

    Next, we're going to perform a quick scan of each subnet and then examine the results. Starting on host1, run the following on host1:

    nmap -sn 10.0.10.0/24\n

    Then check the output on both host1 and host2

    eron@host1:~$ nmap -sn 10.0.10.0/24\nStarting Nmap 7.80 ( https://nmap.org ) at 2023-06-27 13:54 UTC\nNmap scan report for 10.0.10.1\nHost is up (0.00033s latency).\nNmap scan report for 10.0.10.2\nHost is up (0.00023s latency).\nNmap done: 256 IP addresses (2 hosts up) scanned in 15.91 seconds\n
    eron@host2:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n13:54:02.238931 IP 10.0.10.1.54440 > 10.0.10.2.http: Flags [S], seq 3772918725, win 64240, options [mss 1460,sackOK,TS val 3851871978 ecr 0,nop,wscale 7], length 0\n13:54:02.238938 IP 10.0.10.2.http > 10.0.10.1.54440: Flags [R.], seq 0, ack 3772918726, win 0, length 0\n13:54:02.238976 ARP, Request who-has 10.0.10.3 tell 10.0.10.1, length 28\n13:54:02.238996 ARP, Request who-has 10.0.10.4 tell 10.0.10.1, length 28\n13:54:02.239034 ARP, Request who-has 10.0.10.5 tell 10.0.10.1, length 28\n13:54:02.239061 ARP, Request who-has 10.0.10.6 tell 10.0.10.1, length 28\n13:54:02.239079 ARP, Request who-has 10.0.10.7 tell 10.0.10.1, length 28\n13:54:02.239114 ARP, Request who-has 10.0.10.8 tell 10.0.10.1, length 28\n13:54:02.239140 ARP, Request who-has 10.0.10.9 tell 10.0.10.1, length 28\n13:54:02.239174 ARP, Request who-has 10.0.10.10 tell 10.0.10.1, length 28\n13:54:02.239278 ARP, Request who-has 10.0.10.13 tell 10.0.10.1, length 28\n13:54:02.239317 ARP, Request who-has 10.0.10.14 tell 10.0.10.1, length 28\n13:54:02.239343 ARP, Request who-has 10.0.10.15 tell 10.0.10.1, length 28\n13:54:02.239359 ARP, Request who-has 10.0.10.16 tell 10.0.10.1, length 28\n13:54:02.339041 ARP, Request who-has 10.0.10.65 tell 10.0.10.1, length 28\n13:54:02.339115 ARP, Request who-has 10.0.10.68 tell 10.0.10.1, length 28\n13:54:02.339142 ARP, Request who-has 10.0.10.69 tell 10.0.10.1, length 28\n13:54:02.339160 ARP, Request who-has 10.0.10.70 tell 10.0.10.1, length 28\n13:54:02.339230 ARP, Request who-has 10.0.10.73 tell 10.0.10.1, length 28\n13:54:02.339249 ARP, Request who-has 10.0.10.74 tell 10.0.10.1, length 28\n13:54:02.339267 ARP, Request who-has 10.0.10.75 tell 10.0.10.1, length 28\n13:54:02.339284 ARP, Request who-has 10.0.10.76 tell 10.0.10.1, length 28\n13:54:02.339345 ARP, Request who-has 10.0.10.79 tell 10.0.10.1, length 28\n13:54:02.339362 ARP, Request who-has 10.0.10.80 tell 10.0.10.1, length 28\n13:54:02.339424 ARP, Request who-has 10.0.10.83 tell 10.0.10.1, length 28\n13:54:02.339441 ARP, Request who-has 10.0.10.84 tell 10.0.10.1, length 28\n13:54:02.439092 ARP, Request who-has 10.0.10.131 tell 10.0.10.1, length 28\n13:54:02.439157 ARP, Request who-has 10.0.10.134 tell 10.0.10.1, length 28\n13:54:02.439220 ARP, Request who-has 10.0.10.137 tell 10.0.10.1, length 28\n13:54:02.439238 ARP, Request who-has 10.0.10.138 tell 10.0.10.1, length 28\n13:54:02.439299 ARP, Request who-has 10.0.10.141 tell 10.0.10.1, length 28\n13:54:02.439317 ARP, Request who-has 10.0.10.142 tell 10.0.10.1, length 28\n13:54:02.439378 ARP, Request who-has 10.0.10.145 tell 10.0.10.1, length 28\n13:54:02.439400 ARP, Request who-has 10.0.10.146 tell 10.0.10.1, length 28\n13:54:02.439464 ARP, Request who-has 10.0.10.149 tell 10.0.10.1, length 28\n13:54:02.439483 ARP, Request who-has 10.0.10.150 tell 10.0.10.1, length 28\n13:54:02.439500 ARP, Request who-has 10.0.10.151 tell 10.0.10.1, length 28\n13:54:02.439558 ARP, Request who-has 10.0.10.154 tell 10.0.10.1, length 28\n13:54:02.539133 ARP, Request who-has 10.0.10.193 tell 10.0.10.1, length 28\n13:54:02.539197 ARP, Request who-has 10.0.10.196 tell 10.0.10.1, length 28\n13:54:02.539257 ARP, Request who-has 10.0.10.199 tell 10.0.10.1, length 28\n13:54:02.539315 ARP, Request who-has 10.0.10.202 tell 10.0.10.1, length 28\n13:54:02.539376 ARP, Request who-has 10.0.10.205 tell 10.0.10.1, length 28\n13:54:02.539395 ARP, Request who-has 10.0.10.206 tell 10.0.10.1, length 28\n13:54:02.539455 ARP, Request who-has 10.0.10.209 tell 10.0.10.1, length 28\n13:54:02.539474 ARP, Request who-has 10.0.10.210 tell 10.0.10.1, length 28\n13:54:02.539547 ARP, Request who-has 10.0.10.213 tell 10.0.10.1, length 28\n13:54:02.539565 ARP, Request who-has 10.0.10.214 tell 10.0.10.1, length 28\n13:54:02.539631 ARP, Request who-has 10.0.10.217 tell 10.0.10.1, length 28\n13:54:02.539651 ARP, Request who-has 10.0.10.218 tell 10.0.10.1, length 28\n13:54:02.639187 ARP, Request who-has 10.0.10.253 tell 10.0.10.1, length 28\n13:54:02.639252 ARP, Request who-has 10.0.10.0 tell 10.0.10.1, length 28\n13:54:02.639311 ARP, Request who-has 10.0.10.11 tell 10.0.10.1, length 28\n13:54:02.639369 ARP, Request who-has 10.0.10.17 tell 10.0.10.1, length 28\n13:54:02.639426 ARP, Request who-has 10.0.10.20 tell 10.0.10.1, length 28\n13:54:02.639483 ARP, Request who-has 10.0.10.23 tell 10.0.10.1, length 28\n13:54:02.639544 ARP, Request who-has 10.0.10.26 tell 10.0.10.1, length 28\n13:54:02.639562 ARP, Request who-has 10.0.10.27 tell 10.0.10.1, length 28\n13:54:02.639622 ARP, Request who-has 10.0.10.30 tell 10.0.10.1, length 28\n13:54:02.639640 ARP, Request who-has 10.0.10.31 tell 10.0.10.1, length 28\n13:54:02.639700 ARP, Request who-has 10.0.10.34 tell 10.0.10.1, length 28\n13:54:02.639718 ARP, Request who-has 10.0.10.35 tell 10.0.10.1, length 28\n13:54:02.739241 ARP, Request who-has 10.0.10.71 tell 10.0.10.1, length 28\n13:54:02.739306 ARP, Request who-has 10.0.10.77 tell 10.0.10.1, length 28\n13:54:02.739367 ARP, Request who-has 10.0.10.81 tell 10.0.10.1, length 28\n13:54:02.739429 ARP, Request who-has 10.0.10.85 tell 10.0.10.1, length 28\n13:54:02.739490 ARP, Request who-has 10.0.10.88 tell 10.0.10.1, length 28\n13:54:02.739549 ARP, Request who-has 10.0.10.91 tell 10.0.10.1, length 28\n13:54:02.739609 ARP, Request who-has 10.0.10.94 tell 10.0.10.1, length 28\n13:54:02.739626 ARP, Request who-has 10.0.10.95 tell 10.0.10.1, length 28\n13:54:02.739688 ARP, Request who-has 10.0.10.98 tell 10.0.10.1, length 28\n13:54:02.739705 ARP, Request who-has 10.0.10.99 tell 10.0.10.1, length 28\n13:54:02.739771 ARP, Request who-has 10.0.10.102 tell 10.0.10.1, length 28\n13:54:02.739793 ARP, Request who-has 10.0.10.103 tell 10.0.10.1, length 28\n13:54:02.839291 ARP, Request who-has 10.0.10.132 tell 10.0.10.1, length 28\n13:54:02.839359 ARP, Request who-has 10.0.10.135 tell 10.0.10.1, length 28\n13:54:02.839420 ARP, Request who-has 10.0.10.139 tell 10.0.10.1, length 28\n13:54:02.839481 ARP, Request who-has 10.0.10.143 tell 10.0.10.1, length 28\n13:54:02.839540 ARP, Request who-has 10.0.10.147 tell 10.0.10.1, length 28\n13:54:02.839599 ARP, Request who-has 10.0.10.152 tell 10.0.10.1, length 28\n13:54:02.839660 ARP, Request who-has 10.0.10.155 tell 10.0.10.1, length 28\n13:54:02.839724 ARP, Request who-has 10.0.10.158 tell 10.0.10.1, length 28\n13:54:02.839743 ARP, Request who-has 10.0.10.159 tell 10.0.10.1, length 28\n13:54:02.839802 ARP, Request who-has 10.0.10.162 tell 10.0.10.1, length 28\n13:54:02.839862 ARP, Request who-has 10.0.10.165 tell 10.0.10.1, length 28\n13:54:02.839880 ARP, Request who-has 10.0.10.166 tell 10.0.10.1, length 28\n13:54:02.939327 ARP, Request who-has 10.0.10.191 tell 10.0.10.1, length 28\n13:54:02.939393 ARP, Request who-has 10.0.10.194 tell 10.0.10.1, length 28\n13:54:02.939454 ARP, Request who-has 10.0.10.197 tell 10.0.10.1, length 28\n13:54:02.939513 ARP, Request who-has 10.0.10.200 tell 10.0.10.1, length 28\n13:54:02.939591 ARP, Request who-has 10.0.10.207 tell 10.0.10.1, length 28\n13:54:02.939649 ARP, Request who-has 10.0.10.211 tell 10.0.10.1, length 28\n13:54:02.939708 ARP, Request who-has 10.0.10.215 tell 10.0.10.1, length 28\n13:54:02.939767 ARP, Request who-has 10.0.10.219 tell 10.0.10.1, length 28\n13:54:02.939825 ARP, Request who-has 10.0.10.222 tell 10.0.10.1, length 28\n13:54:02.939884 ARP, Request who-has 10.0.10.225 tell 10.0.10.1, length 28\n13:54:02.939946 ARP, Request who-has 10.0.10.228 tell 10.0.10.1, length 28\n13:54:02.939966 ARP, Request who-has 10.0.10.229 tell 10.0.10.1, length 28\n13:54:03.040226 ARP, Request who-has 10.0.10.232 tell 10.0.10.1, length 28\n13:54:03.040248 ARP, Request who-has 10.0.10.233 tell 10.0.10.1, length 28\n13:54:03.040266 ARP, Request who-has 10.0.10.234 tell 10.0.10.1, length 28\n13:54:03.040292 ARP, Request who-has 10.0.10.235 tell 10.0.10.1, length 28\n13:54:03.040309 ARP, Request who-has 10.0.10.236 tell 10.0.10.1, length 28\n13:54:03.040327 ARP, Request who-has 10.0.10.237 tell 10.0.10.1, length 28\n13:54:03.040345 ARP, Request who-has 10.0.10.238 tell 10.0.10.1, length 28\n13:54:03.040362 ARP, Request who-has 10.0.10.239 tell 10.0.10.1, length 28\n13:54:03.040378 ARP, Request who-has 10.0.10.240 tell 10.0.10.1, length 28\n13:54:03.040395 ARP, Request who-has 10.0.10.241 tell 10.0.10.1, length 28\n13:54:03.040413 ARP, Request who-has 10.0.10.242 tell 10.0.10.1, length 28\n13:54:03.040430 ARP, Request who-has 10.0.10.243 tell 10.0.10.1, length 28\n13:54:03.140269 ARP, Request who-has 10.0.10.60 tell 10.0.10.1, length 28\n13:54:03.140341 ARP, Request who-has 10.0.10.63 tell 10.0.10.1, length 28\n13:54:03.140361 ARP, Request who-has 10.0.10.64 tell 10.0.10.1, length 28\n13:54:03.140382 ARP, Request who-has 10.0.10.66 tell 10.0.10.1, length 28\n13:54:03.140456 ARP, Request who-has 10.0.10.72 tell 10.0.10.1, length 28\n13:54:03.140475 ARP, Request who-has 10.0.10.78 tell 10.0.10.1, length 28\n13:54:03.140492 ARP, Request who-has 10.0.10.82 tell 10.0.10.1, length 28\n13:54:03.140509 ARP, Request who-has 10.0.10.86 tell 10.0.10.1, length 28\n13:54:03.140526 ARP, Request who-has 10.0.10.87 tell 10.0.10.1, length 28\n13:54:03.140543 ARP, Request who-has 10.0.10.89 tell 10.0.10.1, length 28\n13:54:03.140607 ARP, Request who-has 10.0.10.92 tell 10.0.10.1, length 28\n13:54:03.140630 ARP, Request who-has 10.0.10.93 tell 10.0.10.1, length 28\n13:54:03.240320 ARP, Request who-has 10.0.10.148 tell 10.0.10.1, length 28\n13:54:03.240387 ARP, Request who-has 10.0.10.153 tell 10.0.10.1, length 28\n13:54:03.240455 ARP, Request who-has 10.0.10.156 tell 10.0.10.1, length 28\n13:54:03.240474 ARP, Request who-has 10.0.10.157 tell 10.0.10.1, length 28\n13:54:03.240538 ARP, Request who-has 10.0.10.160 tell 10.0.10.1, length 28\n13:54:03.240556 ARP, Request who-has 10.0.10.161 tell 10.0.10.1, length 28\n13:54:03.240573 ARP, Request who-has 10.0.10.163 tell 10.0.10.1, length 28\n13:54:03.240638 ARP, Request who-has 10.0.10.167 tell 10.0.10.1, length 28\n13:54:03.240663 ARP, Request who-has 10.0.10.168 tell 10.0.10.1, length 28\n13:54:03.240681 ARP, Request who-has 10.0.10.169 tell 10.0.10.1, length 28\n13:54:03.240744 ARP, Request who-has 10.0.10.172 tell 10.0.10.1, length 28\n13:54:03.240764 ARP, Request who-has 10.0.10.173 tell 10.0.10.1, length 28\n13:54:03.240880 ARP, Request who-has 10.0.10.16 tell 10.0.10.1, length 28\n13:54:03.240882 ARP, Request who-has 10.0.10.15 tell 10.0.10.1, length 28\n13:54:03.240882 ARP, Request who-has 10.0.10.14 tell 10.0.10.1, length 28\n13:54:03.240883 ARP, Request who-has 10.0.10.13 tell 10.0.10.1, length 28\n13:54:03.240884 ARP, Request who-has 10.0.10.10 tell 10.0.10.1, length 28\n13:54:03.240885 ARP, Request who-has 10.0.10.9 tell 10.0.10.1, length 28\n13:54:03.240885 ARP, Request who-has 10.0.10.8 tell 10.0.10.1, length 28\n13:54:03.240886 ARP, Request who-has 10.0.10.7 tell 10.0.10.1, length 28\n13:54:03.240887 ARP, Request who-has 10.0.10.6 tell 10.0.10.1, length 28\n13:54:03.240887 ARP, Request who-has 10.0.10.5 tell 10.0.10.1, length 28\n13:54:03.240888 ARP, Request who-has 10.0.10.4 tell 10.0.10.1, length 28\n13:54:03.240889 ARP, Request who-has 10.0.10.3 tell 10.0.10.1, length 28\n13:54:03.368936 ARP, Request who-has 10.0.10.84 tell 10.0.10.1, length 28\n13:54:03.368938 ARP, Request who-has 10.0.10.83 tell 10.0.10.1, length 28\n13:54:03.368939 ARP, Request who-has 10.0.10.80 tell 10.0.10.1, length 28\n13:54:03.368939 ARP, Request who-has 10.0.10.79 tell 10.0.10.1, length 28\n13:54:03.368940 ARP, Request who-has 10.0.10.76 tell 10.0.10.1, length 28\n13:54:03.368940 ARP, Request who-has 10.0.10.75 tell 10.0.10.1, length 28\n13:54:03.368941 ARP, Request who-has 10.0.10.74 tell 10.0.10.1, length 28\n13:54:03.368942 ARP, Request who-has 10.0.10.73 tell 10.0.10.1, length 28\n13:54:03.368942 ARP, Request who-has 10.0.10.70 tell 10.0.10.1, length 28\n13:54:03.368943 ARP, Request who-has 10.0.10.69 tell 10.0.10.1, length 28\n13:54:03.368943 ARP, Request who-has 10.0.10.68 tell 10.0.10.1, length 28\n13:54:03.368944 ARP, Request who-has 10.0.10.65 tell 10.0.10.1, length 28\n13:54:03.464947 ARP, Request who-has 10.0.10.154 tell 10.0.10.1, length 28\n13:54:03.464950 ARP, Request who-has 10.0.10.151 tell 10.0.10.1, length 28\n13:54:03.464951 ARP, Request who-has 10.0.10.150 tell 10.0.10.1, length 28\n13:54:03.464952 ARP, Request who-has 10.0.10.149 tell 10.0.10.1, length 28\n13:54:03.464952 ARP, Request who-has 10.0.10.146 tell 10.0.10.1, length 28\n13:54:03.464953 ARP, Request who-has 10.0.10.145 tell 10.0.10.1, length 28\n13:54:03.464954 ARP, Request who-has 10.0.10.142 tell 10.0.10.1, length 28\n13:54:03.464954 ARP, Request who-has 10.0.10.141 tell 10.0.10.1, length 28\n13:54:03.464955 ARP, Request who-has 10.0.10.138 tell 10.0.10.1, length 28\n13:54:03.464955 ARP, Request who-has 10.0.10.137 tell 10.0.10.1, length 28\n13:54:03.464956 ARP, Request who-has 10.0.10.134 tell 10.0.10.1, length 28\n13:54:03.464957 ARP, Request who-has 10.0.10.131 tell 10.0.10.1, length 28\n13:54:03.540432 IP 10.0.10.1.54454 > 10.0.10.2.http: Flags [S], seq 1946917605, win 64240, options [mss 1460,sackOK,TS val 3851873279 ecr 0,nop,wscale 7], length 0\n13:54:03.540440 IP 10.0.10.2.http > 10.0.10.1.54454: Flags [R.], seq 0, ack 1946917606, win 0, length 0\n13:54:03.540670 ARP, Request who-has 10.0.10.96 tell 10.0.10.1, length 28\n13:54:03.540691 ARP, Request who-has 10.0.10.97 tell 10.0.10.1, length 28\n13:54:03.540709 ARP, Request who-has 10.0.10.100 tell 10.0.10.1, length 28\n13:54:03.540727 ARP, Request who-has 10.0.10.101 tell 10.0.10.1, length 28\n13:54:03.540747 ARP, Request who-has 10.0.10.104 tell 10.0.10.1, length 28\n13:54:03.540765 ARP, Request who-has 10.0.10.105 tell 10.0.10.1, length 28\n13:54:03.540782 ARP, Request who-has 10.0.10.106 tell 10.0.10.1, length 28\n13:54:03.540808 ARP, Request who-has 10.0.10.107 tell 10.0.10.1, length 28\n13:54:03.540842 ARP, Request who-has 10.0.10.108 tell 10.0.10.1, length 28\n13:54:03.540860 ARP, Request who-has 10.0.10.109 tell 10.0.10.1, length 28\n13:54:03.540877 ARP, Request who-has 10.0.10.110 tell 10.0.10.1, length 28\n13:54:03.540896 ARP, Request who-has 10.0.10.111 tell 10.0.10.1, length 28\n13:54:03.540913 ARP, Request who-has 10.0.10.112 tell 10.0.10.1, length 28\n13:54:03.540932 ARP, Request who-has 10.0.10.113 tell 10.0.10.1, length 28\n13:54:03.540950 ARP, Request who-has 10.0.10.114 tell 10.0.10.1, length 28\n13:54:03.540970 ARP, Request who-has 10.0.10.115 tell 10.0.10.1, length 28\n13:54:03.540988 ARP, Request who-has 10.0.10.116 tell 10.0.10.1, length 28\n13:54:03.541005 ARP, Request who-has 10.0.10.117 tell 10.0.10.1, length 28\n13:54:03.541023 ARP, Request who-has 10.0.10.118 tell 10.0.10.1, length 28\n13:54:03.541040 ARP, Request who-has 10.0.10.119 tell 10.0.10.1, length 28\n13:54:03.541058 ARP, Request who-has 10.0.10.120 tell 10.0.10.1, length 28\n13:54:03.541079 ARP, Request who-has 10.0.10.121 tell 10.0.10.1, length 28\n13:54:03.541096 ARP, Request who-has 10.0.10.122 tell 10.0.10.1, length 28\n13:54:03.541114 ARP, Request who-has 10.0.10.123 tell 10.0.10.1, length 28\n13:54:03.541133 ARP, Request who-has 10.0.10.124 tell 10.0.10.1, length 28\n13:54:03.541153 ARP, Request who-has 10.0.10.125 tell 10.0.10.1, length 28\n13:54:03.541170 ARP, Request who-has 10.0.10.126 tell 10.0.10.1, length 28\n13:54:03.541189 ARP, Request who-has 10.0.10.127 tell 10.0.10.1, length 28\n13:54:03.541207 ARP, Request who-has 10.0.10.128 tell 10.0.10.1, length 28\n13:54:03.541229 ARP, Request who-has 10.0.10.129 tell 10.0.10.1, length 28\n13:54:03.541248 ARP, Request who-has 10.0.10.130 tell 10.0.10.1, length 28\n13:54:03.541273 ARP, Request who-has 10.0.10.133 tell 10.0.10.1, length 28\n13:54:03.541298 ARP, Request who-has 10.0.10.136 tell 10.0.10.1, length 28\n13:54:03.541337 ARP, Request who-has 10.0.10.140 tell 10.0.10.1, length 28\n13:54:03.541441 ARP, Request who-has 10.0.10.144 tell 10.0.10.1, length 28\n13:54:03.541514 ARP, Request who-has 10.0.10.164 tell 10.0.10.1, length 28\n13:54:03.541530 ARP, Request who-has 10.0.10.170 tell 10.0.10.1, length 28\n13:54:03.541546 ARP, Request who-has 10.0.10.171 tell 10.0.10.1, length 28\n13:54:03.541561 ARP, Request who-has 10.0.10.174 tell 10.0.10.1, length 28\n13:54:03.541581 ARP, Request who-has 10.0.10.175 tell 10.0.10.1, length 28\n13:54:03.541597 ARP, Request who-has 10.0.10.176 tell 10.0.10.1, length 28\n13:54:03.541613 ARP, Request who-has 10.0.10.177 tell 10.0.10.1, length 28\n13:54:03.541630 ARP, Request who-has 10.0.10.178 tell 10.0.10.1, length 28\n13:54:03.541645 ARP, Request who-has 10.0.10.179 tell 10.0.10.1, length 28\n13:54:03.541661 ARP, Request who-has 10.0.10.180 tell 10.0.10.1, length 28\n13:54:03.541676 ARP, Request who-has 10.0.10.181 tell 10.0.10.1, length 28\n13:54:03.541695 ARP, Request who-has 10.0.10.182 tell 10.0.10.1, length 28\n13:54:03.541711 ARP, Request who-has 10.0.10.183 tell 10.0.10.1, length 28\n13:54:03.541731 ARP, Request who-has 10.0.10.184 tell 10.0.10.1, length 28\n13:54:03.541750 ARP, Request who-has 10.0.10.185 tell 10.0.10.1, length 28\n13:54:03.541766 ARP, Request who-has 10.0.10.186 tell 10.0.10.1, length 28\n13:54:03.541782 ARP, Request who-has 10.0.10.187 tell 10.0.10.1, length 28\n13:54:03.541799 ARP, Request who-has 10.0.10.188 tell 10.0.10.1, length 28\n13:54:03.560932 ARP, Request who-has 10.0.10.218 tell 10.0.10.1, length 28\n13:54:03.560934 ARP, Request who-has 10.0.10.217 tell 10.0.10.1, length 28\n13:54:03.560934 ARP, Request who-has 10.0.10.214 tell 10.0.10.1, length 28\n13:54:03.560935 ARP, Request who-has 10.0.10.213 tell 10.0.10.1, length 28\n13:54:03.560936 ARP, Request who-has 10.0.10.210 tell 10.0.10.1, length 28\n13:54:03.560936 ARP, Request who-has 10.0.10.209 tell 10.0.10.1, length 28\n13:54:03.560937 ARP, Request who-has 10.0.10.206 tell 10.0.10.1, length 28\n13:54:03.560938 ARP, Request who-has 10.0.10.205 tell 10.0.10.1, length 28\n13:54:03.560938 ARP, Request who-has 10.0.10.202 tell 10.0.10.1, length 28\n13:54:03.560939 ARP, Request who-has 10.0.10.199 tell 10.0.10.1, length 28\n13:54:03.560940 ARP, Request who-has 10.0.10.196 tell 10.0.10.1, length 28\n13:54:03.560940 ARP, Request who-has 10.0.10.193 tell 10.0.10.1, length 28\n13:54:03.640866 ARP, Request who-has 10.0.10.244 tell 10.0.10.1, length 28\n13:54:03.640890 ARP, Request who-has 10.0.10.245 tell 10.0.10.1, length 28\n13:54:03.640910 ARP, Request who-has 10.0.10.246 tell 10.0.10.1, length 28\n13:54:03.641026 ARP, Request who-has 10.0.10.249 tell 10.0.10.1, length 28\n13:54:03.641043 ARP, Request who-has 10.0.10.250 tell 10.0.10.1, length 28\n13:54:03.641060 ARP, Request who-has 10.0.10.251 tell 10.0.10.1, length 28\n13:54:03.641077 ARP, Request who-has 10.0.10.252 tell 10.0.10.1, length 28\n13:54:03.641094 ARP, Request who-has 10.0.10.254 tell 10.0.10.1, length 28\n13:54:03.641285 ARP, Request who-has 10.0.10.12 tell 10.0.10.1, length 28\n13:54:03.641340 ARP, Request who-has 10.0.10.18 tell 10.0.10.1, length 28\n13:54:03.641357 ARP, Request who-has 10.0.10.19 tell 10.0.10.1, length 28\n13:54:03.641374 ARP, Request who-has 10.0.10.21 tell 10.0.10.1, length 28\n13:54:03.641391 ARP, Request who-has 10.0.10.22 tell 10.0.10.1, length 28\n13:54:03.641409 ARP, Request who-has 10.0.10.24 tell 10.0.10.1, length 28\n13:54:03.641426 ARP, Request who-has 10.0.10.25 tell 10.0.10.1, length 28\n13:54:03.641443 ARP, Request who-has 10.0.10.28 tell 10.0.10.1, length 28\n13:54:03.641467 ARP, Request who-has 10.0.10.29 tell 10.0.10.1, length 28\n13:54:03.641483 ARP, Request who-has 10.0.10.32 tell 10.0.10.1, length 28\n13:54:03.641701 ARP, Request who-has 10.0.10.36 tell 10.0.10.1, length 28\n13:54:03.641717 ARP, Request who-has 10.0.10.37 tell 10.0.10.1, length 28\n13:54:03.641734 ARP, Request who-has 10.0.10.38 tell 10.0.10.1, length 28\n13:54:03.641749 ARP, Request who-has 10.0.10.39 tell 10.0.10.1, length 28\n13:54:03.641764 ARP, Request who-has 10.0.10.40 tell 10.0.10.1, length 28\n13:54:03.641783 ARP, Request who-has 10.0.10.41 tell 10.0.10.1, length 28\n13:54:03.641799 ARP, Request who-has 10.0.10.42 tell 10.0.10.1, length 28\n13:54:03.641919 ARP, Request who-has 10.0.10.45 tell 10.0.10.1, length 28\n13:54:03.641936 ARP, Request who-has 10.0.10.46 tell 10.0.10.1, length 28\n13:54:03.641953 ARP, Request who-has 10.0.10.47 tell 10.0.10.1, length 28\n13:54:03.641969 ARP, Request who-has 10.0.10.48 tell 10.0.10.1, length 28\n13:54:03.641984 ARP, Request who-has 10.0.10.49 tell 10.0.10.1, length 28\n13:54:03.642000 ARP, Request who-has 10.0.10.50 tell 10.0.10.1, length 28\n13:54:03.642015 ARP, Request who-has 10.0.10.51 tell 10.0.10.1, length 28\n13:54:03.642030 ARP, Request who-has 10.0.10.52 tell 10.0.10.1, length 28\n13:54:03.642046 ARP, Request who-has 10.0.10.53 tell 10.0.10.1, length 28\n13:54:03.642062 ARP, Request who-has 10.0.10.54 tell 10.0.10.1, length 28\n13:54:03.642078 ARP, Request who-has 10.0.10.55 tell 10.0.10.1, length 28\n13:54:03.642094 ARP, Request who-has 10.0.10.56 tell 10.0.10.1, length 28\n13:54:03.642112 ARP, Request who-has 10.0.10.57 tell 10.0.10.1, length 28\n13:54:03.642128 ARP, Request who-has 10.0.10.58 tell 10.0.10.1, length 28\n13:54:03.642143 ARP, Request who-has 10.0.10.59 tell 10.0.10.1, length 28\n13:54:03.642159 ARP, Request who-has 10.0.10.61 tell 10.0.10.1, length 28\n13:54:03.642175 ARP, Request who-has 10.0.10.62 tell 10.0.10.1, length 28\n13:54:03.656893 ARP, Request who-has 10.0.10.35 tell 10.0.10.1, length 28\n13:54:03.656895 ARP, Request who-has 10.0.10.34 tell 10.0.10.1, length 28\n13:54:03.656895 ARP, Request who-has 10.0.10.31 tell 10.0.10.1, length 28\n13:54:03.656896 ARP, Request who-has 10.0.10.30 tell 10.0.10.1, length 28\n13:54:03.656897 ARP, Request who-has 10.0.10.27 tell 10.0.10.1, length 28\n13:54:03.656898 ARP, Request who-has 10.0.10.26 tell 10.0.10.1, length 28\n13:54:03.656898 ARP, Request who-has 10.0.10.23 tell 10.0.10.1, length 28\n13:54:03.656899 ARP, Request who-has 10.0.10.20 tell 10.0.10.1, length 28\n13:54:03.656899 ARP, Request who-has 10.0.10.17 tell 10.0.10.1, length 28\n13:54:03.656900 ARP, Request who-has 10.0.10.11 tell 10.0.10.1, length 28\n13:54:03.656901 ARP, Request who-has 10.0.10.0 tell 10.0.10.1, length 28\n13:54:03.656901 ARP, Request who-has 10.0.10.253 tell 10.0.10.1, length 28\n13:54:03.741047 ARP, Request who-has 10.0.10.189 tell 10.0.10.1, length 28\n13:54:03.741067 ARP, Request who-has 10.0.10.190 tell 10.0.10.1, length 28\n13:54:03.741163 ARP, Request who-has 10.0.10.195 tell 10.0.10.1, length 28\n13:54:03.741190 ARP, Request who-has 10.0.10.198 tell 10.0.10.1, length 28\n13:54:03.741441 ARP, Request who-has 10.0.10.204 tell 10.0.10.1, length 28\n13:54:03.741537 ARP, Request who-has 10.0.10.208 tell 10.0.10.1, length 28\n13:54:03.741572 ARP, Request who-has 10.0.10.212 tell 10.0.10.1, length 28\n13:54:03.741608 ARP, Request who-has 10.0.10.216 tell 10.0.10.1, length 28\n13:54:03.741717 ARP, Request who-has 10.0.10.220 tell 10.0.10.1, length 28\n13:54:03.741733 ARP, Request who-has 10.0.10.221 tell 10.0.10.1, length 28\n13:54:03.741761 ARP, Request who-has 10.0.10.223 tell 10.0.10.1, length 28\n13:54:03.741795 ARP, Request who-has 10.0.10.224 tell 10.0.10.1, length 28\n13:54:03.741810 ARP, Request who-has 10.0.10.226 tell 10.0.10.1, length 28\n13:54:03.741827 ARP, Request who-has 10.0.10.227 tell 10.0.10.1, length 28\n13:54:03.741843 ARP, Request who-has 10.0.10.230 tell 10.0.10.1, length 28\n13:54:03.741877 ARP, Request who-has 10.0.10.231 tell 10.0.10.1, length 28\n13:54:03.741895 ARP, Request who-has 10.0.10.247 tell 10.0.10.1, length 28\n13:54:03.742130 ARP, Request who-has 10.0.10.33 tell 10.0.10.1, length 28\n13:54:03.742162 ARP, Request who-has 10.0.10.43 tell 10.0.10.1, length 28\n13:54:03.742178 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:03.742313 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:03.752936 ARP, Request who-has 10.0.10.103 tell 10.0.10.1, length 28\n13:54:03.752938 ARP, Request who-has 10.0.10.102 tell 10.0.10.1, length 28\n13:54:03.752938 ARP, Request who-has 10.0.10.99 tell 10.0.10.1, length 28\n13:54:03.752939 ARP, Request who-has 10.0.10.98 tell 10.0.10.1, length 28\n13:54:03.752940 ARP, Request who-has 10.0.10.95 tell 10.0.10.1, length 28\n13:54:03.752940 ARP, Request who-has 10.0.10.94 tell 10.0.10.1, length 28\n13:54:03.752941 ARP, Request who-has 10.0.10.91 tell 10.0.10.1, length 28\n13:54:03.752942 ARP, Request who-has 10.0.10.88 tell 10.0.10.1, length 28\n13:54:03.752942 ARP, Request who-has 10.0.10.85 tell 10.0.10.1, length 28\n13:54:03.752943 ARP, Request who-has 10.0.10.81 tell 10.0.10.1, length 28\n13:54:03.752943 ARP, Request who-has 10.0.10.77 tell 10.0.10.1, length 28\n13:54:03.752944 ARP, Request who-has 10.0.10.71 tell 10.0.10.1, length 28\n13:54:03.841344 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:03.841437 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:03.841464 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:03.842322 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:03.848953 ARP, Request who-has 10.0.10.166 tell 10.0.10.1, length 28\n13:54:03.848954 ARP, Request who-has 10.0.10.165 tell 10.0.10.1, length 28\n13:54:03.848955 ARP, Request who-has 10.0.10.162 tell 10.0.10.1, length 28\n13:54:03.848956 ARP, Request who-has 10.0.10.159 tell 10.0.10.1, length 28\n13:54:03.848956 ARP, Request who-has 10.0.10.158 tell 10.0.10.1, length 28\n13:54:03.848957 ARP, Request who-has 10.0.10.155 tell 10.0.10.1, length 28\n13:54:03.848958 ARP, Request who-has 10.0.10.152 tell 10.0.10.1, length 28\n13:54:03.848958 ARP, Request who-has 10.0.10.147 tell 10.0.10.1, length 28\n13:54:03.848959 ARP, Request who-has 10.0.10.143 tell 10.0.10.1, length 28\n13:54:03.848960 ARP, Request who-has 10.0.10.139 tell 10.0.10.1, length 28\n13:54:03.848960 ARP, Request who-has 10.0.10.135 tell 10.0.10.1, length 28\n13:54:03.848961 ARP, Request who-has 10.0.10.132 tell 10.0.10.1, length 28\n13:54:03.941560 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:03.944939 ARP, Request who-has 10.0.10.229 tell 10.0.10.1, length 28\n13:54:03.944941 ARP, Request who-has 10.0.10.228 tell 10.0.10.1, length 28\n13:54:03.944942 ARP, Request who-has 10.0.10.225 tell 10.0.10.1, length 28\n13:54:03.944943 ARP, Request who-has 10.0.10.222 tell 10.0.10.1, length 28\n13:54:03.944943 ARP, Request who-has 10.0.10.219 tell 10.0.10.1, length 28\n13:54:03.944944 ARP, Request who-has 10.0.10.215 tell 10.0.10.1, length 28\n13:54:03.944945 ARP, Request who-has 10.0.10.211 tell 10.0.10.1, length 28\n13:54:03.944945 ARP, Request who-has 10.0.10.207 tell 10.0.10.1, length 28\n13:54:03.944946 ARP, Request who-has 10.0.10.200 tell 10.0.10.1, length 28\n13:54:03.944947 ARP, Request who-has 10.0.10.197 tell 10.0.10.1, length 28\n13:54:03.944947 ARP, Request who-has 10.0.10.194 tell 10.0.10.1, length 28\n13:54:03.944948 ARP, Request who-has 10.0.10.191 tell 10.0.10.1, length 28\n13:54:04.044932 ARP, Request who-has 10.0.10.243 tell 10.0.10.1, length 28\n13:54:04.044934 ARP, Request who-has 10.0.10.242 tell 10.0.10.1, length 28\n13:54:04.044934 ARP, Request who-has 10.0.10.241 tell 10.0.10.1, length 28\n13:54:04.044935 ARP, Request who-has 10.0.10.240 tell 10.0.10.1, length 28\n13:54:04.044935 ARP, Request who-has 10.0.10.239 tell 10.0.10.1, length 28\n13:54:04.044936 ARP, Request who-has 10.0.10.238 tell 10.0.10.1, length 28\n13:54:04.044937 ARP, Request who-has 10.0.10.237 tell 10.0.10.1, length 28\n13:54:04.044937 ARP, Request who-has 10.0.10.236 tell 10.0.10.1, length 28\n13:54:04.044938 ARP, Request who-has 10.0.10.235 tell 10.0.10.1, length 28\n13:54:04.044939 ARP, Request who-has 10.0.10.234 tell 10.0.10.1, length 28\n13:54:04.044939 ARP, Request who-has 10.0.10.233 tell 10.0.10.1, length 28\n13:54:04.044940 ARP, Request who-has 10.0.10.232 tell 10.0.10.1, length 28\n13:54:04.168927 ARP, Request who-has 10.0.10.93 tell 10.0.10.1, length 28\n13:54:04.168929 ARP, Request who-has 10.0.10.92 tell 10.0.10.1, length 28\n13:54:04.168930 ARP, Request who-has 10.0.10.89 tell 10.0.10.1, length 28\n13:54:04.168930 ARP, Request who-has 10.0.10.87 tell 10.0.10.1, length 28\n13:54:04.168931 ARP, Request who-has 10.0.10.86 tell 10.0.10.1, length 28\n13:54:04.168932 ARP, Request who-has 10.0.10.82 tell 10.0.10.1, length 28\n13:54:04.168932 ARP, Request who-has 10.0.10.78 tell 10.0.10.1, length 28\n13:54:04.168933 ARP, Request who-has 10.0.10.72 tell 10.0.10.1, length 28\n13:54:04.168934 ARP, Request who-has 10.0.10.66 tell 10.0.10.1, length 28\n13:54:04.168934 ARP, Request who-has 10.0.10.64 tell 10.0.10.1, length 28\n13:54:04.168935 ARP, Request who-has 10.0.10.63 tell 10.0.10.1, length 28\n13:54:04.168936 ARP, Request who-has 10.0.10.60 tell 10.0.10.1, length 28\n13:54:04.265000 ARP, Request who-has 10.0.10.3 tell 10.0.10.1, length 28\n13:54:04.265002 ARP, Request who-has 10.0.10.4 tell 10.0.10.1, length 28\n13:54:04.265002 ARP, Request who-has 10.0.10.5 tell 10.0.10.1, length 28\n13:54:04.265003 ARP, Request who-has 10.0.10.6 tell 10.0.10.1, length 28\n13:54:04.265004 ARP, Request who-has 10.0.10.7 tell 10.0.10.1, length 28\n13:54:04.265004 ARP, Request who-has 10.0.10.8 tell 10.0.10.1, length 28\n13:54:04.265005 ARP, Request who-has 10.0.10.9 tell 10.0.10.1, length 28\n13:54:04.265006 ARP, Request who-has 10.0.10.10 tell 10.0.10.1, length 28\n13:54:04.265006 ARP, Request who-has 10.0.10.13 tell 10.0.10.1, length 28\n13:54:04.265007 ARP, Request who-has 10.0.10.14 tell 10.0.10.1, length 28\n13:54:04.265007 ARP, Request who-has 10.0.10.15 tell 10.0.10.1, length 28\n13:54:04.265008 ARP, Request who-has 10.0.10.16 tell 10.0.10.1, length 28\n13:54:04.265009 ARP, Request who-has 10.0.10.173 tell 10.0.10.1, length 28\n13:54:04.265009 ARP, Request who-has 10.0.10.172 tell 10.0.10.1, length 28\n13:54:04.265010 ARP, Request who-has 10.0.10.169 tell 10.0.10.1, length 28\n13:54:04.265011 ARP, Request who-has 10.0.10.168 tell 10.0.10.1, length 28\n13:54:04.265011 ARP, Request who-has 10.0.10.167 tell 10.0.10.1, length 28\n13:54:04.265012 ARP, Request who-has 10.0.10.163 tell 10.0.10.1, length 28\n13:54:04.265013 ARP, Request who-has 10.0.10.161 tell 10.0.10.1, length 28\n13:54:04.265013 ARP, Request who-has 10.0.10.160 tell 10.0.10.1, length 28\n13:54:04.265014 ARP, Request who-has 10.0.10.157 tell 10.0.10.1, length 28\n13:54:04.265015 ARP, Request who-has 10.0.10.156 tell 10.0.10.1, length 28\n13:54:04.265015 ARP, Request who-has 10.0.10.153 tell 10.0.10.1, length 28\n13:54:04.265016 ARP, Request who-has 10.0.10.148 tell 10.0.10.1, length 28\n13:54:04.392915 ARP, Request who-has 10.0.10.65 tell 10.0.10.1, length 28\n13:54:04.392917 ARP, Request who-has 10.0.10.68 tell 10.0.10.1, length 28\n13:54:04.392918 ARP, Request who-has 10.0.10.69 tell 10.0.10.1, length 28\n13:54:04.392919 ARP, Request who-has 10.0.10.70 tell 10.0.10.1, length 28\n13:54:04.392919 ARP, Request who-has 10.0.10.73 tell 10.0.10.1, length 28\n13:54:04.392920 ARP, Request who-has 10.0.10.74 tell 10.0.10.1, length 28\n13:54:04.392921 ARP, Request who-has 10.0.10.75 tell 10.0.10.1, length 28\n13:54:04.392921 ARP, Request who-has 10.0.10.76 tell 10.0.10.1, length 28\n13:54:04.392922 ARP, Request who-has 10.0.10.79 tell 10.0.10.1, length 28\n13:54:04.392922 ARP, Request who-has 10.0.10.80 tell 10.0.10.1, length 28\n13:54:04.392923 ARP, Request who-has 10.0.10.83 tell 10.0.10.1, length 28\n13:54:04.392924 ARP, Request who-has 10.0.10.84 tell 10.0.10.1, length 28\n13:54:04.488924 ARP, Request who-has 10.0.10.131 tell 10.0.10.1, length 28\n13:54:04.488925 ARP, Request who-has 10.0.10.134 tell 10.0.10.1, length 28\n13:54:04.488926 ARP, Request who-has 10.0.10.137 tell 10.0.10.1, length 28\n13:54:04.488927 ARP, Request who-has 10.0.10.138 tell 10.0.10.1, length 28\n13:54:04.488927 ARP, Request who-has 10.0.10.141 tell 10.0.10.1, length 28\n13:54:04.488928 ARP, Request who-has 10.0.10.142 tell 10.0.10.1, length 28\n13:54:04.488929 ARP, Request who-has 10.0.10.145 tell 10.0.10.1, length 28\n13:54:04.488929 ARP, Request who-has 10.0.10.146 tell 10.0.10.1, length 28\n13:54:04.488930 ARP, Request who-has 10.0.10.149 tell 10.0.10.1, length 28\n13:54:04.488930 ARP, Request who-has 10.0.10.150 tell 10.0.10.1, length 28\n13:54:04.488931 ARP, Request who-has 10.0.10.151 tell 10.0.10.1, length 28\n13:54:04.488932 ARP, Request who-has 10.0.10.154 tell 10.0.10.1, length 28\n13:54:04.557150 ARP, Request who-has 10.0.10.188 tell 10.0.10.1, length 28\n13:54:04.557152 ARP, Request who-has 10.0.10.187 tell 10.0.10.1, length 28\n13:54:04.557153 ARP, Request who-has 10.0.10.186 tell 10.0.10.1, length 28\n13:54:04.557154 ARP, Request who-has 10.0.10.185 tell 10.0.10.1, length 28\n13:54:04.557154 ARP, Request who-has 10.0.10.184 tell 10.0.10.1, length 28\n13:54:04.557155 ARP, Request who-has 10.0.10.183 tell 10.0.10.1, length 28\n13:54:04.557156 ARP, Request who-has 10.0.10.182 tell 10.0.10.1, length 28\n13:54:04.557156 ARP, Request who-has 10.0.10.181 tell 10.0.10.1, length 28\n13:54:04.557157 ARP, Request who-has 10.0.10.180 tell 10.0.10.1, length 28\n13:54:04.557158 ARP, Request who-has 10.0.10.179 tell 10.0.10.1, length 28\n13:54:04.557158 ARP, Request who-has 10.0.10.178 tell 10.0.10.1, length 28\n13:54:04.557159 ARP, Request who-has 10.0.10.177 tell 10.0.10.1, length 28\n13:54:04.557160 ARP, Request who-has 10.0.10.176 tell 10.0.10.1, length 28\n13:54:04.557160 ARP, Request who-has 10.0.10.175 tell 10.0.10.1, length 28\n13:54:04.557161 ARP, Request who-has 10.0.10.174 tell 10.0.10.1, length 28\n13:54:04.557162 ARP, Request who-has 10.0.10.171 tell 10.0.10.1, length 28\n13:54:04.557162 ARP, Request who-has 10.0.10.170 tell 10.0.10.1, length 28\n13:54:04.557163 ARP, Request who-has 10.0.10.164 tell 10.0.10.1, length 28\n13:54:04.557164 ARP, Request who-has 10.0.10.144 tell 10.0.10.1, length 28\n13:54:04.557165 ARP, Request who-has 10.0.10.140 tell 10.0.10.1, length 28\n13:54:04.557165 ARP, Request who-has 10.0.10.136 tell 10.0.10.1, length 28\n13:54:04.557166 ARP, Request who-has 10.0.10.133 tell 10.0.10.1, length 28\n13:54:04.557167 ARP, Request who-has 10.0.10.130 tell 10.0.10.1, length 28\n13:54:04.557167 ARP, Request who-has 10.0.10.129 tell 10.0.10.1, length 28\n13:54:04.557168 ARP, Request who-has 10.0.10.128 tell 10.0.10.1, length 28\n13:54:04.557168 ARP, Request who-has 10.0.10.127 tell 10.0.10.1, length 28\n13:54:04.557169 ARP, Request who-has 10.0.10.126 tell 10.0.10.1, length 28\n13:54:04.557170 ARP, Request who-has 10.0.10.125 tell 10.0.10.1, length 28\n13:54:04.557170 ARP, Request who-has 10.0.10.124 tell 10.0.10.1, length 28\n13:54:04.557171 ARP, Request who-has 10.0.10.123 tell 10.0.10.1, length 28\n13:54:04.557172 ARP, Request who-has 10.0.10.122 tell 10.0.10.1, length 28\n13:54:04.557172 ARP, Request who-has 10.0.10.121 tell 10.0.10.1, length 28\n13:54:04.557173 ARP, Request who-has 10.0.10.120 tell 10.0.10.1, length 28\n13:54:04.557174 ARP, Request who-has 10.0.10.119 tell 10.0.10.1, length 28\n13:54:04.557174 ARP, Request who-has 10.0.10.118 tell 10.0.10.1, length 28\n13:54:04.557175 ARP, Request who-has 10.0.10.117 tell 10.0.10.1, length 28\n13:54:04.557175 ARP, Request who-has 10.0.10.116 tell 10.0.10.1, length 28\n13:54:04.557176 ARP, Request who-has 10.0.10.115 tell 10.0.10.1, length 28\n13:54:04.557177 ARP, Request who-has 10.0.10.114 tell 10.0.10.1, length 28\n13:54:04.557178 ARP, Request who-has 10.0.10.113 tell 10.0.10.1, length 28\n13:54:04.557178 ARP, Request who-has 10.0.10.112 tell 10.0.10.1, length 28\n13:54:04.557179 ARP, Request who-has 10.0.10.111 tell 10.0.10.1, length 28\n13:54:04.557180 ARP, Request who-has 10.0.10.110 tell 10.0.10.1, length 28\n13:54:04.557180 ARP, Request who-has 10.0.10.109 tell 10.0.10.1, length 28\n13:54:04.557181 ARP, Request who-has 10.0.10.108 tell 10.0.10.1, length 28\n13:54:04.557182 ARP, Request who-has 10.0.10.107 tell 10.0.10.1, length 28\n13:54:04.557182 ARP, Request who-has 10.0.10.106 tell 10.0.10.1, length 28\n13:54:04.557183 ARP, Request who-has 10.0.10.105 tell 10.0.10.1, length 28\n13:54:04.557184 ARP, Request who-has 10.0.10.104 tell 10.0.10.1, length 28\n13:54:04.557184 ARP, Request who-has 10.0.10.101 tell 10.0.10.1, length 28\n13:54:04.557185 ARP, Request who-has 10.0.10.100 tell 10.0.10.1, length 28\n13:54:04.557185 ARP, Request who-has 10.0.10.97 tell 10.0.10.1, length 28\n13:54:04.557186 ARP, Request who-has 10.0.10.96 tell 10.0.10.1, length 28\n13:54:04.588884 ARP, Request who-has 10.0.10.193 tell 10.0.10.1, length 28\n13:54:04.588885 ARP, Request who-has 10.0.10.196 tell 10.0.10.1, length 28\n13:54:04.588886 ARP, Request who-has 10.0.10.199 tell 10.0.10.1, length 28\n13:54:04.588887 ARP, Request who-has 10.0.10.202 tell 10.0.10.1, length 28\n13:54:04.588887 ARP, Request who-has 10.0.10.205 tell 10.0.10.1, length 28\n13:54:04.588888 ARP, Request who-has 10.0.10.206 tell 10.0.10.1, length 28\n13:54:04.588889 ARP, Request who-has 10.0.10.209 tell 10.0.10.1, length 28\n13:54:04.588889 ARP, Request who-has 10.0.10.210 tell 10.0.10.1, length 28\n13:54:04.588890 ARP, Request who-has 10.0.10.213 tell 10.0.10.1, length 28\n13:54:04.588890 ARP, Request who-has 10.0.10.214 tell 10.0.10.1, length 28\n13:54:04.588891 ARP, Request who-has 10.0.10.217 tell 10.0.10.1, length 28\n13:54:04.588892 ARP, Request who-has 10.0.10.218 tell 10.0.10.1, length 28\n13:54:04.649103 ARP, Request who-has 10.0.10.62 tell 10.0.10.1, length 28\n13:54:04.649105 ARP, Request who-has 10.0.10.61 tell 10.0.10.1, length 28\n13:54:04.649105 ARP, Request who-has 10.0.10.59 tell 10.0.10.1, length 28\n13:54:04.649106 ARP, Request who-has 10.0.10.58 tell 10.0.10.1, length 28\n13:54:04.649107 ARP, Request who-has 10.0.10.57 tell 10.0.10.1, length 28\n13:54:04.649107 ARP, Request who-has 10.0.10.56 tell 10.0.10.1, length 28\n13:54:04.649108 ARP, Request who-has 10.0.10.55 tell 10.0.10.1, length 28\n13:54:04.649109 ARP, Request who-has 10.0.10.54 tell 10.0.10.1, length 28\n13:54:04.649109 ARP, Request who-has 10.0.10.53 tell 10.0.10.1, length 28\n13:54:04.649110 ARP, Request who-has 10.0.10.52 tell 10.0.10.1, length 28\n13:54:04.649111 ARP, Request who-has 10.0.10.51 tell 10.0.10.1, length 28\n13:54:04.649111 ARP, Request who-has 10.0.10.50 tell 10.0.10.1, length 28\n13:54:04.649112 ARP, Request who-has 10.0.10.49 tell 10.0.10.1, length 28\n13:54:04.649113 ARP, Request who-has 10.0.10.48 tell 10.0.10.1, length 28\n13:54:04.649113 ARP, Request who-has 10.0.10.47 tell 10.0.10.1, length 28\n13:54:04.649114 ARP, Request who-has 10.0.10.46 tell 10.0.10.1, length 28\n13:54:04.649114 ARP, Request who-has 10.0.10.45 tell 10.0.10.1, length 28\n13:54:04.649115 ARP, Request who-has 10.0.10.42 tell 10.0.10.1, length 28\n13:54:04.649116 ARP, Request who-has 10.0.10.41 tell 10.0.10.1, length 28\n13:54:04.649117 ARP, Request who-has 10.0.10.40 tell 10.0.10.1, length 28\n13:54:04.649117 ARP, Request who-has 10.0.10.39 tell 10.0.10.1, length 28\n13:54:04.649118 ARP, Request who-has 10.0.10.38 tell 10.0.10.1, length 28\n13:54:04.649119 ARP, Request who-has 10.0.10.37 tell 10.0.10.1, length 28\n13:54:04.649119 ARP, Request who-has 10.0.10.36 tell 10.0.10.1, length 28\n13:54:04.649120 ARP, Request who-has 10.0.10.32 tell 10.0.10.1, length 28\n13:54:04.649121 ARP, Request who-has 10.0.10.29 tell 10.0.10.1, length 28\n13:54:04.649121 ARP, Request who-has 10.0.10.28 tell 10.0.10.1, length 28\n13:54:04.649122 ARP, Request who-has 10.0.10.25 tell 10.0.10.1, length 28\n13:54:04.649123 ARP, Request who-has 10.0.10.24 tell 10.0.10.1, length 28\n13:54:04.649123 ARP, Request who-has 10.0.10.22 tell 10.0.10.1, length 28\n13:54:04.649124 ARP, Request who-has 10.0.10.21 tell 10.0.10.1, length 28\n13:54:04.649125 ARP, Request who-has 10.0.10.19 tell 10.0.10.1, length 28\n13:54:04.649125 ARP, Request who-has 10.0.10.18 tell 10.0.10.1, length 28\n13:54:04.649126 ARP, Request who-has 10.0.10.12 tell 10.0.10.1, length 28\n13:54:04.649127 ARP, Request who-has 10.0.10.254 tell 10.0.10.1, length 28\n13:54:04.649127 ARP, Request who-has 10.0.10.252 tell 10.0.10.1, length 28\n13:54:04.649128 ARP, Request who-has 10.0.10.251 tell 10.0.10.1, length 28\n13:54:04.649129 ARP, Request who-has 10.0.10.250 tell 10.0.10.1, length 28\n13:54:04.649129 ARP, Request who-has 10.0.10.249 tell 10.0.10.1, length 28\n13:54:04.649130 ARP, Request who-has 10.0.10.246 tell 10.0.10.1, length 28\n13:54:04.649131 ARP, Request who-has 10.0.10.245 tell 10.0.10.1, length 28\n13:54:04.649131 ARP, Request who-has 10.0.10.244 tell 10.0.10.1, length 28\n13:54:04.680926 ARP, Request who-has 10.0.10.253 tell 10.0.10.1, length 28\n13:54:04.680928 ARP, Request who-has 10.0.10.0 tell 10.0.10.1, length 28\n13:54:04.680928 ARP, Request who-has 10.0.10.11 tell 10.0.10.1, length 28\n13:54:04.680929 ARP, Request who-has 10.0.10.17 tell 10.0.10.1, length 28\n13:54:04.680930 ARP, Request who-has 10.0.10.20 tell 10.0.10.1, length 28\n13:54:04.680930 ARP, Request who-has 10.0.10.23 tell 10.0.10.1, length 28\n13:54:04.680931 ARP, Request who-has 10.0.10.26 tell 10.0.10.1, length 28\n13:54:04.680932 ARP, Request who-has 10.0.10.27 tell 10.0.10.1, length 28\n13:54:04.680932 ARP, Request who-has 10.0.10.30 tell 10.0.10.1, length 28\n13:54:04.680933 ARP, Request who-has 10.0.10.31 tell 10.0.10.1, length 28\n13:54:04.680934 ARP, Request who-has 10.0.10.34 tell 10.0.10.1, length 28\n13:54:04.680934 ARP, Request who-has 10.0.10.35 tell 10.0.10.1, length 28\n13:54:04.744975 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:04.744977 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:04.744978 ARP, Request who-has 10.0.10.43 tell 10.0.10.1, length 28\n13:54:04.744978 ARP, Request who-has 10.0.10.33 tell 10.0.10.1, length 28\n13:54:04.744979 ARP, Request who-has 10.0.10.247 tell 10.0.10.1, length 28\n13:54:04.744980 ARP, Request who-has 10.0.10.231 tell 10.0.10.1, length 28\n13:54:04.744981 ARP, Request who-has 10.0.10.230 tell 10.0.10.1, length 28\n13:54:04.744981 ARP, Request who-has 10.0.10.227 tell 10.0.10.1, length 28\n13:54:04.744982 ARP, Request who-has 10.0.10.226 tell 10.0.10.1, length 28\n13:54:04.744982 ARP, Request who-has 10.0.10.224 tell 10.0.10.1, length 28\n13:54:04.744983 ARP, Request who-has 10.0.10.223 tell 10.0.10.1, length 28\n13:54:04.744984 ARP, Request who-has 10.0.10.221 tell 10.0.10.1, length 28\n13:54:04.744984 ARP, Request who-has 10.0.10.220 tell 10.0.10.1, length 28\n13:54:04.744985 ARP, Request who-has 10.0.10.216 tell 10.0.10.1, length 28\n13:54:04.744986 ARP, Request who-has 10.0.10.212 tell 10.0.10.1, length 28\n13:54:04.744986 ARP, Request who-has 10.0.10.208 tell 10.0.10.1, length 28\n13:54:04.744987 ARP, Request who-has 10.0.10.204 tell 10.0.10.1, length 28\n13:54:04.744988 ARP, Request who-has 10.0.10.198 tell 10.0.10.1, length 28\n13:54:04.744988 ARP, Request who-has 10.0.10.195 tell 10.0.10.1, length 28\n13:54:04.744989 ARP, Request who-has 10.0.10.190 tell 10.0.10.1, length 28\n13:54:04.744989 ARP, Request who-has 10.0.10.189 tell 10.0.10.1, length 28\n13:54:04.776896 ARP, Request who-has 10.0.10.71 tell 10.0.10.1, length 28\n13:54:04.776898 ARP, Request who-has 10.0.10.77 tell 10.0.10.1, length 28\n13:54:04.776898 ARP, Request who-has 10.0.10.81 tell 10.0.10.1, length 28\n13:54:04.776899 ARP, Request who-has 10.0.10.85 tell 10.0.10.1, length 28\n13:54:04.776900 ARP, Request who-has 10.0.10.88 tell 10.0.10.1, length 28\n13:54:04.776900 ARP, Request who-has 10.0.10.91 tell 10.0.10.1, length 28\n13:54:04.776901 ARP, Request who-has 10.0.10.94 tell 10.0.10.1, length 28\n13:54:04.776902 ARP, Request who-has 10.0.10.95 tell 10.0.10.1, length 28\n13:54:04.776902 ARP, Request who-has 10.0.10.98 tell 10.0.10.1, length 28\n13:54:04.776903 ARP, Request who-has 10.0.10.99 tell 10.0.10.1, length 28\n13:54:04.776903 ARP, Request who-has 10.0.10.102 tell 10.0.10.1, length 28\n13:54:04.776904 ARP, Request who-has 10.0.10.103 tell 10.0.10.1, length 28\n13:54:04.872958 ARP, Request who-has 10.0.10.132 tell 10.0.10.1, length 28\n13:54:04.872959 ARP, Request who-has 10.0.10.135 tell 10.0.10.1, length 28\n13:54:04.872960 ARP, Request who-has 10.0.10.139 tell 10.0.10.1, length 28\n13:54:04.872961 ARP, Request who-has 10.0.10.143 tell 10.0.10.1, length 28\n13:54:04.872961 ARP, Request who-has 10.0.10.147 tell 10.0.10.1, length 28\n13:54:04.872962 ARP, Request who-has 10.0.10.152 tell 10.0.10.1, length 28\n13:54:04.872963 ARP, Request who-has 10.0.10.155 tell 10.0.10.1, length 28\n13:54:04.872963 ARP, Request who-has 10.0.10.158 tell 10.0.10.1, length 28\n13:54:04.872964 ARP, Request who-has 10.0.10.159 tell 10.0.10.1, length 28\n13:54:04.872965 ARP, Request who-has 10.0.10.162 tell 10.0.10.1, length 28\n13:54:04.872965 ARP, Request who-has 10.0.10.165 tell 10.0.10.1, length 28\n13:54:04.872966 ARP, Request who-has 10.0.10.166 tell 10.0.10.1, length 28\n13:54:04.872967 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:04.872967 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:04.872968 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:04.872969 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:04.940875 IP 10.0.10.1.57006 > 10.0.10.2.http: Flags [S], seq 2246678905, win 64240, options [mss 1460,sackOK,TS val 3851874680 ecr 0,nop,wscale 7], length 0\n13:54:04.940882 IP 10.0.10.2.http > 10.0.10.1.57006: Flags [R.], seq 0, ack 2246678906, win 0, length 0\n13:54:04.968925 ARP, Request who-has 10.0.10.191 tell 10.0.10.1, length 28\n13:54:04.968927 ARP, Request who-has 10.0.10.194 tell 10.0.10.1, length 28\n13:54:04.968927 ARP, Request who-has 10.0.10.197 tell 10.0.10.1, length 28\n13:54:04.968928 ARP, Request who-has 10.0.10.200 tell 10.0.10.1, length 28\n13:54:04.968929 ARP, Request who-has 10.0.10.207 tell 10.0.10.1, length 28\n13:54:04.968929 ARP, Request who-has 10.0.10.211 tell 10.0.10.1, length 28\n13:54:04.968930 ARP, Request who-has 10.0.10.215 tell 10.0.10.1, length 28\n13:54:04.968930 ARP, Request who-has 10.0.10.219 tell 10.0.10.1, length 28\n13:54:04.968931 ARP, Request who-has 10.0.10.222 tell 10.0.10.1, length 28\n13:54:04.968932 ARP, Request who-has 10.0.10.225 tell 10.0.10.1, length 28\n13:54:04.968932 ARP, Request who-has 10.0.10.228 tell 10.0.10.1, length 28\n13:54:04.968933 ARP, Request who-has 10.0.10.229 tell 10.0.10.1, length 28\n13:54:04.968934 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:05.064931 ARP, Request who-has 10.0.10.232 tell 10.0.10.1, length 28\n13:54:05.064933 ARP, Request who-has 10.0.10.233 tell 10.0.10.1, length 28\n13:54:05.064934 ARP, Request who-has 10.0.10.234 tell 10.0.10.1, length 28\n13:54:05.064934 ARP, Request who-has 10.0.10.235 tell 10.0.10.1, length 28\n13:54:05.064935 ARP, Request who-has 10.0.10.236 tell 10.0.10.1, length 28\n13:54:05.064936 ARP, Request who-has 10.0.10.237 tell 10.0.10.1, length 28\n13:54:05.064936 ARP, Request who-has 10.0.10.238 tell 10.0.10.1, length 28\n13:54:05.064937 ARP, Request who-has 10.0.10.239 tell 10.0.10.1, length 28\n13:54:05.064938 ARP, Request who-has 10.0.10.240 tell 10.0.10.1, length 28\n13:54:05.064938 ARP, Request who-has 10.0.10.241 tell 10.0.10.1, length 28\n13:54:05.064939 ARP, Request who-has 10.0.10.242 tell 10.0.10.1, length 28\n13:54:05.064939 ARP, Request who-has 10.0.10.243 tell 10.0.10.1, length 28\n13:54:05.192927 ARP, Request who-has 10.0.10.60 tell 10.0.10.1, length 28\n13:54:05.192929 ARP, Request who-has 10.0.10.63 tell 10.0.10.1, length 28\n13:54:05.192929 ARP, Request who-has 10.0.10.64 tell 10.0.10.1, length 28\n13:54:05.192930 ARP, Request who-has 10.0.10.66 tell 10.0.10.1, length 28\n13:54:05.192931 ARP, Request who-has 10.0.10.72 tell 10.0.10.1, length 28\n13:54:05.192932 ARP, Request who-has 10.0.10.78 tell 10.0.10.1, length 28\n13:54:05.192932 ARP, Request who-has 10.0.10.82 tell 10.0.10.1, length 28\n13:54:05.192933 ARP, Request who-has 10.0.10.86 tell 10.0.10.1, length 28\n13:54:05.192933 ARP, Request who-has 10.0.10.87 tell 10.0.10.1, length 28\n13:54:05.192934 ARP, Request who-has 10.0.10.89 tell 10.0.10.1, length 28\n13:54:05.192935 ARP, Request who-has 10.0.10.92 tell 10.0.10.1, length 28\n13:54:05.192935 ARP, Request who-has 10.0.10.93 tell 10.0.10.1, length 28\n13:54:05.289141 ARP, Request who-has 10.0.10.148 tell 10.0.10.1, length 28\n13:54:05.289143 ARP, Request who-has 10.0.10.153 tell 10.0.10.1, length 28\n13:54:05.289143 ARP, Request who-has 10.0.10.156 tell 10.0.10.1, length 28\n13:54:05.289144 ARP, Request who-has 10.0.10.157 tell 10.0.10.1, length 28\n13:54:05.289145 ARP, Request who-has 10.0.10.160 tell 10.0.10.1, length 28\n13:54:05.289145 ARP, Request who-has 10.0.10.161 tell 10.0.10.1, length 28\n13:54:05.289146 ARP, Request who-has 10.0.10.163 tell 10.0.10.1, length 28\n13:54:05.289147 ARP, Request who-has 10.0.10.167 tell 10.0.10.1, length 28\n13:54:05.289147 ARP, Request who-has 10.0.10.168 tell 10.0.10.1, length 28\n13:54:05.289148 ARP, Request who-has 10.0.10.169 tell 10.0.10.1, length 28\n13:54:05.289149 ARP, Request who-has 10.0.10.172 tell 10.0.10.1, length 28\n13:54:05.289149 ARP, Request who-has 10.0.10.173 tell 10.0.10.1, length 28\n13:54:05.577198 ARP, Request who-has 10.0.10.96 tell 10.0.10.1, length 28\n13:54:05.577202 ARP, Request who-has 10.0.10.97 tell 10.0.10.1, length 28\n13:54:05.577203 ARP, Request who-has 10.0.10.100 tell 10.0.10.1, length 28\n13:54:05.577203 ARP, Request who-has 10.0.10.101 tell 10.0.10.1, length 28\n13:54:05.577204 ARP, Request who-has 10.0.10.104 tell 10.0.10.1, length 28\n13:54:05.577205 ARP, Request who-has 10.0.10.105 tell 10.0.10.1, length 28\n13:54:05.577205 ARP, Request who-has 10.0.10.106 tell 10.0.10.1, length 28\n13:54:05.577206 ARP, Request who-has 10.0.10.107 tell 10.0.10.1, length 28\n13:54:05.577207 ARP, Request who-has 10.0.10.108 tell 10.0.10.1, length 28\n13:54:05.577207 ARP, Request who-has 10.0.10.109 tell 10.0.10.1, length 28\n13:54:05.577208 ARP, Request who-has 10.0.10.110 tell 10.0.10.1, length 28\n13:54:05.577209 ARP, Request who-has 10.0.10.111 tell 10.0.10.1, length 28\n13:54:05.577209 ARP, Request who-has 10.0.10.112 tell 10.0.10.1, length 28\n13:54:05.577210 ARP, Request who-has 10.0.10.113 tell 10.0.10.1, length 28\n13:54:05.577210 ARP, Request who-has 10.0.10.114 tell 10.0.10.1, length 28\n13:54:05.577211 ARP, Request who-has 10.0.10.115 tell 10.0.10.1, length 28\n13:54:05.577212 ARP, Request who-has 10.0.10.116 tell 10.0.10.1, length 28\n13:54:05.577212 ARP, Request who-has 10.0.10.117 tell 10.0.10.1, length 28\n13:54:05.577213 ARP, Request who-has 10.0.10.118 tell 10.0.10.1, length 28\n13:54:05.577214 ARP, Request who-has 10.0.10.119 tell 10.0.10.1, length 28\n13:54:05.577215 ARP, Request who-has 10.0.10.120 tell 10.0.10.1, length 28\n13:54:05.577216 ARP, Request who-has 10.0.10.121 tell 10.0.10.1, length 28\n13:54:05.577216 ARP, Request who-has 10.0.10.122 tell 10.0.10.1, length 28\n13:54:05.577217 ARP, Request who-has 10.0.10.123 tell 10.0.10.1, length 28\n13:54:05.577218 ARP, Request who-has 10.0.10.124 tell 10.0.10.1, length 28\n13:54:05.577218 ARP, Request who-has 10.0.10.125 tell 10.0.10.1, length 28\n13:54:05.577219 ARP, Request who-has 10.0.10.126 tell 10.0.10.1, length 28\n13:54:05.577220 ARP, Request who-has 10.0.10.127 tell 10.0.10.1, length 28\n13:54:05.577220 ARP, Request who-has 10.0.10.128 tell 10.0.10.1, length 28\n13:54:05.577221 ARP, Request who-has 10.0.10.129 tell 10.0.10.1, length 28\n13:54:05.577222 ARP, Request who-has 10.0.10.130 tell 10.0.10.1, length 28\n13:54:05.577222 ARP, Request who-has 10.0.10.133 tell 10.0.10.1, length 28\n13:54:05.577223 ARP, Request who-has 10.0.10.136 tell 10.0.10.1, length 28\n13:54:05.577224 ARP, Request who-has 10.0.10.140 tell 10.0.10.1, length 28\n13:54:05.577224 ARP, Request who-has 10.0.10.144 tell 10.0.10.1, length 28\n13:54:05.577225 ARP, Request who-has 10.0.10.164 tell 10.0.10.1, length 28\n13:54:05.577226 ARP, Request who-has 10.0.10.170 tell 10.0.10.1, length 28\n13:54:05.577226 ARP, Request who-has 10.0.10.171 tell 10.0.10.1, length 28\n13:54:05.577227 ARP, Request who-has 10.0.10.174 tell 10.0.10.1, length 28\n13:54:05.577228 ARP, Request who-has 10.0.10.175 tell 10.0.10.1, length 28\n13:54:05.577229 ARP, Request who-has 10.0.10.176 tell 10.0.10.1, length 28\n13:54:05.577229 ARP, Request who-has 10.0.10.177 tell 10.0.10.1, length 28\n13:54:05.577230 ARP, Request who-has 10.0.10.178 tell 10.0.10.1, length 28\n13:54:05.577231 ARP, Request who-has 10.0.10.179 tell 10.0.10.1, length 28\n13:54:05.577231 ARP, Request who-has 10.0.10.180 tell 10.0.10.1, length 28\n13:54:05.577232 ARP, Request who-has 10.0.10.181 tell 10.0.10.1, length 28\n13:54:05.577233 ARP, Request who-has 10.0.10.182 tell 10.0.10.1, length 28\n13:54:05.577233 ARP, Request who-has 10.0.10.183 tell 10.0.10.1, length 28\n13:54:05.577234 ARP, Request who-has 10.0.10.184 tell 10.0.10.1, length 28\n13:54:05.577234 ARP, Request who-has 10.0.10.185 tell 10.0.10.1, length 28\n13:54:05.577235 ARP, Request who-has 10.0.10.186 tell 10.0.10.1, length 28\n13:54:05.577236 ARP, Request who-has 10.0.10.187 tell 10.0.10.1, length 28\n13:54:05.577236 ARP, Request who-has 10.0.10.188 tell 10.0.10.1, length 28\n13:54:05.673096 ARP, Request who-has 10.0.10.244 tell 10.0.10.1, length 28\n13:54:05.673099 ARP, Request who-has 10.0.10.245 tell 10.0.10.1, length 28\n13:54:05.673100 ARP, Request who-has 10.0.10.246 tell 10.0.10.1, length 28\n13:54:05.673101 ARP, Request who-has 10.0.10.249 tell 10.0.10.1, length 28\n13:54:05.673101 ARP, Request who-has 10.0.10.250 tell 10.0.10.1, length 28\n13:54:05.673102 ARP, Request who-has 10.0.10.251 tell 10.0.10.1, length 28\n13:54:05.673103 ARP, Request who-has 10.0.10.252 tell 10.0.10.1, length 28\n13:54:05.673103 ARP, Request who-has 10.0.10.254 tell 10.0.10.1, length 28\n13:54:05.673104 ARP, Request who-has 10.0.10.12 tell 10.0.10.1, length 28\n13:54:05.673105 ARP, Request who-has 10.0.10.18 tell 10.0.10.1, length 28\n13:54:05.673105 ARP, Request who-has 10.0.10.19 tell 10.0.10.1, length 28\n13:54:05.673106 ARP, Request who-has 10.0.10.21 tell 10.0.10.1, length 28\n13:54:05.673107 ARP, Request who-has 10.0.10.22 tell 10.0.10.1, length 28\n13:54:05.673107 ARP, Request who-has 10.0.10.24 tell 10.0.10.1, length 28\n13:54:05.673108 ARP, Request who-has 10.0.10.25 tell 10.0.10.1, length 28\n13:54:05.673108 ARP, Request who-has 10.0.10.28 tell 10.0.10.1, length 28\n13:54:05.673109 ARP, Request who-has 10.0.10.29 tell 10.0.10.1, length 28\n13:54:05.673110 ARP, Request who-has 10.0.10.32 tell 10.0.10.1, length 28\n13:54:05.673110 ARP, Request who-has 10.0.10.36 tell 10.0.10.1, length 28\n13:54:05.673111 ARP, Request who-has 10.0.10.37 tell 10.0.10.1, length 28\n13:54:05.673112 ARP, Request who-has 10.0.10.38 tell 10.0.10.1, length 28\n13:54:05.673113 ARP, Request who-has 10.0.10.39 tell 10.0.10.1, length 28\n13:54:05.673113 ARP, Request who-has 10.0.10.40 tell 10.0.10.1, length 28\n13:54:05.673114 ARP, Request who-has 10.0.10.41 tell 10.0.10.1, length 28\n13:54:05.673115 ARP, Request who-has 10.0.10.42 tell 10.0.10.1, length 28\n13:54:05.673115 ARP, Request who-has 10.0.10.45 tell 10.0.10.1, length 28\n13:54:05.673116 ARP, Request who-has 10.0.10.46 tell 10.0.10.1, length 28\n13:54:05.673116 ARP, Request who-has 10.0.10.47 tell 10.0.10.1, length 28\n13:54:05.673117 ARP, Request who-has 10.0.10.48 tell 10.0.10.1, length 28\n13:54:05.673118 ARP, Request who-has 10.0.10.49 tell 10.0.10.1, length 28\n13:54:05.673118 ARP, Request who-has 10.0.10.50 tell 10.0.10.1, length 28\n13:54:05.673119 ARP, Request who-has 10.0.10.51 tell 10.0.10.1, length 28\n13:54:05.673120 ARP, Request who-has 10.0.10.52 tell 10.0.10.1, length 28\n13:54:05.673120 ARP, Request who-has 10.0.10.53 tell 10.0.10.1, length 28\n13:54:05.673121 ARP, Request who-has 10.0.10.54 tell 10.0.10.1, length 28\n13:54:05.673121 ARP, Request who-has 10.0.10.55 tell 10.0.10.1, length 28\n13:54:05.673122 ARP, Request who-has 10.0.10.56 tell 10.0.10.1, length 28\n13:54:05.673123 ARP, Request who-has 10.0.10.57 tell 10.0.10.1, length 28\n13:54:05.673123 ARP, Request who-has 10.0.10.58 tell 10.0.10.1, length 28\n13:54:05.673124 ARP, Request who-has 10.0.10.59 tell 10.0.10.1, length 28\n13:54:05.673125 ARP, Request who-has 10.0.10.61 tell 10.0.10.1, length 28\n13:54:05.673125 ARP, Request who-has 10.0.10.62 tell 10.0.10.1, length 28\n13:54:05.768982 ARP, Request who-has 10.0.10.189 tell 10.0.10.1, length 28\n13:54:05.768985 ARP, Request who-has 10.0.10.190 tell 10.0.10.1, length 28\n13:54:05.768986 ARP, Request who-has 10.0.10.195 tell 10.0.10.1, length 28\n13:54:05.768986 ARP, Request who-has 10.0.10.198 tell 10.0.10.1, length 28\n13:54:05.768987 ARP, Request who-has 10.0.10.204 tell 10.0.10.1, length 28\n13:54:05.768988 ARP, Request who-has 10.0.10.208 tell 10.0.10.1, length 28\n13:54:05.768988 ARP, Request who-has 10.0.10.212 tell 10.0.10.1, length 28\n13:54:05.768989 ARP, Request who-has 10.0.10.216 tell 10.0.10.1, length 28\n13:54:05.768990 ARP, Request who-has 10.0.10.220 tell 10.0.10.1, length 28\n13:54:05.768990 ARP, Request who-has 10.0.10.221 tell 10.0.10.1, length 28\n13:54:05.768991 ARP, Request who-has 10.0.10.223 tell 10.0.10.1, length 28\n13:54:05.768991 ARP, Request who-has 10.0.10.224 tell 10.0.10.1, length 28\n13:54:05.768992 ARP, Request who-has 10.0.10.226 tell 10.0.10.1, length 28\n13:54:05.768993 ARP, Request who-has 10.0.10.227 tell 10.0.10.1, length 28\n13:54:05.768993 ARP, Request who-has 10.0.10.230 tell 10.0.10.1, length 28\n13:54:05.768994 ARP, Request who-has 10.0.10.231 tell 10.0.10.1, length 28\n13:54:05.768995 ARP, Request who-has 10.0.10.247 tell 10.0.10.1, length 28\n13:54:05.768995 ARP, Request who-has 10.0.10.33 tell 10.0.10.1, length 28\n13:54:05.768996 ARP, Request who-has 10.0.10.43 tell 10.0.10.1, length 28\n13:54:05.768997 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:05.768997 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:05.897167 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:05.897170 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:05.993145 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:07.432845 ARP, Request who-has 10.0.10.1 tell 10.0.10.2, length 28\n13:54:07.432890 ARP, Request who-has 10.0.10.2 tell 10.0.10.1, length 28\n13:54:07.432893 ARP, Reply 10.0.10.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n13:54:07.432898 ARP, Reply 10.0.10.1 is-at 00:50:56:94:55:70 (oui Unknown), length 28\n

    This generated a lot of broadcast traffic! For practice, see if you can find the ARP request and response packets for host1 and host2 in the packet capture output. We can tell that they were properly discovered in the output from host1.

    Now check the output on host4, which should pick up the above packets if it was still on the same broadcasting domain:

    eron@host4:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n

    Still nothing? Awesome, there should be no packets yet if everything has been set up right.

    Now we're going to perform a quick scan of the other subnet and examine the results. Starting on host3, run the following:

    nmap -sn 10.0.10.0/24\n

    When nmap is finished, cancel the packet capture on host4, and then check the output on both host3 and host4:

    eron@host3:~$ nmap -sn 10.0.20.0/24\nStarting Nmap 7.80 ( https://nmap.org ) at 2023-06-27 13:54 UTC\nNmap scan report for 10.0.20.3\nHost is up (0.00052s latency).\nNmap scan report for 10.0.20.4\nHost is up (0.00040s latency).\nNmap done: 256 IP addresses (2 hosts up) scanned in 15.91 seconds\n
    eron@host4:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n13:54:49.924495 ARP, Request who-has 10.0.20.1 tell 10.0.20.3, length 28\n13:54:49.924534 ARP, Request who-has 10.0.20.2 tell 10.0.20.3, length 28\n13:54:49.924579 ARP, Request who-has 10.0.20.4 tell 10.0.20.3, length 28\n13:54:49.924593 ARP, Reply 10.0.20.4 is-at 00:50:56:ad:24:4a (oui Unknown), length 28\n13:54:49.924613 IP 10.0.20.3.57422 > 10.0.20.4.http: Flags [S], seq 2960543896, win 64240, options [mss 1460,sackOK,TS val 230221782 ecr 0,nop,wscale 7], length 0\n13:54:49.924619 IP 10.0.20.4.http > 10.0.20.3.57422: Flags [R.], seq 0, ack 2960543897, win 0, length 0\n13:54:49.924956 ARP, Request who-has 10.0.20.5 tell 10.0.20.3, length 28\n13:54:49.924977 ARP, Request who-has 10.0.20.6 tell 10.0.20.3, length 28\n13:54:49.924995 ARP, Request who-has 10.0.20.7 tell 10.0.20.3, length 28\n13:54:49.925013 ARP, Request who-has 10.0.20.8 tell 10.0.20.3, length 28\n13:54:49.925030 ARP, Request who-has 10.0.20.9 tell 10.0.20.3, length 28\n13:54:49.925047 ARP, Request who-has 10.0.20.10 tell 10.0.20.3, length 28\n13:54:49.925135 ARP, Request who-has 10.0.20.13 tell 10.0.20.3, length 28\n13:54:49.925151 ARP, Request who-has 10.0.20.14 tell 10.0.20.3, length 28\n13:54:49.925182 ARP, Request who-has 10.0.20.15 tell 10.0.20.3, length 28\n13:54:49.925199 ARP, Request who-has 10.0.20.16 tell 10.0.20.3, length 28\n13:54:50.025457 ARP, Request who-has 10.0.20.19 tell 10.0.20.3, length 28\n13:54:50.025481 ARP, Request who-has 10.0.20.20 tell 10.0.20.3, length 28\n13:54:50.025504 ARP, Request who-has 10.0.20.21 tell 10.0.20.3, length 28\n13:54:50.025522 ARP, Request who-has 10.0.20.22 tell 10.0.20.3, length 28\n13:54:50.025540 ARP, Request who-has 10.0.20.23 tell 10.0.20.3, length 28\n13:54:50.025557 ARP, Request who-has 10.0.20.24 tell 10.0.20.3, length 28\n13:54:50.025576 ARP, Request who-has 10.0.20.25 tell 10.0.20.3, length 28\n13:54:50.025594 ARP, Request who-has 10.0.20.26 tell 10.0.20.3, length 28\n13:54:50.025611 ARP, Request who-has 10.0.20.27 tell 10.0.20.3, length 28\n13:54:50.025629 ARP, Request who-has 10.0.20.28 tell 10.0.20.3, length 28\n13:54:50.025646 ARP, Request who-has 10.0.20.29 tell 10.0.20.3, length 28\n13:54:50.025664 ARP, Request who-has 10.0.20.30 tell 10.0.20.3, length 28\n13:54:50.125512 ARP, Request who-has 10.0.20.93 tell 10.0.20.3, length 28\n13:54:50.125582 ARP, Request who-has 10.0.20.96 tell 10.0.20.3, length 28\n13:54:50.125602 ARP, Request who-has 10.0.20.97 tell 10.0.20.3, length 28\n13:54:50.125619 ARP, Request who-has 10.0.20.98 tell 10.0.20.3, length 28\n13:54:50.125690 ARP, Request who-has 10.0.20.101 tell 10.0.20.3, length 28\n13:54:50.125708 ARP, Request who-has 10.0.20.102 tell 10.0.20.3, length 28\n13:54:50.125725 ARP, Request who-has 10.0.20.103 tell 10.0.20.3, length 28\n13:54:50.125743 ARP, Request who-has 10.0.20.104 tell 10.0.20.3, length 28\n13:54:50.125760 ARP, Request who-has 10.0.20.105 tell 10.0.20.3, length 28\n13:54:50.125778 ARP, Request who-has 10.0.20.106 tell 10.0.20.3, length 28\n13:54:50.125839 ARP, Request who-has 10.0.20.109 tell 10.0.20.3, length 28\n13:54:50.125858 ARP, Request who-has 10.0.20.110 tell 10.0.20.3, length 28\n13:54:50.225570 ARP, Request who-has 10.0.20.163 tell 10.0.20.3, length 28\n13:54:50.225637 ARP, Request who-has 10.0.20.166 tell 10.0.20.3, length 28\n13:54:50.225701 ARP, Request who-has 10.0.20.169 tell 10.0.20.3, length 28\n13:54:50.225719 ARP, Request who-has 10.0.20.170 tell 10.0.20.3, length 28\n13:54:50.225783 ARP, Request who-has 10.0.20.173 tell 10.0.20.3, length 28\n13:54:50.225801 ARP, Request who-has 10.0.20.174 tell 10.0.20.3, length 28\n13:54:50.225818 ARP, Request who-has 10.0.20.175 tell 10.0.20.3, length 28\n13:54:50.225900 ARP, Request who-has 10.0.20.178 tell 10.0.20.3, length 28\n13:54:50.225918 ARP, Request who-has 10.0.20.179 tell 10.0.20.3, length 28\n13:54:50.225936 ARP, Request who-has 10.0.20.180 tell 10.0.20.3, length 28\n13:54:50.225952 ARP, Request who-has 10.0.20.181 tell 10.0.20.3, length 28\n13:54:50.226013 ARP, Request who-has 10.0.20.184 tell 10.0.20.3, length 28\n13:54:50.325608 ARP, Request who-has 10.0.20.223 tell 10.0.20.3, length 28\n13:54:50.325675 ARP, Request who-has 10.0.20.226 tell 10.0.20.3, length 28\n13:54:50.325737 ARP, Request who-has 10.0.20.229 tell 10.0.20.3, length 28\n13:54:50.325797 ARP, Request who-has 10.0.20.232 tell 10.0.20.3, length 28\n13:54:50.325861 ARP, Request who-has 10.0.20.235 tell 10.0.20.3, length 28\n13:54:50.325880 ARP, Request who-has 10.0.20.236 tell 10.0.20.3, length 28\n13:54:50.325897 ARP, Request who-has 10.0.20.237 tell 10.0.20.3, length 28\n13:54:50.325960 ARP, Request who-has 10.0.20.240 tell 10.0.20.3, length 28\n13:54:50.325979 ARP, Request who-has 10.0.20.241 tell 10.0.20.3, length 28\n13:54:50.326040 ARP, Request who-has 10.0.20.244 tell 10.0.20.3, length 28\n13:54:50.326059 ARP, Request who-has 10.0.20.245 tell 10.0.20.3, length 28\n13:54:50.326118 ARP, Request who-has 10.0.20.248 tell 10.0.20.3, length 28\n13:54:50.425662 ARP, Request who-has 10.0.20.31 tell 10.0.20.3, length 28\n13:54:50.425729 ARP, Request who-has 10.0.20.34 tell 10.0.20.3, length 28\n13:54:50.425791 ARP, Request who-has 10.0.20.37 tell 10.0.20.3, length 28\n13:54:50.425851 ARP, Request who-has 10.0.20.40 tell 10.0.20.3, length 28\n13:54:50.425911 ARP, Request who-has 10.0.20.43 tell 10.0.20.3, length 28\n13:54:50.425972 ARP, Request who-has 10.0.20.46 tell 10.0.20.3, length 28\n13:54:50.425990 ARP, Request who-has 10.0.20.47 tell 10.0.20.3, length 28\n13:54:50.426052 ARP, Request who-has 10.0.20.50 tell 10.0.20.3, length 28\n13:54:50.426070 ARP, Request who-has 10.0.20.51 tell 10.0.20.3, length 28\n13:54:50.426132 ARP, Request who-has 10.0.20.54 tell 10.0.20.3, length 28\n13:54:50.426151 ARP, Request who-has 10.0.20.55 tell 10.0.20.3, length 28\n13:54:50.426216 ARP, Request who-has 10.0.20.58 tell 10.0.20.3, length 28\n13:54:50.525719 ARP, Request who-has 10.0.20.87 tell 10.0.20.3, length 28\n13:54:50.525786 ARP, Request who-has 10.0.20.90 tell 10.0.20.3, length 28\n13:54:50.525849 ARP, Request who-has 10.0.20.94 tell 10.0.20.3, length 28\n13:54:50.525910 ARP, Request who-has 10.0.20.99 tell 10.0.20.3, length 28\n13:54:50.525970 ARP, Request who-has 10.0.20.107 tell 10.0.20.3, length 28\n13:54:50.526032 ARP, Request who-has 10.0.20.111 tell 10.0.20.3, length 28\n13:54:50.526050 ARP, Request who-has 10.0.20.112 tell 10.0.20.3, length 28\n13:54:50.526111 ARP, Request who-has 10.0.20.115 tell 10.0.20.3, length 28\n13:54:50.526129 ARP, Request who-has 10.0.20.116 tell 10.0.20.3, length 28\n13:54:50.526191 ARP, Request who-has 10.0.20.119 tell 10.0.20.3, length 28\n13:54:50.526209 ARP, Request who-has 10.0.20.120 tell 10.0.20.3, length 28\n13:54:50.526269 ARP, Request who-has 10.0.20.123 tell 10.0.20.3, length 28\n13:54:50.625771 ARP, Request who-has 10.0.20.152 tell 10.0.20.3, length 28\n13:54:50.625838 ARP, Request who-has 10.0.20.155 tell 10.0.20.3, length 28\n13:54:50.625900 ARP, Request who-has 10.0.20.158 tell 10.0.20.3, length 28\n13:54:50.625965 ARP, Request who-has 10.0.20.161 tell 10.0.20.3, length 28\n13:54:50.626026 ARP, Request who-has 10.0.20.164 tell 10.0.20.3, length 28\n13:54:50.626086 ARP, Request who-has 10.0.20.167 tell 10.0.20.3, length 28\n13:54:50.626148 ARP, Request who-has 10.0.20.171 tell 10.0.20.3, length 28\n13:54:50.626166 ARP, Request who-has 10.0.20.172 tell 10.0.20.3, length 28\n13:54:50.626227 ARP, Request who-has 10.0.20.176 tell 10.0.20.3, length 28\n13:54:50.626245 ARP, Request who-has 10.0.20.177 tell 10.0.20.3, length 28\n13:54:50.626306 ARP, Request who-has 10.0.20.182 tell 10.0.20.3, length 28\n13:54:50.626324 ARP, Request who-has 10.0.20.183 tell 10.0.20.3, length 28\n13:54:50.725827 ARP, Request who-has 10.0.20.212 tell 10.0.20.3, length 28\n13:54:50.725894 ARP, Request who-has 10.0.20.215 tell 10.0.20.3, length 28\n13:54:50.725955 ARP, Request who-has 10.0.20.218 tell 10.0.20.3, length 28\n13:54:50.726022 ARP, Request who-has 10.0.20.221 tell 10.0.20.3, length 28\n13:54:50.726083 ARP, Request who-has 10.0.20.224 tell 10.0.20.3, length 28\n13:54:50.726143 ARP, Request who-has 10.0.20.227 tell 10.0.20.3, length 28\n13:54:50.726205 ARP, Request who-has 10.0.20.230 tell 10.0.20.3, length 28\n13:54:50.726226 ARP, Request who-has 10.0.20.231 tell 10.0.20.3, length 28\n13:54:50.726289 ARP, Request who-has 10.0.20.234 tell 10.0.20.3, length 28\n13:54:50.726307 ARP, Request who-has 10.0.20.238 tell 10.0.20.3, length 28\n13:54:50.726369 ARP, Request who-has 10.0.20.242 tell 10.0.20.3, length 28\n13:54:50.726388 ARP, Request who-has 10.0.20.243 tell 10.0.20.3, length 28\n13:54:50.825885 ARP, Request who-has 10.0.20.18 tell 10.0.20.3, length 28\n13:54:50.825956 ARP, Request who-has 10.0.20.32 tell 10.0.20.3, length 28\n13:54:50.826018 ARP, Request who-has 10.0.20.35 tell 10.0.20.3, length 28\n13:54:50.826079 ARP, Request who-has 10.0.20.38 tell 10.0.20.3, length 28\n13:54:50.826141 ARP, Request who-has 10.0.20.41 tell 10.0.20.3, length 28\n13:54:50.826203 ARP, Request who-has 10.0.20.44 tell 10.0.20.3, length 28\n13:54:50.826265 ARP, Request who-has 10.0.20.48 tell 10.0.20.3, length 28\n13:54:50.826283 ARP, Request who-has 10.0.20.49 tell 10.0.20.3, length 28\n13:54:50.826342 ARP, Request who-has 10.0.20.52 tell 10.0.20.3, length 28\n13:54:50.826406 ARP, Request who-has 10.0.20.56 tell 10.0.20.3, length 28\n13:54:50.826469 ARP, Request who-has 10.0.20.59 tell 10.0.20.3, length 28\n13:54:50.826489 ARP, Request who-has 10.0.20.60 tell 10.0.20.3, length 28\n13:54:50.925934 ARP, Request who-has 10.0.20.83 tell 10.0.20.3, length 28\n13:54:50.926002 ARP, Request who-has 10.0.20.86 tell 10.0.20.3, length 28\n13:54:50.926065 ARP, Request who-has 10.0.20.89 tell 10.0.20.3, length 28\n13:54:50.926126 ARP, Request who-has 10.0.20.92 tell 10.0.20.3, length 28\n13:54:50.926189 ARP, Request who-has 10.0.20.95 tell 10.0.20.3, length 28\n13:54:50.926249 ARP, Request who-has 10.0.20.100 tell 10.0.20.3, length 28\n13:54:50.926309 ARP, Request who-has 10.0.20.108 tell 10.0.20.3, length 28\n13:54:50.926370 ARP, Request who-has 10.0.20.113 tell 10.0.20.3, length 28\n13:54:50.926437 ARP, Request who-has 10.0.20.117 tell 10.0.20.3, length 28\n13:54:50.926498 ARP, Request who-has 10.0.20.121 tell 10.0.20.3, length 28\n13:54:50.926561 ARP, Request who-has 10.0.20.124 tell 10.0.20.3, length 28\n13:54:50.926582 ARP, Request who-has 10.0.20.125 tell 10.0.20.3, length 28\n13:54:50.952936 ARP, Request who-has 10.0.20.16 tell 10.0.20.3, length 28\n13:54:50.952937 ARP, Request who-has 10.0.20.15 tell 10.0.20.3, length 28\n13:54:50.952938 ARP, Request who-has 10.0.20.14 tell 10.0.20.3, length 28\n13:54:50.952938 ARP, Request who-has 10.0.20.13 tell 10.0.20.3, length 28\n13:54:50.952939 ARP, Request who-has 10.0.20.10 tell 10.0.20.3, length 28\n13:54:50.952940 ARP, Request who-has 10.0.20.9 tell 10.0.20.3, length 28\n13:54:50.952940 ARP, Request who-has 10.0.20.8 tell 10.0.20.3, length 28\n13:54:50.952941 ARP, Request who-has 10.0.20.7 tell 10.0.20.3, length 28\n13:54:50.952942 ARP, Request who-has 10.0.20.6 tell 10.0.20.3, length 28\n13:54:50.952942 ARP, Request who-has 10.0.20.5 tell 10.0.20.3, length 28\n13:54:50.952943 ARP, Request who-has 10.0.20.2 tell 10.0.20.3, length 28\n13:54:50.952943 ARP, Request who-has 10.0.20.1 tell 10.0.20.3, length 28\n13:54:51.048924 ARP, Request who-has 10.0.20.30 tell 10.0.20.3, length 28\n13:54:51.048926 ARP, Request who-has 10.0.20.29 tell 10.0.20.3, length 28\n13:54:51.048927 ARP, Request who-has 10.0.20.28 tell 10.0.20.3, length 28\n13:54:51.048928 ARP, Request who-has 10.0.20.27 tell 10.0.20.3, length 28\n13:54:51.048928 ARP, Request who-has 10.0.20.26 tell 10.0.20.3, length 28\n13:54:51.048929 ARP, Request who-has 10.0.20.25 tell 10.0.20.3, length 28\n13:54:51.048930 ARP, Request who-has 10.0.20.24 tell 10.0.20.3, length 28\n13:54:51.048930 ARP, Request who-has 10.0.20.23 tell 10.0.20.3, length 28\n13:54:51.048931 ARP, Request who-has 10.0.20.22 tell 10.0.20.3, length 28\n13:54:51.048931 ARP, Request who-has 10.0.20.21 tell 10.0.20.3, length 28\n13:54:51.048932 ARP, Request who-has 10.0.20.20 tell 10.0.20.3, length 28\n13:54:51.048933 ARP, Request who-has 10.0.20.19 tell 10.0.20.3, length 28\n13:54:51.144945 ARP, Request who-has 10.0.20.110 tell 10.0.20.3, length 28\n13:54:51.144949 ARP, Request who-has 10.0.20.109 tell 10.0.20.3, length 28\n13:54:51.144949 ARP, Request who-has 10.0.20.106 tell 10.0.20.3, length 28\n13:54:51.144950 ARP, Request who-has 10.0.20.105 tell 10.0.20.3, length 28\n13:54:51.144950 ARP, Request who-has 10.0.20.104 tell 10.0.20.3, length 28\n13:54:51.144951 ARP, Request who-has 10.0.20.103 tell 10.0.20.3, length 28\n13:54:51.144951 ARP, Request who-has 10.0.20.102 tell 10.0.20.3, length 28\n13:54:51.144952 ARP, Request who-has 10.0.20.101 tell 10.0.20.3, length 28\n13:54:51.144953 ARP, Request who-has 10.0.20.98 tell 10.0.20.3, length 28\n13:54:51.144953 ARP, Request who-has 10.0.20.97 tell 10.0.20.3, length 28\n13:54:51.144954 ARP, Request who-has 10.0.20.96 tell 10.0.20.3, length 28\n13:54:51.144954 ARP, Request who-has 10.0.20.93 tell 10.0.20.3, length 28\n13:54:51.226935 IP 10.0.20.3.57436 > 10.0.20.4.http: Flags [S], seq 2574521844, win 64240, options [mss 1460,sackOK,TS val 230223085 ecr 0,nop,wscale 7], length 0\n13:54:51.226947 IP 10.0.20.4.http > 10.0.20.3.57436: Flags [R.], seq 0, ack 2574521845, win 0, length 0\n13:54:51.227247 ARP, Request who-has 10.0.20.11 tell 10.0.20.3, length 28\n13:54:51.227269 ARP, Request who-has 10.0.20.12 tell 10.0.20.3, length 28\n13:54:51.227322 ARP, Request who-has 10.0.20.17 tell 10.0.20.3, length 28\n13:54:51.227454 ARP, Request who-has 10.0.20.33 tell 10.0.20.3, length 28\n13:54:51.227471 ARP, Request who-has 10.0.20.36 tell 10.0.20.3, length 28\n13:54:51.227488 ARP, Request who-has 10.0.20.39 tell 10.0.20.3, length 28\n13:54:51.227504 ARP, Request who-has 10.0.20.42 tell 10.0.20.3, length 28\n13:54:51.227521 ARP, Request who-has 10.0.20.45 tell 10.0.20.3, length 28\n13:54:51.227542 ARP, Request who-has 10.0.20.53 tell 10.0.20.3, length 28\n13:54:51.227559 ARP, Request who-has 10.0.20.57 tell 10.0.20.3, length 28\n13:54:51.227578 ARP, Request who-has 10.0.20.61 tell 10.0.20.3, length 28\n13:54:51.227594 ARP, Request who-has 10.0.20.62 tell 10.0.20.3, length 28\n13:54:51.227614 ARP, Request who-has 10.0.20.63 tell 10.0.20.3, length 28\n13:54:51.227640 ARP, Request who-has 10.0.20.64 tell 10.0.20.3, length 28\n13:54:51.227667 ARP, Request who-has 10.0.20.65 tell 10.0.20.3, length 28\n13:54:51.227682 ARP, Request who-has 10.0.20.66 tell 10.0.20.3, length 28\n13:54:51.227697 ARP, Request who-has 10.0.20.67 tell 10.0.20.3, length 28\n13:54:51.227817 ARP, Request who-has 10.0.20.70 tell 10.0.20.3, length 28\n13:54:51.227848 ARP, Request who-has 10.0.20.71 tell 10.0.20.3, length 28\n13:54:51.227870 ARP, Request who-has 10.0.20.72 tell 10.0.20.3, length 28\n13:54:51.227888 ARP, Request who-has 10.0.20.73 tell 10.0.20.3, length 28\n13:54:51.227908 ARP, Request who-has 10.0.20.74 tell 10.0.20.3, length 28\n13:54:51.227927 ARP, Request who-has 10.0.20.75 tell 10.0.20.3, length 28\n13:54:51.227945 ARP, Request who-has 10.0.20.76 tell 10.0.20.3, length 28\n13:54:51.227963 ARP, Request who-has 10.0.20.77 tell 10.0.20.3, length 28\n13:54:51.227981 ARP, Request who-has 10.0.20.78 tell 10.0.20.3, length 28\n13:54:51.228003 ARP, Request who-has 10.0.20.79 tell 10.0.20.3, length 28\n13:54:51.228037 ARP, Request who-has 10.0.20.80 tell 10.0.20.3, length 28\n13:54:51.228055 ARP, Request who-has 10.0.20.81 tell 10.0.20.3, length 28\n13:54:51.228081 ARP, Request who-has 10.0.20.82 tell 10.0.20.3, length 28\n13:54:51.228097 ARP, Request who-has 10.0.20.84 tell 10.0.20.3, length 28\n13:54:51.228111 ARP, Request who-has 10.0.20.85 tell 10.0.20.3, length 28\n13:54:51.228126 ARP, Request who-has 10.0.20.88 tell 10.0.20.3, length 28\n13:54:51.228141 ARP, Request who-has 10.0.20.91 tell 10.0.20.3, length 28\n13:54:51.240943 ARP, Request who-has 10.0.20.184 tell 10.0.20.3, length 28\n13:54:51.240946 ARP, Request who-has 10.0.20.181 tell 10.0.20.3, length 28\n13:54:51.240956 ARP, Request who-has 10.0.20.180 tell 10.0.20.3, length 28\n13:54:51.240957 ARP, Request who-has 10.0.20.179 tell 10.0.20.3, length 28\n13:54:51.240957 ARP, Request who-has 10.0.20.178 tell 10.0.20.3, length 28\n13:54:51.240958 ARP, Request who-has 10.0.20.175 tell 10.0.20.3, length 28\n13:54:51.240959 ARP, Request who-has 10.0.20.174 tell 10.0.20.3, length 28\n13:54:51.240959 ARP, Request who-has 10.0.20.173 tell 10.0.20.3, length 28\n13:54:51.240960 ARP, Request who-has 10.0.20.170 tell 10.0.20.3, length 28\n13:54:51.240960 ARP, Request who-has 10.0.20.169 tell 10.0.20.3, length 28\n13:54:51.240961 ARP, Request who-has 10.0.20.166 tell 10.0.20.3, length 28\n13:54:51.240962 ARP, Request who-has 10.0.20.163 tell 10.0.20.3, length 28\n13:54:51.327457 ARP, Request who-has 10.0.20.126 tell 10.0.20.3, length 28\n13:54:51.327490 ARP, Request who-has 10.0.20.127 tell 10.0.20.3, length 28\n13:54:51.327781 ARP, Request who-has 10.0.20.130 tell 10.0.20.3, length 28\n13:54:51.327809 ARP, Request who-has 10.0.20.131 tell 10.0.20.3, length 28\n13:54:51.327827 ARP, Request who-has 10.0.20.132 tell 10.0.20.3, length 28\n13:54:51.327843 ARP, Request who-has 10.0.20.133 tell 10.0.20.3, length 28\n13:54:51.327864 ARP, Request who-has 10.0.20.134 tell 10.0.20.3, length 28\n13:54:51.328013 ARP, Request who-has 10.0.20.137 tell 10.0.20.3, length 28\n13:54:51.328053 ARP, Request who-has 10.0.20.138 tell 10.0.20.3, length 28\n13:54:51.328079 ARP, Request who-has 10.0.20.139 tell 10.0.20.3, length 28\n13:54:51.328095 ARP, Request who-has 10.0.20.140 tell 10.0.20.3, length 28\n13:54:51.328111 ARP, Request who-has 10.0.20.141 tell 10.0.20.3, length 28\n13:54:51.328127 ARP, Request who-has 10.0.20.142 tell 10.0.20.3, length 28\n13:54:51.328143 ARP, Request who-has 10.0.20.143 tell 10.0.20.3, length 28\n13:54:51.328160 ARP, Request who-has 10.0.20.144 tell 10.0.20.3, length 28\n13:54:51.328178 ARP, Request who-has 10.0.20.145 tell 10.0.20.3, length 28\n13:54:51.328194 ARP, Request who-has 10.0.20.146 tell 10.0.20.3, length 28\n13:54:51.328211 ARP, Request who-has 10.0.20.147 tell 10.0.20.3, length 28\n13:54:51.328226 ARP, Request who-has 10.0.20.148 tell 10.0.20.3, length 28\n13:54:51.328242 ARP, Request who-has 10.0.20.149 tell 10.0.20.3, length 28\n13:54:51.328258 ARP, Request who-has 10.0.20.150 tell 10.0.20.3, length 28\n13:54:51.328279 ARP, Request who-has 10.0.20.151 tell 10.0.20.3, length 28\n13:54:51.328490 ARP, Request who-has 10.0.20.154 tell 10.0.20.3, length 28\n13:54:51.328509 ARP, Request who-has 10.0.20.156 tell 10.0.20.3, length 28\n13:54:51.328525 ARP, Request who-has 10.0.20.157 tell 10.0.20.3, length 28\n13:54:51.328541 ARP, Request who-has 10.0.20.159 tell 10.0.20.3, length 28\n13:54:51.328557 ARP, Request who-has 10.0.20.160 tell 10.0.20.3, length 28\n13:54:51.328581 ARP, Request who-has 10.0.20.162 tell 10.0.20.3, length 28\n13:54:51.328606 ARP, Request who-has 10.0.20.165 tell 10.0.20.3, length 28\n13:54:51.328630 ARP, Request who-has 10.0.20.168 tell 10.0.20.3, length 28\n13:54:51.336932 ARP, Request who-has 10.0.20.248 tell 10.0.20.3, length 28\n13:54:51.336934 ARP, Request who-has 10.0.20.245 tell 10.0.20.3, length 28\n13:54:51.336935 ARP, Request who-has 10.0.20.244 tell 10.0.20.3, length 28\n13:54:51.336935 ARP, Request who-has 10.0.20.241 tell 10.0.20.3, length 28\n13:54:51.336936 ARP, Request who-has 10.0.20.240 tell 10.0.20.3, length 28\n13:54:51.336946 ARP, Request who-has 10.0.20.237 tell 10.0.20.3, length 28\n13:54:51.336947 ARP, Request who-has 10.0.20.236 tell 10.0.20.3, length 28\n13:54:51.336948 ARP, Request who-has 10.0.20.235 tell 10.0.20.3, length 28\n13:54:51.336948 ARP, Request who-has 10.0.20.232 tell 10.0.20.3, length 28\n13:54:51.336949 ARP, Request who-has 10.0.20.229 tell 10.0.20.3, length 28\n13:54:51.336949 ARP, Request who-has 10.0.20.226 tell 10.0.20.3, length 28\n13:54:51.336950 ARP, Request who-has 10.0.20.223 tell 10.0.20.3, length 28\n13:54:51.427504 ARP, Request who-has 10.0.20.199 tell 10.0.20.3, length 28\n13:54:51.427547 ARP, Request who-has 10.0.20.200 tell 10.0.20.3, length 28\n13:54:51.427661 ARP, Request who-has 10.0.20.203 tell 10.0.20.3, length 28\n13:54:51.427699 ARP, Request who-has 10.0.20.204 tell 10.0.20.3, length 28\n13:54:51.427734 ARP, Request who-has 10.0.20.205 tell 10.0.20.3, length 28\n13:54:51.427763 ARP, Request who-has 10.0.20.206 tell 10.0.20.3, length 28\n13:54:51.427793 ARP, Request who-has 10.0.20.207 tell 10.0.20.3, length 28\n13:54:51.427945 ARP, Request who-has 10.0.20.210 tell 10.0.20.3, length 28\n13:54:51.427981 ARP, Request who-has 10.0.20.211 tell 10.0.20.3, length 28\n13:54:51.428003 ARP, Request who-has 10.0.20.213 tell 10.0.20.3, length 28\n13:54:51.428019 ARP, Request who-has 10.0.20.214 tell 10.0.20.3, length 28\n13:54:51.428036 ARP, Request who-has 10.0.20.216 tell 10.0.20.3, length 28\n13:54:51.428071 ARP, Request who-has 10.0.20.217 tell 10.0.20.3, length 28\n13:54:51.428088 ARP, Request who-has 10.0.20.219 tell 10.0.20.3, length 28\n13:54:51.428105 ARP, Request who-has 10.0.20.220 tell 10.0.20.3, length 28\n13:54:51.428124 ARP, Request who-has 10.0.20.222 tell 10.0.20.3, length 28\n13:54:51.428149 ARP, Request who-has 10.0.20.225 tell 10.0.20.3, length 28\n13:54:51.428174 ARP, Request who-has 10.0.20.228 tell 10.0.20.3, length 28\n13:54:51.428205 ARP, Request who-has 10.0.20.233 tell 10.0.20.3, length 28\n13:54:51.428384 ARP, Request who-has 10.0.20.246 tell 10.0.20.3, length 28\n13:54:51.428401 ARP, Request who-has 10.0.20.247 tell 10.0.20.3, length 28\n13:54:51.428425 ARP, Request who-has 10.0.20.249 tell 10.0.20.3, length 28\n13:54:51.428443 ARP, Request who-has 10.0.20.250 tell 10.0.20.3, length 28\n13:54:51.428460 ARP, Request who-has 10.0.20.251 tell 10.0.20.3, length 28\n13:54:51.428476 ARP, Request who-has 10.0.20.252 tell 10.0.20.3, length 28\n13:54:51.428496 ARP, Request who-has 10.0.20.253 tell 10.0.20.3, length 28\n13:54:51.428513 ARP, Request who-has 10.0.20.254 tell 10.0.20.3, length 28\n13:54:51.428542 ARP, Request who-has 10.0.20.0 tell 10.0.20.3, length 28\n13:54:51.428687 ARP, Request who-has 10.0.20.68 tell 10.0.20.3, length 28\n13:54:51.428706 ARP, Request who-has 10.0.20.69 tell 10.0.20.3, length 28\n13:54:51.428757 ARP, Request who-has 10.0.20.114 tell 10.0.20.3, length 28\n13:54:51.428775 ARP, Request who-has 10.0.20.118 tell 10.0.20.3, length 28\n13:54:51.428795 ARP, Request who-has 10.0.20.122 tell 10.0.20.3, length 28\n13:54:51.432294 ARP, Request who-has 10.0.20.128 tell 10.0.20.3, length 28\n13:54:51.432327 ARP, Request who-has 10.0.20.129 tell 10.0.20.3, length 28\n13:54:51.432353 ARP, Request who-has 10.0.20.135 tell 10.0.20.3, length 28\n13:54:51.432384 ARP, Request who-has 10.0.20.136 tell 10.0.20.3, length 28\n13:54:51.432402 ARP, Request who-has 10.0.20.153 tell 10.0.20.3, length 28\n13:54:51.432897 ARP, Request who-has 10.0.20.58 tell 10.0.20.3, length 28\n13:54:51.432899 ARP, Request who-has 10.0.20.55 tell 10.0.20.3, length 28\n13:54:51.432900 ARP, Request who-has 10.0.20.54 tell 10.0.20.3, length 28\n13:54:51.432900 ARP, Request who-has 10.0.20.51 tell 10.0.20.3, length 28\n13:54:51.432901 ARP, Request who-has 10.0.20.50 tell 10.0.20.3, length 28\n13:54:51.432902 ARP, Request who-has 10.0.20.47 tell 10.0.20.3, length 28\n13:54:51.432902 ARP, Request who-has 10.0.20.46 tell 10.0.20.3, length 28\n13:54:51.432903 ARP, Request who-has 10.0.20.43 tell 10.0.20.3, length 28\n13:54:51.432903 ARP, Request who-has 10.0.20.40 tell 10.0.20.3, length 28\n13:54:51.432904 ARP, Request who-has 10.0.20.37 tell 10.0.20.3, length 28\n13:54:51.432905 ARP, Request who-has 10.0.20.34 tell 10.0.20.3, length 28\n13:54:51.432905 ARP, Request who-has 10.0.20.31 tell 10.0.20.3, length 28\n13:54:51.528083 ARP, Request who-has 10.0.20.239 tell 10.0.20.3, length 28\n13:54:51.532392 ARP, Request who-has 10.0.20.194 tell 10.0.20.3, length 28\n13:54:51.532479 ARP, Request who-has 10.0.20.197 tell 10.0.20.3, length 28\n13:54:51.532500 ARP, Request who-has 10.0.20.198 tell 10.0.20.3, length 28\n13:54:51.532518 ARP, Request who-has 10.0.20.201 tell 10.0.20.3, length 28\n13:54:51.532537 ARP, Request who-has 10.0.20.202 tell 10.0.20.3, length 28\n13:54:51.532614 ARP, Request who-has 10.0.20.208 tell 10.0.20.3, length 28\n13:54:51.532637 ARP, Request who-has 10.0.20.209 tell 10.0.20.3, length 28\n13:54:51.532893 ARP, Request who-has 10.0.20.123 tell 10.0.20.3, length 28\n13:54:51.532894 ARP, Request who-has 10.0.20.120 tell 10.0.20.3, length 28\n13:54:51.532895 ARP, Request who-has 10.0.20.119 tell 10.0.20.3, length 28\n13:54:51.532895 ARP, Request who-has 10.0.20.116 tell 10.0.20.3, length 28\n13:54:51.532896 ARP, Request who-has 10.0.20.115 tell 10.0.20.3, length 28\n13:54:51.532897 ARP, Request who-has 10.0.20.112 tell 10.0.20.3, length 28\n13:54:51.532897 ARP, Request who-has 10.0.20.111 tell 10.0.20.3, length 28\n13:54:51.532898 ARP, Request who-has 10.0.20.107 tell 10.0.20.3, length 28\n13:54:51.532899 ARP, Request who-has 10.0.20.99 tell 10.0.20.3, length 28\n13:54:51.532899 ARP, Request who-has 10.0.20.94 tell 10.0.20.3, length 28\n13:54:51.532900 ARP, Request who-has 10.0.20.90 tell 10.0.20.3, length 28\n13:54:51.532900 ARP, Request who-has 10.0.20.87 tell 10.0.20.3, length 28\n13:54:51.628025 ARP, Request who-has 10.0.20.186 tell 10.0.20.3, length 28\n13:54:51.628094 ARP, Request who-has 10.0.20.189 tell 10.0.20.3, length 28\n13:54:51.628160 ARP, Request who-has 10.0.20.192 tell 10.0.20.3, length 28\n13:54:51.628228 ARP, Request who-has 10.0.20.195 tell 10.0.20.3, length 28\n13:54:51.628610 ARP, Request who-has 10.0.20.185 tell 10.0.20.3, length 28\n13:54:51.628751 ARP, Request who-has 10.0.20.188 tell 10.0.20.3, length 28\n13:54:51.628924 ARP, Request who-has 10.0.20.191 tell 10.0.20.3, length 28\n13:54:51.628958 ARP, Request who-has 10.0.20.193 tell 10.0.20.3, length 28\n13:54:51.629091 ARP, Request who-has 10.0.20.187 tell 10.0.20.3, length 28\n13:54:51.629131 ARP, Request who-has 10.0.20.190 tell 10.0.20.3, length 28\n13:54:51.632603 ARP, Request who-has 10.0.20.196 tell 10.0.20.3, length 28\n13:54:51.656931 ARP, Request who-has 10.0.20.183 tell 10.0.20.3, length 28\n13:54:51.656932 ARP, Request who-has 10.0.20.182 tell 10.0.20.3, length 28\n13:54:51.656933 ARP, Request who-has 10.0.20.177 tell 10.0.20.3, length 28\n13:54:51.656934 ARP, Request who-has 10.0.20.176 tell 10.0.20.3, length 28\n13:54:51.656934 ARP, Request who-has 10.0.20.172 tell 10.0.20.3, length 28\n13:54:51.656935 ARP, Request who-has 10.0.20.171 tell 10.0.20.3, length 28\n13:54:51.656936 ARP, Request who-has 10.0.20.167 tell 10.0.20.3, length 28\n13:54:51.656936 ARP, Request who-has 10.0.20.164 tell 10.0.20.3, length 28\n13:54:51.656937 ARP, Request who-has 10.0.20.161 tell 10.0.20.3, length 28\n13:54:51.656938 ARP, Request who-has 10.0.20.158 tell 10.0.20.3, length 28\n13:54:51.656938 ARP, Request who-has 10.0.20.155 tell 10.0.20.3, length 28\n13:54:51.656939 ARP, Request who-has 10.0.20.152 tell 10.0.20.3, length 28\n13:54:51.752909 ARP, Request who-has 10.0.20.243 tell 10.0.20.3, length 28\n13:54:51.752911 ARP, Request who-has 10.0.20.242 tell 10.0.20.3, length 28\n13:54:51.752912 ARP, Request who-has 10.0.20.238 tell 10.0.20.3, length 28\n13:54:51.752912 ARP, Request who-has 10.0.20.234 tell 10.0.20.3, length 28\n13:54:51.752913 ARP, Request who-has 10.0.20.231 tell 10.0.20.3, length 28\n13:54:51.752913 ARP, Request who-has 10.0.20.230 tell 10.0.20.3, length 28\n13:54:51.752914 ARP, Request who-has 10.0.20.227 tell 10.0.20.3, length 28\n13:54:51.752915 ARP, Request who-has 10.0.20.224 tell 10.0.20.3, length 28\n13:54:51.752915 ARP, Request who-has 10.0.20.221 tell 10.0.20.3, length 28\n13:54:51.752916 ARP, Request who-has 10.0.20.218 tell 10.0.20.3, length 28\n13:54:51.752917 ARP, Request who-has 10.0.20.215 tell 10.0.20.3, length 28\n13:54:51.752917 ARP, Request who-has 10.0.20.212 tell 10.0.20.3, length 28\n13:54:51.848938 ARP, Request who-has 10.0.20.60 tell 10.0.20.3, length 28\n13:54:51.848940 ARP, Request who-has 10.0.20.59 tell 10.0.20.3, length 28\n13:54:51.848941 ARP, Request who-has 10.0.20.56 tell 10.0.20.3, length 28\n13:54:51.848942 ARP, Request who-has 10.0.20.52 tell 10.0.20.3, length 28\n13:54:51.848942 ARP, Request who-has 10.0.20.49 tell 10.0.20.3, length 28\n13:54:51.848943 ARP, Request who-has 10.0.20.48 tell 10.0.20.3, length 28\n13:54:51.848944 ARP, Request who-has 10.0.20.44 tell 10.0.20.3, length 28\n13:54:51.848944 ARP, Request who-has 10.0.20.41 tell 10.0.20.3, length 28\n13:54:51.848945 ARP, Request who-has 10.0.20.38 tell 10.0.20.3, length 28\n13:54:51.848946 ARP, Request who-has 10.0.20.35 tell 10.0.20.3, length 28\n13:54:51.848946 ARP, Request who-has 10.0.20.32 tell 10.0.20.3, length 28\n13:54:51.848947 ARP, Request who-has 10.0.20.18 tell 10.0.20.3, length 28\n13:54:51.948923 ARP, Request who-has 10.0.20.125 tell 10.0.20.3, length 28\n13:54:51.948925 ARP, Request who-has 10.0.20.124 tell 10.0.20.3, length 28\n13:54:51.948925 ARP, Request who-has 10.0.20.121 tell 10.0.20.3, length 28\n13:54:51.948926 ARP, Request who-has 10.0.20.117 tell 10.0.20.3, length 28\n13:54:51.948927 ARP, Request who-has 10.0.20.113 tell 10.0.20.3, length 28\n13:54:51.948927 ARP, Request who-has 10.0.20.108 tell 10.0.20.3, length 28\n13:54:51.948928 ARP, Request who-has 10.0.20.100 tell 10.0.20.3, length 28\n13:54:51.948929 ARP, Request who-has 10.0.20.95 tell 10.0.20.3, length 28\n13:54:51.948929 ARP, Request who-has 10.0.20.92 tell 10.0.20.3, length 28\n13:54:51.948930 ARP, Request who-has 10.0.20.89 tell 10.0.20.3, length 28\n13:54:51.948931 ARP, Request who-has 10.0.20.86 tell 10.0.20.3, length 28\n13:54:51.948931 ARP, Request who-has 10.0.20.83 tell 10.0.20.3, length 28\n13:54:51.976931 ARP, Request who-has 10.0.20.1 tell 10.0.20.3, length 28\n13:54:51.976933 ARP, Request who-has 10.0.20.2 tell 10.0.20.3, length 28\n13:54:51.976934 ARP, Request who-has 10.0.20.5 tell 10.0.20.3, length 28\n13:54:51.976934 ARP, Request who-has 10.0.20.6 tell 10.0.20.3, length 28\n13:54:51.976935 ARP, Request who-has 10.0.20.7 tell 10.0.20.3, length 28\n13:54:51.976936 ARP, Request who-has 10.0.20.8 tell 10.0.20.3, length 28\n13:54:51.976936 ARP, Request who-has 10.0.20.9 tell 10.0.20.3, length 28\n13:54:51.976937 ARP, Request who-has 10.0.20.10 tell 10.0.20.3, length 28\n13:54:51.976938 ARP, Request who-has 10.0.20.13 tell 10.0.20.3, length 28\n13:54:51.976938 ARP, Request who-has 10.0.20.14 tell 10.0.20.3, length 28\n13:54:51.976939 ARP, Request who-has 10.0.20.15 tell 10.0.20.3, length 28\n13:54:51.976939 ARP, Request who-has 10.0.20.16 tell 10.0.20.3, length 28\n13:54:52.072939 ARP, Request who-has 10.0.20.19 tell 10.0.20.3, length 28\n13:54:52.072942 ARP, Request who-has 10.0.20.20 tell 10.0.20.3, length 28\n13:54:52.072943 ARP, Request who-has 10.0.20.21 tell 10.0.20.3, length 28\n13:54:52.072944 ARP, Request who-has 10.0.20.22 tell 10.0.20.3, length 28\n13:54:52.072944 ARP, Request who-has 10.0.20.23 tell 10.0.20.3, length 28\n13:54:52.072945 ARP, Request who-has 10.0.20.24 tell 10.0.20.3, length 28\n13:54:52.072945 ARP, Request who-has 10.0.20.25 tell 10.0.20.3, length 28\n13:54:52.072946 ARP, Request who-has 10.0.20.26 tell 10.0.20.3, length 28\n13:54:52.072946 ARP, Request who-has 10.0.20.27 tell 10.0.20.3, length 28\n13:54:52.072947 ARP, Request who-has 10.0.20.28 tell 10.0.20.3, length 28\n13:54:52.072948 ARP, Request who-has 10.0.20.29 tell 10.0.20.3, length 28\n13:54:52.072948 ARP, Request who-has 10.0.20.30 tell 10.0.20.3, length 28\n13:54:52.168928 ARP, Request who-has 10.0.20.93 tell 10.0.20.3, length 28\n13:54:52.168932 ARP, Request who-has 10.0.20.96 tell 10.0.20.3, length 28\n13:54:52.168932 ARP, Request who-has 10.0.20.97 tell 10.0.20.3, length 28\n13:54:52.168933 ARP, Request who-has 10.0.20.98 tell 10.0.20.3, length 28\n13:54:52.168934 ARP, Request who-has 10.0.20.101 tell 10.0.20.3, length 28\n13:54:52.168934 ARP, Request who-has 10.0.20.102 tell 10.0.20.3, length 28\n13:54:52.168935 ARP, Request who-has 10.0.20.103 tell 10.0.20.3, length 28\n13:54:52.168935 ARP, Request who-has 10.0.20.104 tell 10.0.20.3, length 28\n13:54:52.168936 ARP, Request who-has 10.0.20.105 tell 10.0.20.3, length 28\n13:54:52.168937 ARP, Request who-has 10.0.20.106 tell 10.0.20.3, length 28\n13:54:52.168937 ARP, Request who-has 10.0.20.109 tell 10.0.20.3, length 28\n13:54:52.168938 ARP, Request who-has 10.0.20.110 tell 10.0.20.3, length 28\n13:54:52.233031 ARP, Request who-has 10.0.20.91 tell 10.0.20.3, length 28\n13:54:52.233033 ARP, Request who-has 10.0.20.88 tell 10.0.20.3, length 28\n13:54:52.233034 ARP, Request who-has 10.0.20.85 tell 10.0.20.3, length 28\n13:54:52.233035 ARP, Request who-has 10.0.20.84 tell 10.0.20.3, length 28\n13:54:52.233035 ARP, Request who-has 10.0.20.82 tell 10.0.20.3, length 28\n13:54:52.233036 ARP, Request who-has 10.0.20.81 tell 10.0.20.3, length 28\n13:54:52.233037 ARP, Request who-has 10.0.20.80 tell 10.0.20.3, length 28\n13:54:52.233037 ARP, Request who-has 10.0.20.79 tell 10.0.20.3, length 28\n13:54:52.233038 ARP, Request who-has 10.0.20.78 tell 10.0.20.3, length 28\n13:54:52.233039 ARP, Request who-has 10.0.20.77 tell 10.0.20.3, length 28\n13:54:52.233039 ARP, Request who-has 10.0.20.76 tell 10.0.20.3, length 28\n13:54:52.233040 ARP, Request who-has 10.0.20.75 tell 10.0.20.3, length 28\n13:54:52.233041 ARP, Request who-has 10.0.20.74 tell 10.0.20.3, length 28\n13:54:52.233041 ARP, Request who-has 10.0.20.73 tell 10.0.20.3, length 28\n13:54:52.233042 ARP, Request who-has 10.0.20.72 tell 10.0.20.3, length 28\n13:54:52.233043 ARP, Request who-has 10.0.20.71 tell 10.0.20.3, length 28\n13:54:52.233043 ARP, Request who-has 10.0.20.70 tell 10.0.20.3, length 28\n13:54:52.233044 ARP, Request who-has 10.0.20.67 tell 10.0.20.3, length 28\n13:54:52.233045 ARP, Request who-has 10.0.20.66 tell 10.0.20.3, length 28\n13:54:52.233046 ARP, Request who-has 10.0.20.65 tell 10.0.20.3, length 28\n13:54:52.233047 ARP, Request who-has 10.0.20.64 tell 10.0.20.3, length 28\n13:54:52.233047 ARP, Request who-has 10.0.20.63 tell 10.0.20.3, length 28\n13:54:52.233048 ARP, Request who-has 10.0.20.62 tell 10.0.20.3, length 28\n13:54:52.233048 ARP, Request who-has 10.0.20.61 tell 10.0.20.3, length 28\n13:54:52.233049 ARP, Request who-has 10.0.20.57 tell 10.0.20.3, length 28\n13:54:52.233050 ARP, Request who-has 10.0.20.53 tell 10.0.20.3, length 28\n13:54:52.233050 ARP, Request who-has 10.0.20.45 tell 10.0.20.3, length 28\n13:54:52.233051 ARP, Request who-has 10.0.20.42 tell 10.0.20.3, length 28\n13:54:52.233052 ARP, Request who-has 10.0.20.39 tell 10.0.20.3, length 28\n13:54:52.233052 ARP, Request who-has 10.0.20.36 tell 10.0.20.3, length 28\n13:54:52.233053 ARP, Request who-has 10.0.20.33 tell 10.0.20.3, length 28\n13:54:52.233054 ARP, Request who-has 10.0.20.17 tell 10.0.20.3, length 28\n13:54:52.233054 ARP, Request who-has 10.0.20.12 tell 10.0.20.3, length 28\n13:54:52.233055 ARP, Request who-has 10.0.20.11 tell 10.0.20.3, length 28\n13:54:52.264917 ARP, Request who-has 10.0.20.163 tell 10.0.20.3, length 28\n13:54:52.264918 ARP, Request who-has 10.0.20.166 tell 10.0.20.3, length 28\n13:54:52.264919 ARP, Request who-has 10.0.20.169 tell 10.0.20.3, length 28\n13:54:52.264920 ARP, Request who-has 10.0.20.170 tell 10.0.20.3, length 28\n13:54:52.264920 ARP, Request who-has 10.0.20.173 tell 10.0.20.3, length 28\n13:54:52.264921 ARP, Request who-has 10.0.20.174 tell 10.0.20.3, length 28\n13:54:52.264925 ARP, Request who-has 10.0.20.175 tell 10.0.20.3, length 28\n13:54:52.264925 ARP, Request who-has 10.0.20.178 tell 10.0.20.3, length 28\n13:54:52.264926 ARP, Request who-has 10.0.20.179 tell 10.0.20.3, length 28\n13:54:52.264927 ARP, Request who-has 10.0.20.180 tell 10.0.20.3, length 28\n13:54:52.264927 ARP, Request who-has 10.0.20.181 tell 10.0.20.3, length 28\n13:54:52.264928 ARP, Request who-has 10.0.20.184 tell 10.0.20.3, length 28\n13:54:52.333031 ARP, Request who-has 10.0.20.168 tell 10.0.20.3, length 28\n13:54:52.333032 ARP, Request who-has 10.0.20.165 tell 10.0.20.3, length 28\n13:54:52.333033 ARP, Request who-has 10.0.20.162 tell 10.0.20.3, length 28\n13:54:52.333034 ARP, Request who-has 10.0.20.160 tell 10.0.20.3, length 28\n13:54:52.333034 ARP, Request who-has 10.0.20.159 tell 10.0.20.3, length 28\n13:54:52.333035 ARP, Request who-has 10.0.20.157 tell 10.0.20.3, length 28\n13:54:52.333036 ARP, Request who-has 10.0.20.156 tell 10.0.20.3, length 28\n13:54:52.333036 ARP, Request who-has 10.0.20.154 tell 10.0.20.3, length 28\n13:54:52.333037 ARP, Request who-has 10.0.20.151 tell 10.0.20.3, length 28\n13:54:52.333038 ARP, Request who-has 10.0.20.150 tell 10.0.20.3, length 28\n13:54:52.333039 ARP, Request who-has 10.0.20.149 tell 10.0.20.3, length 28\n13:54:52.333039 ARP, Request who-has 10.0.20.148 tell 10.0.20.3, length 28\n13:54:52.333040 ARP, Request who-has 10.0.20.147 tell 10.0.20.3, length 28\n13:54:52.333040 ARP, Request who-has 10.0.20.146 tell 10.0.20.3, length 28\n13:54:52.333041 ARP, Request who-has 10.0.20.145 tell 10.0.20.3, length 28\n13:54:52.333042 ARP, Request who-has 10.0.20.144 tell 10.0.20.3, length 28\n13:54:52.333042 ARP, Request who-has 10.0.20.143 tell 10.0.20.3, length 28\n13:54:52.333043 ARP, Request who-has 10.0.20.142 tell 10.0.20.3, length 28\n13:54:52.333044 ARP, Request who-has 10.0.20.141 tell 10.0.20.3, length 28\n13:54:52.333044 ARP, Request who-has 10.0.20.140 tell 10.0.20.3, length 28\n13:54:52.333045 ARP, Request who-has 10.0.20.139 tell 10.0.20.3, length 28\n13:54:52.333045 ARP, Request who-has 10.0.20.138 tell 10.0.20.3, length 28\n13:54:52.333046 ARP, Request who-has 10.0.20.137 tell 10.0.20.3, length 28\n13:54:52.333047 ARP, Request who-has 10.0.20.134 tell 10.0.20.3, length 28\n13:54:52.333048 ARP, Request who-has 10.0.20.133 tell 10.0.20.3, length 28\n13:54:52.333048 ARP, Request who-has 10.0.20.132 tell 10.0.20.3, length 28\n13:54:52.333049 ARP, Request who-has 10.0.20.131 tell 10.0.20.3, length 28\n13:54:52.333049 ARP, Request who-has 10.0.20.130 tell 10.0.20.3, length 28\n13:54:52.333050 ARP, Request who-has 10.0.20.127 tell 10.0.20.3, length 28\n13:54:52.333051 ARP, Request who-has 10.0.20.126 tell 10.0.20.3, length 28\n13:54:52.360921 ARP, Request who-has 10.0.20.223 tell 10.0.20.3, length 28\n13:54:52.360922 ARP, Request who-has 10.0.20.226 tell 10.0.20.3, length 28\n13:54:52.360923 ARP, Request who-has 10.0.20.229 tell 10.0.20.3, length 28\n13:54:52.360924 ARP, Request who-has 10.0.20.232 tell 10.0.20.3, length 28\n13:54:52.360924 ARP, Request who-has 10.0.20.235 tell 10.0.20.3, length 28\n13:54:52.360925 ARP, Request who-has 10.0.20.236 tell 10.0.20.3, length 28\n13:54:52.360926 ARP, Request who-has 10.0.20.237 tell 10.0.20.3, length 28\n13:54:52.360926 ARP, Request who-has 10.0.20.240 tell 10.0.20.3, length 28\n13:54:52.360927 ARP, Request who-has 10.0.20.241 tell 10.0.20.3, length 28\n13:54:52.360928 ARP, Request who-has 10.0.20.244 tell 10.0.20.3, length 28\n13:54:52.360928 ARP, Request who-has 10.0.20.245 tell 10.0.20.3, length 28\n13:54:52.360929 ARP, Request who-has 10.0.20.248 tell 10.0.20.3, length 28\n13:54:52.457147 ARP, Request who-has 10.0.20.31 tell 10.0.20.3, length 28\n13:54:52.457149 ARP, Request who-has 10.0.20.34 tell 10.0.20.3, length 28\n13:54:52.457149 ARP, Request who-has 10.0.20.37 tell 10.0.20.3, length 28\n13:54:52.457150 ARP, Request who-has 10.0.20.40 tell 10.0.20.3, length 28\n13:54:52.457151 ARP, Request who-has 10.0.20.43 tell 10.0.20.3, length 28\n13:54:52.457152 ARP, Request who-has 10.0.20.46 tell 10.0.20.3, length 28\n13:54:52.457152 ARP, Request who-has 10.0.20.47 tell 10.0.20.3, length 28\n13:54:52.457153 ARP, Request who-has 10.0.20.50 tell 10.0.20.3, length 28\n13:54:52.457154 ARP, Request who-has 10.0.20.51 tell 10.0.20.3, length 28\n13:54:52.457154 ARP, Request who-has 10.0.20.54 tell 10.0.20.3, length 28\n13:54:52.457155 ARP, Request who-has 10.0.20.55 tell 10.0.20.3, length 28\n13:54:52.457156 ARP, Request who-has 10.0.20.58 tell 10.0.20.3, length 28\n13:54:52.457156 ARP, Request who-has 10.0.20.153 tell 10.0.20.3, length 28\n13:54:52.457157 ARP, Request who-has 10.0.20.136 tell 10.0.20.3, length 28\n13:54:52.457158 ARP, Request who-has 10.0.20.135 tell 10.0.20.3, length 28\n13:54:52.457158 ARP, Request who-has 10.0.20.129 tell 10.0.20.3, length 28\n13:54:52.457159 ARP, Request who-has 10.0.20.128 tell 10.0.20.3, length 28\n13:54:52.457160 ARP, Request who-has 10.0.20.122 tell 10.0.20.3, length 28\n13:54:52.457160 ARP, Request who-has 10.0.20.118 tell 10.0.20.3, length 28\n13:54:52.457161 ARP, Request who-has 10.0.20.114 tell 10.0.20.3, length 28\n13:54:52.457162 ARP, Request who-has 10.0.20.69 tell 10.0.20.3, length 28\n13:54:52.457162 ARP, Request who-has 10.0.20.68 tell 10.0.20.3, length 28\n13:54:52.457163 ARP, Request who-has 10.0.20.0 tell 10.0.20.3, length 28\n13:54:52.457164 ARP, Request who-has 10.0.20.254 tell 10.0.20.3, length 28\n13:54:52.457165 ARP, Request who-has 10.0.20.253 tell 10.0.20.3, length 28\n13:54:52.457165 ARP, Request who-has 10.0.20.252 tell 10.0.20.3, length 28\n13:54:52.457166 ARP, Request who-has 10.0.20.251 tell 10.0.20.3, length 28\n13:54:52.457166 ARP, Request who-has 10.0.20.250 tell 10.0.20.3, length 28\n13:54:52.457167 ARP, Request who-has 10.0.20.249 tell 10.0.20.3, length 28\n13:54:52.457168 ARP, Request who-has 10.0.20.247 tell 10.0.20.3, length 28\n13:54:52.457168 ARP, Request who-has 10.0.20.246 tell 10.0.20.3, length 28\n13:54:52.457169 ARP, Request who-has 10.0.20.233 tell 10.0.20.3, length 28\n13:54:52.457170 ARP, Request who-has 10.0.20.228 tell 10.0.20.3, length 28\n13:54:52.457170 ARP, Request who-has 10.0.20.225 tell 10.0.20.3, length 28\n13:54:52.457171 ARP, Request who-has 10.0.20.222 tell 10.0.20.3, length 28\n13:54:52.457172 ARP, Request who-has 10.0.20.220 tell 10.0.20.3, length 28\n13:54:52.457172 ARP, Request who-has 10.0.20.219 tell 10.0.20.3, length 28\n13:54:52.457173 ARP, Request who-has 10.0.20.217 tell 10.0.20.3, length 28\n13:54:52.457174 ARP, Request who-has 10.0.20.216 tell 10.0.20.3, length 28\n13:54:52.457174 ARP, Request who-has 10.0.20.214 tell 10.0.20.3, length 28\n13:54:52.457175 ARP, Request who-has 10.0.20.213 tell 10.0.20.3, length 28\n13:54:52.457176 ARP, Request who-has 10.0.20.211 tell 10.0.20.3, length 28\n13:54:52.457177 ARP, Request who-has 10.0.20.210 tell 10.0.20.3, length 28\n13:54:52.457177 ARP, Request who-has 10.0.20.207 tell 10.0.20.3, length 28\n13:54:52.457178 ARP, Request who-has 10.0.20.206 tell 10.0.20.3, length 28\n13:54:52.457178 ARP, Request who-has 10.0.20.205 tell 10.0.20.3, length 28\n13:54:52.457179 ARP, Request who-has 10.0.20.204 tell 10.0.20.3, length 28\n13:54:52.457180 ARP, Request who-has 10.0.20.203 tell 10.0.20.3, length 28\n13:54:52.457180 ARP, Request who-has 10.0.20.200 tell 10.0.20.3, length 28\n13:54:52.457181 ARP, Request who-has 10.0.20.199 tell 10.0.20.3, length 28\n13:54:52.552958 ARP, Request who-has 10.0.20.87 tell 10.0.20.3, length 28\n13:54:52.552959 ARP, Request who-has 10.0.20.90 tell 10.0.20.3, length 28\n13:54:52.552960 ARP, Request who-has 10.0.20.94 tell 10.0.20.3, length 28\n13:54:52.552961 ARP, Request who-has 10.0.20.99 tell 10.0.20.3, length 28\n13:54:52.552962 ARP, Request who-has 10.0.20.107 tell 10.0.20.3, length 28\n13:54:52.552962 ARP, Request who-has 10.0.20.111 tell 10.0.20.3, length 28\n13:54:52.552963 ARP, Request who-has 10.0.20.112 tell 10.0.20.3, length 28\n13:54:52.552964 ARP, Request who-has 10.0.20.115 tell 10.0.20.3, length 28\n13:54:52.552964 ARP, Request who-has 10.0.20.116 tell 10.0.20.3, length 28\n13:54:52.552965 ARP, Request who-has 10.0.20.119 tell 10.0.20.3, length 28\n13:54:52.552965 ARP, Request who-has 10.0.20.120 tell 10.0.20.3, length 28\n13:54:52.552966 ARP, Request who-has 10.0.20.123 tell 10.0.20.3, length 28\n13:54:52.552967 ARP, Request who-has 10.0.20.209 tell 10.0.20.3, length 28\n13:54:52.552967 ARP, Request who-has 10.0.20.208 tell 10.0.20.3, length 28\n13:54:52.552968 ARP, Request who-has 10.0.20.202 tell 10.0.20.3, length 28\n13:54:52.552969 ARP, Request who-has 10.0.20.201 tell 10.0.20.3, length 28\n13:54:52.552969 ARP, Request who-has 10.0.20.198 tell 10.0.20.3, length 28\n13:54:52.552970 ARP, Request who-has 10.0.20.197 tell 10.0.20.3, length 28\n13:54:52.552970 ARP, Request who-has 10.0.20.194 tell 10.0.20.3, length 28\n13:54:52.552971 ARP, Request who-has 10.0.20.239 tell 10.0.20.3, length 28\n13:54:52.648942 ARP, Request who-has 10.0.20.196 tell 10.0.20.3, length 28\n13:54:52.648943 ARP, Request who-has 10.0.20.190 tell 10.0.20.3, length 28\n13:54:52.648944 ARP, Request who-has 10.0.20.187 tell 10.0.20.3, length 28\n13:54:52.648945 ARP, Request who-has 10.0.20.193 tell 10.0.20.3, length 28\n13:54:52.648945 ARP, Request who-has 10.0.20.191 tell 10.0.20.3, length 28\n13:54:52.648946 ARP, Request who-has 10.0.20.188 tell 10.0.20.3, length 28\n13:54:52.648947 ARP, Request who-has 10.0.20.185 tell 10.0.20.3, length 28\n13:54:52.648947 ARP, Request who-has 10.0.20.195 tell 10.0.20.3, length 28\n13:54:52.648948 ARP, Request who-has 10.0.20.192 tell 10.0.20.3, length 28\n13:54:52.648948 ARP, Request who-has 10.0.20.189 tell 10.0.20.3, length 28\n13:54:52.648949 ARP, Request who-has 10.0.20.186 tell 10.0.20.3, length 28\n13:54:52.680923 ARP, Request who-has 10.0.20.152 tell 10.0.20.3, length 28\n13:54:52.680924 ARP, Request who-has 10.0.20.155 tell 10.0.20.3, length 28\n13:54:52.680925 ARP, Request who-has 10.0.20.158 tell 10.0.20.3, length 28\n13:54:52.680925 ARP, Request who-has 10.0.20.161 tell 10.0.20.3, length 28\n13:54:52.680926 ARP, Request who-has 10.0.20.164 tell 10.0.20.3, length 28\n13:54:52.680927 ARP, Request who-has 10.0.20.167 tell 10.0.20.3, length 28\n13:54:52.680927 ARP, Request who-has 10.0.20.171 tell 10.0.20.3, length 28\n13:54:52.680928 ARP, Request who-has 10.0.20.172 tell 10.0.20.3, length 28\n13:54:52.680929 ARP, Request who-has 10.0.20.176 tell 10.0.20.3, length 28\n13:54:52.680929 ARP, Request who-has 10.0.20.177 tell 10.0.20.3, length 28\n13:54:52.680930 ARP, Request who-has 10.0.20.182 tell 10.0.20.3, length 28\n13:54:52.680930 ARP, Request who-has 10.0.20.183 tell 10.0.20.3, length 28\n13:54:52.726900 IP 10.0.20.3.57450 > 10.0.20.4.http: Flags [S], seq 1057964882, win 64240, options [mss 1460,sackOK,TS val 230224585 ecr 0,nop,wscale 7], length 0\n13:54:52.726908 IP 10.0.20.4.http > 10.0.20.3.57450: Flags [R.], seq 0, ack 1057964883, win 0, length 0\n13:54:52.776920 ARP, Request who-has 10.0.20.212 tell 10.0.20.3, length 28\n13:54:52.776922 ARP, Request who-has 10.0.20.215 tell 10.0.20.3, length 28\n13:54:52.776922 ARP, Request who-has 10.0.20.218 tell 10.0.20.3, length 28\n13:54:52.776923 ARP, Request who-has 10.0.20.221 tell 10.0.20.3, length 28\n13:54:52.776924 ARP, Request who-has 10.0.20.224 tell 10.0.20.3, length 28\n13:54:52.776924 ARP, Request who-has 10.0.20.227 tell 10.0.20.3, length 28\n13:54:52.776925 ARP, Request who-has 10.0.20.230 tell 10.0.20.3, length 28\n13:54:52.776926 ARP, Request who-has 10.0.20.231 tell 10.0.20.3, length 28\n13:54:52.776926 ARP, Request who-has 10.0.20.234 tell 10.0.20.3, length 28\n13:54:52.776927 ARP, Request who-has 10.0.20.238 tell 10.0.20.3, length 28\n13:54:52.776927 ARP, Request who-has 10.0.20.242 tell 10.0.20.3, length 28\n13:54:52.776928 ARP, Request who-has 10.0.20.243 tell 10.0.20.3, length 28\n13:54:52.872924 ARP, Request who-has 10.0.20.18 tell 10.0.20.3, length 28\n13:54:52.872926 ARP, Request who-has 10.0.20.32 tell 10.0.20.3, length 28\n13:54:52.872927 ARP, Request who-has 10.0.20.35 tell 10.0.20.3, length 28\n13:54:52.872927 ARP, Request who-has 10.0.20.38 tell 10.0.20.3, length 28\n13:54:52.872928 ARP, Request who-has 10.0.20.41 tell 10.0.20.3, length 28\n13:54:52.872929 ARP, Request who-has 10.0.20.44 tell 10.0.20.3, length 28\n13:54:52.872929 ARP, Request who-has 10.0.20.48 tell 10.0.20.3, length 28\n13:54:52.872930 ARP, Request who-has 10.0.20.49 tell 10.0.20.3, length 28\n13:54:52.872930 ARP, Request who-has 10.0.20.52 tell 10.0.20.3, length 28\n13:54:52.872931 ARP, Request who-has 10.0.20.56 tell 10.0.20.3, length 28\n13:54:52.872932 ARP, Request who-has 10.0.20.59 tell 10.0.20.3, length 28\n13:54:52.872932 ARP, Request who-has 10.0.20.60 tell 10.0.20.3, length 28\n13:54:52.968919 ARP, Request who-has 10.0.20.83 tell 10.0.20.3, length 28\n13:54:52.968921 ARP, Request who-has 10.0.20.86 tell 10.0.20.3, length 28\n13:54:52.968922 ARP, Request who-has 10.0.20.89 tell 10.0.20.3, length 28\n13:54:52.968922 ARP, Request who-has 10.0.20.92 tell 10.0.20.3, length 28\n13:54:52.968923 ARP, Request who-has 10.0.20.95 tell 10.0.20.3, length 28\n13:54:52.968923 ARP, Request who-has 10.0.20.100 tell 10.0.20.3, length 28\n13:54:52.968924 ARP, Request who-has 10.0.20.108 tell 10.0.20.3, length 28\n13:54:52.968925 ARP, Request who-has 10.0.20.113 tell 10.0.20.3, length 28\n13:54:52.968925 ARP, Request who-has 10.0.20.117 tell 10.0.20.3, length 28\n13:54:52.968926 ARP, Request who-has 10.0.20.121 tell 10.0.20.3, length 28\n13:54:52.968927 ARP, Request who-has 10.0.20.124 tell 10.0.20.3, length 28\n13:54:52.968927 ARP, Request who-has 10.0.20.125 tell 10.0.20.3, length 28\n13:54:53.257044 ARP, Request who-has 10.0.20.11 tell 10.0.20.3, length 28\n13:54:53.257046 ARP, Request who-has 10.0.20.12 tell 10.0.20.3, length 28\n13:54:53.257047 ARP, Request who-has 10.0.20.17 tell 10.0.20.3, length 28\n13:54:53.257047 ARP, Request who-has 10.0.20.33 tell 10.0.20.3, length 28\n13:54:53.257048 ARP, Request who-has 10.0.20.36 tell 10.0.20.3, length 28\n13:54:53.257048 ARP, Request who-has 10.0.20.39 tell 10.0.20.3, length 28\n13:54:53.257049 ARP, Request who-has 10.0.20.42 tell 10.0.20.3, length 28\n13:54:53.257050 ARP, Request who-has 10.0.20.45 tell 10.0.20.3, length 28\n13:54:53.257050 ARP, Request who-has 10.0.20.53 tell 10.0.20.3, length 28\n13:54:53.257051 ARP, Request who-has 10.0.20.57 tell 10.0.20.3, length 28\n13:54:53.257052 ARP, Request who-has 10.0.20.61 tell 10.0.20.3, length 28\n13:54:53.257052 ARP, Request who-has 10.0.20.62 tell 10.0.20.3, length 28\n13:54:53.257053 ARP, Request who-has 10.0.20.63 tell 10.0.20.3, length 28\n13:54:53.257054 ARP, Request who-has 10.0.20.64 tell 10.0.20.3, length 28\n13:54:53.257055 ARP, Request who-has 10.0.20.65 tell 10.0.20.3, length 28\n13:54:53.257055 ARP, Request who-has 10.0.20.66 tell 10.0.20.3, length 28\n13:54:53.257056 ARP, Request who-has 10.0.20.67 tell 10.0.20.3, length 28\n13:54:53.257057 ARP, Request who-has 10.0.20.70 tell 10.0.20.3, length 28\n13:54:53.257057 ARP, Request who-has 10.0.20.71 tell 10.0.20.3, length 28\n13:54:53.257058 ARP, Request who-has 10.0.20.72 tell 10.0.20.3, length 28\n13:54:53.257059 ARP, Request who-has 10.0.20.73 tell 10.0.20.3, length 28\n13:54:53.257059 ARP, Request who-has 10.0.20.74 tell 10.0.20.3, length 28\n13:54:53.257060 ARP, Request who-has 10.0.20.75 tell 10.0.20.3, length 28\n13:54:53.257061 ARP, Request who-has 10.0.20.76 tell 10.0.20.3, length 28\n13:54:53.257061 ARP, Request who-has 10.0.20.77 tell 10.0.20.3, length 28\n13:54:53.257062 ARP, Request who-has 10.0.20.78 tell 10.0.20.3, length 28\n13:54:53.257063 ARP, Request who-has 10.0.20.79 tell 10.0.20.3, length 28\n13:54:53.257063 ARP, Request who-has 10.0.20.80 tell 10.0.20.3, length 28\n13:54:53.257064 ARP, Request who-has 10.0.20.81 tell 10.0.20.3, length 28\n13:54:53.257064 ARP, Request who-has 10.0.20.82 tell 10.0.20.3, length 28\n13:54:53.257065 ARP, Request who-has 10.0.20.84 tell 10.0.20.3, length 28\n13:54:53.257066 ARP, Request who-has 10.0.20.85 tell 10.0.20.3, length 28\n13:54:53.257067 ARP, Request who-has 10.0.20.88 tell 10.0.20.3, length 28\n13:54:53.257067 ARP, Request who-has 10.0.20.91 tell 10.0.20.3, length 28\n13:54:53.353028 ARP, Request who-has 10.0.20.126 tell 10.0.20.3, length 28\n13:54:53.353030 ARP, Request who-has 10.0.20.127 tell 10.0.20.3, length 28\n13:54:53.353031 ARP, Request who-has 10.0.20.130 tell 10.0.20.3, length 28\n13:54:53.353031 ARP, Request who-has 10.0.20.131 tell 10.0.20.3, length 28\n13:54:53.353032 ARP, Request who-has 10.0.20.132 tell 10.0.20.3, length 28\n13:54:53.353033 ARP, Request who-has 10.0.20.133 tell 10.0.20.3, length 28\n13:54:53.353033 ARP, Request who-has 10.0.20.134 tell 10.0.20.3, length 28\n13:54:53.353034 ARP, Request who-has 10.0.20.137 tell 10.0.20.3, length 28\n13:54:53.353035 ARP, Request who-has 10.0.20.138 tell 10.0.20.3, length 28\n13:54:53.353036 ARP, Request who-has 10.0.20.139 tell 10.0.20.3, length 28\n13:54:53.353036 ARP, Request who-has 10.0.20.140 tell 10.0.20.3, length 28\n13:54:53.353037 ARP, Request who-has 10.0.20.141 tell 10.0.20.3, length 28\n13:54:53.353037 ARP, Request who-has 10.0.20.142 tell 10.0.20.3, length 28\n13:54:53.353038 ARP, Request who-has 10.0.20.143 tell 10.0.20.3, length 28\n13:54:53.353039 ARP, Request who-has 10.0.20.144 tell 10.0.20.3, length 28\n13:54:53.353039 ARP, Request who-has 10.0.20.145 tell 10.0.20.3, length 28\n13:54:53.353040 ARP, Request who-has 10.0.20.146 tell 10.0.20.3, length 28\n13:54:53.353041 ARP, Request who-has 10.0.20.147 tell 10.0.20.3, length 28\n13:54:53.353041 ARP, Request who-has 10.0.20.148 tell 10.0.20.3, length 28\n13:54:53.353042 ARP, Request who-has 10.0.20.149 tell 10.0.20.3, length 28\n13:54:53.353043 ARP, Request who-has 10.0.20.150 tell 10.0.20.3, length 28\n13:54:53.353043 ARP, Request who-has 10.0.20.151 tell 10.0.20.3, length 28\n13:54:53.353044 ARP, Request who-has 10.0.20.154 tell 10.0.20.3, length 28\n13:54:53.353044 ARP, Request who-has 10.0.20.156 tell 10.0.20.3, length 28\n13:54:53.353045 ARP, Request who-has 10.0.20.157 tell 10.0.20.3, length 28\n13:54:53.353046 ARP, Request who-has 10.0.20.159 tell 10.0.20.3, length 28\n13:54:53.353046 ARP, Request who-has 10.0.20.160 tell 10.0.20.3, length 28\n13:54:53.353047 ARP, Request who-has 10.0.20.162 tell 10.0.20.3, length 28\n13:54:53.353047 ARP, Request who-has 10.0.20.165 tell 10.0.20.3, length 28\n13:54:53.353048 ARP, Request who-has 10.0.20.168 tell 10.0.20.3, length 28\n13:54:53.481257 ARP, Request who-has 10.0.20.199 tell 10.0.20.3, length 28\n13:54:53.481259 ARP, Request who-has 10.0.20.200 tell 10.0.20.3, length 28\n13:54:53.481259 ARP, Request who-has 10.0.20.203 tell 10.0.20.3, length 28\n13:54:53.481260 ARP, Request who-has 10.0.20.204 tell 10.0.20.3, length 28\n13:54:53.481261 ARP, Request who-has 10.0.20.205 tell 10.0.20.3, length 28\n13:54:53.481261 ARP, Request who-has 10.0.20.206 tell 10.0.20.3, length 28\n13:54:53.481262 ARP, Request who-has 10.0.20.207 tell 10.0.20.3, length 28\n13:54:53.481263 ARP, Request who-has 10.0.20.210 tell 10.0.20.3, length 28\n13:54:53.481263 ARP, Request who-has 10.0.20.211 tell 10.0.20.3, length 28\n13:54:53.481264 ARP, Request who-has 10.0.20.213 tell 10.0.20.3, length 28\n13:54:53.481265 ARP, Request who-has 10.0.20.214 tell 10.0.20.3, length 28\n13:54:53.481265 ARP, Request who-has 10.0.20.216 tell 10.0.20.3, length 28\n13:54:53.481266 ARP, Request who-has 10.0.20.217 tell 10.0.20.3, length 28\n13:54:53.481266 ARP, Request who-has 10.0.20.219 tell 10.0.20.3, length 28\n13:54:53.481267 ARP, Request who-has 10.0.20.220 tell 10.0.20.3, length 28\n13:54:53.481268 ARP, Request who-has 10.0.20.222 tell 10.0.20.3, length 28\n13:54:53.481268 ARP, Request who-has 10.0.20.225 tell 10.0.20.3, length 28\n13:54:53.481269 ARP, Request who-has 10.0.20.228 tell 10.0.20.3, length 28\n13:54:53.481270 ARP, Request who-has 10.0.20.233 tell 10.0.20.3, length 28\n13:54:53.481271 ARP, Request who-has 10.0.20.246 tell 10.0.20.3, length 28\n13:54:53.481271 ARP, Request who-has 10.0.20.247 tell 10.0.20.3, length 28\n13:54:53.481272 ARP, Request who-has 10.0.20.249 tell 10.0.20.3, length 28\n13:54:53.481273 ARP, Request who-has 10.0.20.250 tell 10.0.20.3, length 28\n13:54:53.481273 ARP, Request who-has 10.0.20.251 tell 10.0.20.3, length 28\n13:54:53.481274 ARP, Request who-has 10.0.20.252 tell 10.0.20.3, length 28\n13:54:53.481274 ARP, Request who-has 10.0.20.253 tell 10.0.20.3, length 28\n13:54:53.481275 ARP, Request who-has 10.0.20.254 tell 10.0.20.3, length 28\n13:54:53.481276 ARP, Request who-has 10.0.20.0 tell 10.0.20.3, length 28\n13:54:53.481276 ARP, Request who-has 10.0.20.68 tell 10.0.20.3, length 28\n13:54:53.481277 ARP, Request who-has 10.0.20.69 tell 10.0.20.3, length 28\n13:54:53.481278 ARP, Request who-has 10.0.20.114 tell 10.0.20.3, length 28\n13:54:53.481278 ARP, Request who-has 10.0.20.118 tell 10.0.20.3, length 28\n13:54:53.481279 ARP, Request who-has 10.0.20.122 tell 10.0.20.3, length 28\n13:54:53.481280 ARP, Request who-has 10.0.20.128 tell 10.0.20.3, length 28\n13:54:53.481280 ARP, Request who-has 10.0.20.129 tell 10.0.20.3, length 28\n13:54:53.481281 ARP, Request who-has 10.0.20.135 tell 10.0.20.3, length 28\n13:54:53.481281 ARP, Request who-has 10.0.20.136 tell 10.0.20.3, length 28\n13:54:53.481282 ARP, Request who-has 10.0.20.153 tell 10.0.20.3, length 28\n13:54:53.577103 ARP, Request who-has 10.0.20.239 tell 10.0.20.3, length 28\n13:54:53.577104 ARP, Request who-has 10.0.20.194 tell 10.0.20.3, length 28\n13:54:53.577105 ARP, Request who-has 10.0.20.197 tell 10.0.20.3, length 28\n13:54:53.577105 ARP, Request who-has 10.0.20.198 tell 10.0.20.3, length 28\n13:54:53.577106 ARP, Request who-has 10.0.20.201 tell 10.0.20.3, length 28\n13:54:53.577106 ARP, Request who-has 10.0.20.202 tell 10.0.20.3, length 28\n13:54:53.577107 ARP, Request who-has 10.0.20.208 tell 10.0.20.3, length 28\n13:54:53.577108 ARP, Request who-has 10.0.20.209 tell 10.0.20.3, length 28\n13:54:53.672917 ARP, Request who-has 10.0.20.186 tell 10.0.20.3, length 28\n13:54:53.672919 ARP, Request who-has 10.0.20.189 tell 10.0.20.3, length 28\n13:54:53.672920 ARP, Request who-has 10.0.20.192 tell 10.0.20.3, length 28\n13:54:53.672920 ARP, Request who-has 10.0.20.195 tell 10.0.20.3, length 28\n13:54:53.672921 ARP, Request who-has 10.0.20.185 tell 10.0.20.3, length 28\n13:54:53.672922 ARP, Request who-has 10.0.20.188 tell 10.0.20.3, length 28\n13:54:53.672922 ARP, Request who-has 10.0.20.191 tell 10.0.20.3, length 28\n13:54:53.672923 ARP, Request who-has 10.0.20.193 tell 10.0.20.3, length 28\n13:54:53.672924 ARP, Request who-has 10.0.20.187 tell 10.0.20.3, length 28\n13:54:53.672924 ARP, Request who-has 10.0.20.190 tell 10.0.20.3, length 28\n13:54:53.672925 ARP, Request who-has 10.0.20.196 tell 10.0.20.3, length 28\n13:54:55.048845 ARP, Request who-has 10.0.20.3 tell 10.0.20.4, length 28\n13:54:55.048960 ARP, Reply 10.0.20.3 is-at 00:50:56:16:30:c7 (oui Unknown), length 28\n^C\n769 packets captured\n769 packets received by filter\n0 packets dropped by kernel\n

    Another huge flurry of broadcast activity! My apologies for having you scroll through it all, but scanning such output, and even better\u2014analyzing what's going on\u2014is essential practice. Expect lots of output as part of these labs.

    So what did we see in all that? The network scan output reported that host3 and host4 were discovered; did you see where in the packet capture the ARP request and replies are? And speaking of packet captures, we left tcpdump running back on host2, so cancel that now and try to find any broadcasts involving 10.0.20.0/24.

    Assuming everything was done correctly, there should be nothing from that second subnet, as shown in the (heavily shortened) output below. Very good.

    (omitted)\n...\n13:54:05.768997 ARP, Request who-has 10.0.10.44 tell 10.0.10.1, length 28\n13:54:05.768997 ARP, Request who-has 10.0.10.67 tell 10.0.10.1, length 28\n13:54:05.897167 ARP, Request who-has 10.0.10.192 tell 10.0.10.1, length 28\n13:54:05.897170 ARP, Request who-has 10.0.10.201 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.203 tell 10.0.10.1, length 28\n13:54:05.897171 ARP, Request who-has 10.0.10.90 tell 10.0.10.1, length 28\n13:54:05.993145 ARP, Request who-has 10.0.10.248 tell 10.0.10.1, length 28\n13:54:07.432845 ARP, Request who-has 10.0.10.1 tell 10.0.10.2, length 28\n13:54:07.432890 ARP, Request who-has 10.0.10.2 tell 10.0.10.1, length 28\n13:54:07.432893 ARP, Reply 10.0.10.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n13:54:07.432898 ARP, Reply 10.0.10.1 is-at 00:50:56:94:55:70 (oui Unknown), length 28\n^C\n769 packets captured\n769 packets received by filter\n0 packets dropped by kernel\n
    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-and-vlans-in-proxmox/#conclusion-and-next-lab","title":"Conclusion and Next Lab","text":"

    So there you have it: use VLANs around your subnets to maintain full control over your broadcast domains and take advantage of all the other benefits of VLANs that I briefly mentioned in the beginning, which we'll dig into in new labs.

    Now isolating subnets against unwanted broadcast traffic is great, but what about unicast, multicast, or even anycast traffic that needs to be able to reach across subnets? It's time to bring in Layer 3 and the role of routing to enable subnets to communicate and full networks to function. But in order to do that, we'll need to add a router to our lab.

    In the next lab, Installing RouterOS on Proxmox, we'll learn how to install MikroTik's RouterOS, a fantastic network operating system (NOS), on Proxmox so we can use it as our router and firewall in future labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/","title":"Exploring Subnets, Broadcast Domains, and Bridges in Proxmox","text":"

    Based on our progress in the last lab, Connecting and Configuring Network Hosts in Proxmox, we know that our four hosts are somehow able to communicate within their subnet. But how exactly are the hosts connecting?

    Recall that each host is configured with a network device connected to the vmbr1 bridge and assigned an IPv4 address in the 10.0.1.0/24 subnet. These two factors are the key to understanding what is happening behind the scenes.

    In this lab, we're going to begin exploring the concepts of subnets, broadcasting domains, and bridges to allow our hosts to communicate (or not, in some cases). Along the way, we'll see how these fundamental concepts lay the foundation for us to build increasingly complex labs.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/#step-1-examining-the-state-of-our-network-hosts","title":"Step 1: Examining the State of Our Network Hosts","text":"

    The first thing we'll look at is the \"state\" of our network hosts. When host1 sent ping requests and an nmap scan to the other hosts, and received responses, it created records of how to reach them. But how did it find them?

    Remember the Address Resolution Protocol (ARP)? In IPv4, ARP is the first point of contact between hosts on the same subnet. Because host1 has already made contact with each of the other hosts, it should have ARP records accessible that map each host's IPv4 address with its MAC address, which is what is actually used to communicate here on Layer 2.

    When hosts are restarted, however, the ARP cache is flushed, so let's start out with a clean ARP cache here, too, and populate it again so you can visibly see what's happening. First flush host1's ARP cache:

    ip neighbor flush dev eth0\n

    Then perform the nmap network scan again:

    nmap -sn 10.0.1.0/24\n

    which should produce something similar to the following output:

    Starting Nmap 7.80 ( https://nmap.org ) at 2023-06-21 19:07 UTC\nNmap scan report for 10.0.1.1\nHost is up (0.00048s latency).\nNmap scan report for 10.0.1.2\nHost is up (0.00044s latency).\nNmap scan report for 10.0.1.3\nHost is up (0.00022s latency).\nNmap scan report for 10.0.1.4\nHost is up (0.00013s latency).\nNmap done: 256 IP addresses (4 hosts up) scanned in 16.61 seconds\n

    Now that we have a fresh network scan, let's look at host1's ARP cache using the ip tool, part of the iproute2 suite of tools we'll be using regularly in our labs:

    ip neighbor\n

    which should output the following:

    10.0.1.3 dev eth0 lladdr 00:50:56:16:30:c7 REACHABLE\n10.0.1.4 dev eth0 lladdr 00:50:56:ad:24:4a REACHABLE\n10.0.1.2 dev eth0 lladdr 00:50:56:ad:0e:33 REACHABLE\n

    Entries in a device's ARP cache are cached for a certain amount of time and then cleared out, with the \"soft\" limit being once 512 entries are reached and the \"hard\" limit being when there are 1,024 entries, at which point the cache is cleared.

    Check the ARP cache again:

    ip neighbor\n

    and you will see the status of the existing entries have changed, and now indicate they may be flushed if new MAC addresses continue actively populating the ARP cache:

    10.0.1.3 dev eth0 lladdr 00:50:56:16:30:c7 STALE\n10.0.1.4 dev eth0 lladdr 00:50:56:ad:24:4a STALE\n10.0.1.2 dev eth0 lladdr 00:50:56:ad:0e:33 STALE\n

    We won't go much deeper into the innerworkings of the ARP cache at this point, but we will study how the protocol works for neighbor discovery, so you can see what goes on when hosts attempt to reach each other and how it relates to the ARP cache.

    To do this, let's operate from host2, and observe its interactions with host1 at the protocol level during a ping test. To begin, clear out host2's ARP cache so we're starting fresh again:

    sudo ip neighbor flush dev eth0\n

    Return to host1, and begin a packet capture session using tcpdump, another crucial tool we'll be using constantly in our labs:

    sudo tcpdump\n

    Switch back to host2, where we're going to send host1 a single ping request:

    sudo ping -c 1 10.0.1.1\n

    which should produce the following output:

    PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.\n64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.148 ms\n\n--- 10.0.1.1 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 0.148/0.148/0.148/0.000 ms\n

    Here you can see that one request packet was sent from host1 to host2, and a reply packet from host2 to host1 was also successfully transferred, resulting in no packet loss. The two hosts successfully communicated, which means each should now have a record of the other in its ARP cache. Let's check host2's ARP cache:

    ip neighbor\n

    which shows a fresh entry for host2:

    10.0.1.1 dev eth0 lladdr 00:50:56:94:55:70 REACHABLE\n

    This means that not only was host2's ping request successful, but that host1 was properly captured in the ARP cache. The same is also true on the other side for host1. How did all of this happen exchanging just two packets? It didn't\u2014there were six packets involved.

    Let's return to host1, and cancel out (CTRL+C on Windows) of the packet capture. Your output should look very similar to this:

    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n19:21:42.310066 ARP, Request who-has 10.0.1.1 tell 10.0.1.2, length 28\n19:21:42.310088 ARP, Reply 10.0.1.1 is-at 00:50:56:94:55:70 (oui Unknown), length 28\n19:21:42.310132 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 21255, seq 1, length 64\n19:21:42.310140 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 21255, seq 1, length 64\n19:21:47.343328 ARP, Request who-has 10.0.1.2 tell 10.0.1.1, length 28\n19:21:47.343360 ARP, Reply 10.0.1.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n^C\n6 packets captured\n6 packets received by filter\n0 packets dropped by kernel\n

    We'll dig deep into analyzing packets in future labs, but knowing the basics is an invaluable skill from the beginning of your learning to enhance your ability to observe how protocols work and troubleshoot network issues that inevitably arise. So let's start with the packet capture from host2.

    On line 2, you see that tcpdump was listening on host1's eth0 interface, which is connected to host2 via bridge vmbr1 (again, think \"switch\"). That's obvious for this lab, as there's only one interface, but always check on devices with multiple ports.

    The next two lines, 3 and 4, are ARP packets. The first, at 19:21:42.310066, is a broadcast request from the bridge vmbr1 to all hosts on the subnet asking who is 10.0.1.1, as 10.0.1.2 needs to know. The next packet, at 19:21:42.310088, is the broadcast reply from 10.0.1.1 letting the bridge and 10.0.1.2 that it has that IP address, and its MAC address is 00:50:56:94:55:70 (we'll discuss OUIs later).

    The bridge, like any switch, then sends the 3rd packet, at 19:21:42.310132, which is the ICMP echo request (the formal term for the protocol used by ping), to host1, now knowing who it is. host1 responds with the proper ICMP echo reply in the packet at 19:21:42.310140, addressed to 10.0.1.2, but not sure which host that is.

    As a result, host1 also utilizes ARP in packet 5, at 19:21:47.343328, broadcasting a request asking who has 10.0.1.2, as 10.0.1.1 needs to know. The sixth packet, at 19:21:47.343360, is the broadcast reply from 10.0.1.2 letting the bridge and 10.0.1.2 that it has that IP address, and its MAC address is 00:50:56:ad:0e:33.

    When the packet capture was stopped, it completed its job by reporting the number of packets captured, filtered, and dropped. We didn't have a filter defined, such as filtering out ARP packets, and no packets were dropped because of other transmission issues, so it was a successful job.

    One last point about ARP before we move on. Once host1 and host2 know each other, is ARP no longer necessary, since they can simply address each other directly during communication? As with anything in our labs, let's test it out.

    Just like before, put host1 into a packet capture mode:

    sudo tcpdump\n

    and have host2 ping host1. This time, however, have host2 flood ping host1 25 times:

    sudo ping -f -c 25 10.0.1.1\n

    This should result in something like the following:

    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n02:14:34.087556 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 1, length 64\n02:14:34.087576 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 1, length 64\n02:14:34.087644 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 2, length 64\n02:14:34.087647 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 2, length 64\n02:14:34.087702 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 3, length 64\n02:14:34.087705 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 3, length 64\n02:14:34.087740 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 4, length 64\n02:14:34.087743 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 4, length 64\n02:14:34.087769 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 5, length 64\n02:14:34.087772 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 5, length 64\n02:14:34.087797 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 6, length 64\n02:14:34.087800 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 6, length 64\n02:14:34.087845 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 7, length 64\n02:14:34.087848 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 7, length 64\n02:14:34.087897 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 8, length 64\n02:14:34.087900 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 8, length 64\n02:14:34.087933 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 9, length 64\n02:14:34.087936 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 9, length 64\n02:14:34.087962 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 10, length 64\n02:14:34.087964 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 10, length 64\n02:14:34.087997 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 11, length 64\n02:14:34.088000 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 11, length 64\n02:14:34.088033 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 12, length 64\n02:14:34.088036 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 12, length 64\n02:14:34.088078 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 13, length 64\n02:14:34.088081 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 13, length 64\n02:14:34.088105 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 14, length 64\n02:14:34.088108 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 14, length 64\n02:14:34.088141 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 15, length 64\n02:14:34.088144 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 15, length 64\n02:14:34.088178 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 16, length 64\n02:14:34.088180 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 16, length 64\n02:14:34.088221 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 17, length 64\n02:14:34.088224 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 17, length 64\n02:14:34.088255 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 18, length 64\n02:14:34.088257 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 18, length 64\n02:14:34.088295 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 19, length 64\n02:14:34.088298 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 19, length 64\n02:14:34.088329 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 20, length 64\n02:14:34.088331 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 20, length 64\n02:14:34.088373 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 21, length 64\n02:14:34.088375 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 21, length 64\n02:14:34.088414 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 22, length 64\n02:14:34.088417 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 22, length 64\n02:14:34.088448 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 23, length 64\n02:14:34.088450 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 23, length 64\n02:14:34.088475 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 24, length 64\n02:14:34.088478 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 24, length 64\n02:14:34.088502 IP 10.0.1.2 > 10.0.1.1: ICMP echo request, id 9783, seq 25, length 64\n02:14:34.088504 IP 10.0.1.1 > 10.0.1.2: ICMP echo reply, id 9783, seq 25, length 64\n02:14:39.183337 ARP, Request who-has 10.0.1.2 tell 10.0.1.1, length 28\n02:14:39.183380 ARP, Reply 10.0.1.2 is-at 00:50:56:ad:0e:33 (oui Unknown), length 28\n^C\n52 packets captured\n52 packets received by filter\n0 packets dropped by kernel\n

    So the basic answer is that, for the most part, once hosts have cached their addresses in the ARP cache, they can communicate via unicast transmission. Every so often, however, ARP checks are sent to verify host addressing, thus the two extra packets in addition to the 25 pairs of ICMP request/reply pairs.

    Question

    Wondering how often ARP is part of the transmissions between known hosts? Modify the ping command above to use higher count flood pings and see what happens. If it's too many, does the kernel drop packets?

    As we saw with the ARP process, communication between hosts begins with broadcasts across their subnet to determine which hosts have which MAC and IP addresses. Let's move on and learn more about the role of subnets and broadcast domains.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/#step-2-digging-into-ipv4-subnets-and-broadcast-domains","title":"Step 2: Digging into IPv4 Subnets and Broadcast Domains","text":"

    Currently our network consists of four hosts all assigned IPv4 addresses in the same subnet of 10.0.1.0/24, all contained in the same Layer 2 bridge vmbr1. Because they are in the same subnet, and on the same bridge, they should always be able to communicate. We've verifed this using both ping and nmap tests.

    Performing a packet capture, we've also seen what happens during communication at the protocol layer, with hosts broadcasting ARP requests/replies to all hosts when identifying each other. How does broadcasting work within a subnet?

    As we know, a subnet is a defined IP space assigned to hosts. So far, we have assigned the IPs

    • 10.0.1.1 to host1
    • 10.0.1.2 to host2
    • 10.0.1.3 to host3
    • 10.0.1.4 to host4

    Note

    You might have noticed that the last \"octet\" of each host matches the number in each host name. IP addressing is generally arbitrary, but we'll do things like this in some cases to help you follow along in these early labs.

    How many hosts can we have in this address space? You probably have seen many ways to calculate subnet sizes, but let's make it easy by using another handy tool on our Linux hosts: ipcalc.

    Ask ipcalc to calculate the details of our 10.0.1.0/24 subnet from host1:

    ipcalc 10.0.1.0/24\n

    which reports back the following:

    Address:   10.0.1.0             00001010.00000000.00000001. 00000000\nNetmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000\nWildcard:  0.0.0.255            00000000.00000000.00000000. 11111111\n=>\nNetwork:   10.0.1.0/24          00001010.00000000.00000001. 00000000\nHostMin:   10.0.1.1             00001010.00000000.00000001. 00000001\nHostMax:   10.0.1.254           00001010.00000000.00000001. 11111110\nBroadcast: 10.0.1.255           00001010.00000000.00000001. 11111111\nHosts/Net: 254                   Class A, Private Internet\n

    ipcalc has provided us everything we need to know about our subnet in a very nice format. On the left is the name of each calculation, followed by the value in IPv4 integer octets, then the value again formatted as binary octets (for all IP-related data). The last line is a bit different, which we'll also cover below.

    • The Address line shows the address that we submitted in the command
    • The Netmask line shows the netmask that we submitted in the command, both in octet and CIDR format
    • The Wildcard line shows the usable portion of the address within the subnet while everything in the first three octets remains fixed
    • The Network line shows the network ID for this subnet, which you'll recall we used in our nmap network discovery scans
    • The HostMin line shows the first address in this subnet available for host assignment; and we've assigned this value to host1
    • The HostMax line shows the last address in this subnet available for host assignment, and we haven't assigned this value to any host yet
    • The Broadcast line shows the broadcast address in this subnet
    • The Hosts/Net line shows the total number of hosts available in this subnet, which is 256 in our case

    The Network address cannot be assigned to a host, thus it cannot respond to ping requests, either. Let's verify this with a test from host1:

    sudo ping -c 4 10.0.1.0\n

    which results in no replies, as expected:

    PING 10.0.1.0 (10.0.1.0) 56(84) bytes of data.\nFrom 10.0.1.1 icmp_seq=1 Destination Host Unreachable\nFrom 10.0.1.1 icmp_seq=2 Destination Host Unreachable\nFrom 10.0.1.1 icmp_seq=3 Destination Host Unreachable\nFrom 10.0.1.1 icmp_seq=4 Destination Host Unreachable\n\n--- 10.0.1.0 ping statistics ---\n4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3077ms\n

    Tip

    Before we move on, bring up a detached console window for each host in Proxmox by clicking the Console button near the top-right of each guest view, and arrange them on your screen so they're all visible. Depending on your desktop, there are \"quarter tile\" features built-in, such as in Windows or KDE, or extentions available, such as Rectangle for macOS or WinTile for GNOME.

    We already know we can ping 10.0.1.1 through 10.0.1.4, and anything up to 10.0.1.254 if we had hosts assigned to those IP addresses. But what about the broadcast address? Don't hosts use that for ARP request/replies? Let's try to ping it from host1:

    sudo ping 10.0.1.255\n

    and we get an interesting response:

    ping: Do you want to ping broadcast? Then -b. If not, check your local firewall rules\n

    The ping command is giving us a helpful tip: if we want to ping the broadcast address, we need to add the -c flag to the command. Let's try again from host1:

    sudo ping -b 10.0.1.255\n

    and now we get the following output:

    WARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n

    At this point ping is sending ICMP requests, but nothing is visible in the output like it would a normal ping test. How can we observe what's happening? Let's check our other hosts.

    On host2, host3, and host4, run the following command:

    sudo tcpdump\n

    Upon doing this, you should see something similar to the following:

    01:15:56.463377 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 29, length 64\n01:15:57.487378 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 30, length 64\n01:15:58.515390 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 31, length 64\n01:15:59.535379 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 32, length 64\n01:16:00.559384 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 59888, seq 33, length 64\n

    In these packet captures, you're seeing broadcast requests from host1 at 10.0.1.1 to the broadcast address for this subnet at 10.0.1.255. In this case, there are two key things to notice:

    1. Each packet is an ICMP echo request, with no ICMP echo reply being returned
    2. Within each host's console, the seq count matches, showing that every host is receiving the broadcasts simultaneously

    Return to host1 and cancel the broadcast pings with Ctrl+C, and look at the results:

    WARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n^C\n--- 10.0.1.255 ping statistics ---\n33 packets transmitted, 0 received, 100% packet loss, time 32757ms\n

    In this case, 33 packets (here in my case, for example) were broadcasted, but host1 believes none were received resulting in 100% packet loss. However, as we saw using tcpdump, the packets were delivered, but no protocol, such as ARP, was targeted for a reply.

    Note

    There are times where hosts may reply to broadcast pings using approaches such as nmap --script broadcast-ping, but it is not a reliable method depending on the host configuration.

    Now that we've experimented with broadcasts a bit, let's consider the broadcast domain itself. So far, we've observed that all hosts in the subnet can be reached via unicast and broadcast communication. Does this mean the subnet and broadcast domain are contiguous? Let's test this by making a change.

    From Proxmox's UI, change host2's IPv4 address to 10.0.2.2/24. By doing this, we create a second subnet within the same bridge vmbr1. Next, calculate host2's subnet details using the ipcalc tool:

    ipcalc 10.0.2.2/24\n

    and we can see from the results that host2 is now in a completely different subnet:

    Address:   10.0.2.2             00001010.00000000.00000010. 00000010\nNetmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000\nWildcard:  0.0.0.255            00000000.00000000.00000000. 11111111\n=>\nNetwork:   10.0.2.0/24          00001010.00000000.00000010. 00000000\nHostMin:   10.0.2.1             00001010.00000000.00000010. 00000001\nHostMax:   10.0.2.254           00001010.00000000.00000010. 11111110\nBroadcast: 10.0.2.255           00001010.00000000.00000010. 11111111\nHosts/Net: 254                   Class A, Private Internet\n
    • The Network is now 10.0.2.0/24, not 10.0.1.0/24
    • The HostMin is now 10.0.2.1 and the HostMax is now 10.0.2.254
    • The Broadcast is now 10.0.2.255

    Going back to host1, try to ping host2:

    sudo ping 10.0.2.2\n

    Doing this will issue an error:

    ping: connect: Network is unreachable\n

    Try the same from host2, and try to ping host1:

    sudo ping 10.0.1.1\n

    Again, the other subnet is unreachable:

    ping: connect: Network is unreachable\n

    It appears both subnets are isolated from each other, and for subnets on the same switch, this is generally what you want. But are they? Let's try a broadcast from host1 to its subnet's broadcast address. First start the broadcasting from host1:

    sudo ping -b 10.0.1.255\n

    Next, start a packet capture on host2:

    sudo tcpdump\n

    Did you end up with something similar to the output displayed below? What are you now seeing on host2? ICMP requests from host1 on the other network? Apparently broadcast domains are larger in scope than subnets.

    18:05:12.216806 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 1, length 64\n18:05:13.231371 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 2, length 64\n18:05:14.255380 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 3, length 64\n18:05:15.279377 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 4, length 64\n18:05:16.303372 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 5, length 64\n18:05:17.327376 IP 10.0.1.1 > 10.0.1.255: ICMP echo request, id 2358, seq 6, length 64\n

    It appears that hosts on different subnets cannot directly communicate with each other at Layer 3, but communication is still possible at Layer 2. This is because there is a difference between a Layer 3 broadcast address and a Layer 2 broadcast domain.

    These are the next questions we need to explore with our labs:

    1. How would we prevent communication between subnets at Layer 2
    2. How would we allow communication between subnets at Layer 3

    Before we wrap up this lab, let's consider the role of bridging in this situation.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/#step-3-dipping-our-toes-into-bridging-details","title":"Step 3: Dipping Our Toes into Bridging Details","text":"

    Recall the differences between hubs and switches. Hubs broadcast all frames out to all connected hosts, and not those destined for the broadcast address. All connected hosts are also in the same collision domain, causing packets to collide when hosts attempt to communicate at the same time.

    Switches, however, can enable unicast communication between hosts while limiting broadcasts to all hosts. Each port on a switch is a separate collision domain, as well, preventing packet transmissions among hosts from interfering with each other.

    What about our Linux bridge? In an earlier lab I stated bridges are basically switches, especially in eliminating the impact of collision domains, but they share other characteristics, too. Let's make some more changes to our network to experiment with the impact of bridges on subnets and broadcast domains.

    The first thing we need to do is create another Linux bridge on our Proxmox hypervisor:

    1. At the top of the Proxmox resource tree, select the Proxmox node your lab is running within and then select the System > Network view of the content panel.
    2. At the top-left of the network device table, click the Create dropdown button and select Linux Bridge.
    3. In the dialog box, ensure the Name is vmbr2 and Autostart is checked, then click the Create button.
    4. At the top of the network device table, click the Apply Configuration button and the new bridge will be enabled.

    Next, edit host2s network configuration in Proxmox by setting the eth0 network device's bridge to vmbr2. Be sure to keep the IPv4 address the same, however.

    Now, again start pinging from host1 to its broadcast address:

    sudo ping -b 10.0.1.255\n

    Then start another packet capture on host2:

    sudo tcpdump\n

    What happened this time? Let's look at the results of host1's and host2's output together:

    WARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n^C\n--- 10.0.1.255 ping statistics ---\n145 packets transmitted, 0 received, 100% packet loss, time 147437ms\n
    listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n^C\n0 packets captured\n0 packets received by filter\n0 packets dropped by kernel\n

    In this case, host1 transmitted 145 packets, but host2 captured none of them. Now Layer 2 communication is blocked by creating a second bridge, thus creating two broadcast domains. Bridging seems key to answering the question about preventing communication between subnets at Layer 2.

    Before we wrap up, let's perform a larger test of both unicast and broadcast communication. Like host2, change host4's Bridge to vmbr2, but keep its IPv4 address 10.0.1.4/24. Then arrange the console windows for all four hosts in a quarter tile layout so they're all visible.

    Start a packet capture again on host2:

    sudo tcpdump\n

    and start a ping test on host4 to that subnet's broadcast address:

    sudo ping -b -c 4 10.0.1.255\n

    Next, start a packet capture on host1:

    sudo tcpdump\n

    and start a ping test on host3:

    sudo ping -b -c 4 10.0.1.255\n

    Let's review the results for each host, grouped by bridge.

    host3 sent four ICMP echo requests, which were detected (but not replied to) by host1 within bridge vmbr1:

    eron@host3:~$ sudo ping -b -c 4 10.0.1.255\nWARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n\n--- 10.0.1.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3072ms\n
    eron@host1:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n11:23:16.591449 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 1, length 64\n11:23:17.615374 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 2, length 64\n11:23:18.639371 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 3, length 64\n11:23:19.663375 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 54008, seq 4, length 64\n^C\n4 packets captured\n4 packets received by filter\n0 packets dropped by kernel\n

    Just as above, host4 sent four ICMP echo requests, which were detected (but not replied to) by host2 within bridge vmbr2:

    eron@host4:~$ sudo ping -b -c 4 10.0.1.255\nWARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n\n--- 10.0.1.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3064ms\n
    eron@host2:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n11:22:47.191030 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 1, length 64\n11:22:48.207371 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 2, length 64\n11:22:49.231376 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 3, length 64\n11:22:50.255377 IP 10.0.1.4 > 10.0.1.255: ICMP echo request, id 27961, seq 4, length 64\n^C\n4 packets captured\n4 packets received by filter\n0 packets dropped by kernel\n

    Within bridge vmbr1, the two hosts were in the same subnet, and the broadcasts were captured as expected. Within bridge vmbr2, the two hosts were not in the same subnet, but the broadcasts were still captured.

    Remember that this was also expected, because regardless of the subnet, broadcasts are being transmitted across the entire Layer 2 broadcast domain, which right now is the entire bridge.

    So we see that bridges can isolate broadcast domains, but only when there is one subnet per bridge. But that essentially means having to restrict an entire switch to only one subnet, which is unrealistic in nearly any network with multiple subnets. In a physical network, this would require a switch for each subnet.

    As our final experiment, let's move host2 and host4 back to vmbr1, and change host4's IPv4 address to 10.0.2.4/24, so it's in the same subnet as host2. With those configuration changes made, we now have two subnets, each with two hosts, on one bridge. What happens when they start communicating?

    Start a packet capture on host1:

    sudo tcpdump\n

    and start a ping test to 10.0.1.0/24 network's broadcast address from host3:

    sudo ping -b -c 4 10.0.1.255\n

    Next start a packet capture on host2:

    sudo tcpdump\n

    and start a ping test to 10.0.2.0/24 network's broadcast address from host4:

    sudo ping -b -c 4 10.0.2.255\n

    Again we'll review the results for each host, grouped by bridge.

    host3 sent four ICMP echo requests, which were detected (but not replied to) by host1 within bridge vmbr1:

    eron@host3:~$ sudo ping -b -c 4 10.0.1.255\nWARNING: pinging broadcast address\nPING 10.0.1.255 (10.0.1.255) 56(84) bytes of data.\n\n--- 10.0.1.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3065ms\n
    eron@host1:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n15:07:12.790897 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 1, length 64\n15:07:13.807380 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 2, length 64\n15:07:14.831382 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 3, length 64\n15:07:15.855384 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 4, length 64\n15:07:44.485779 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 1, length 64\n15:07:45.487366 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 2, length 64\n15:07:46.511402 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 3, length 64\n15:07:47.535375 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 4, length 64\n^C\n8 packets captured\n8 packets received by filter\n0 packets dropped by kernel\n

    But wait, there are four broadcast packets from host4 here as well! All host4 did was send four ICMP echo requests on its own subnet, which were detected (but not replied to) by host2 within bridge vmbr1:

    eron@host4:~$ sudo ping -b -c 4 10.0.2.255\nWARNING: pinging broadcast address\nPING 10.0.2.255 (10.0.2.255) 56(84) bytes of data.\n\n--- 10.0.2.255 ping statistics ---\n4 packets transmitted, 0 received, 100% packet loss, time 3050ms\n
    eron@host2:~$ sudo tcpdump\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n15:07:12.790892 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 1, length 64\n15:07:13.807374 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 2, length 64\n15:07:14.831376 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 3, length 64\n15:07:15.855379 IP 10.0.1.3 > 10.0.1.255: ICMP echo request, id 57207, seq 4, length 64\n15:07:44.485776 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 1, length 64\n15:07:45.487364 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 2, length 64\n15:07:46.511399 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 3, length 64\n15:07:47.535372 IP 10.0.2.4 > 10.0.2.255: ICMP echo request, id 7169, seq 4, length 64\n^C\n8 packets captured\n8 packets received by filter\n0 packets dropped by kernel\n

    The packet capture from host2 shows packets from host4 along with those from host3 as well! So now we really see the problem: how can we restrict broadcast domains within the same bridge or switch containing multiple subnets?

    We'll figure that out in the next lab, Exploring Subnets and VLANs in Proxmox. Great work today; I know this was a long lab, but hopefully these concepts are starting to make sense.

    ","tags":["Proxmox","Linux"]},{"location":"labs/networks/general/initial-proxmox-network-configuration/","title":"Initial Proxmox Network Configuration","text":"

    In this lab we'll review Proxmox's initial configuration and discuss some preparatory changes to support our lab activities.

    Warning

    Be sure to review the following recommendations before beginning the labs to ensure your setup is configured properly and help you avoid conflicts or downtime on your home LAN.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#default-network-configuration","title":"Default Network Configuration","text":"

    Out of the box, Proxmox detects all compatible network interface cards (NICs) on each node and adds them to the node's list of network devices in the \"System\" > \"Network\" panel. The Proxmox installation will also create a Linux Bridge called vmbr0 that maps to one of the hardware NICs for LAN connectivity.

    This bridge will be configured with IP addressing for the node itself and the default gateway for the LAN the node is connected to. The IP addresses for vmbr0 will be used for accessing the node via the Web and SSH, and also will provide connectivity for clustering with other nodes.

    I recommend considering vmbr0 to be the node's management network, and restricted for these roles. Depending on the setup, it may also be used for LAN access for production VMs and CTs (often on separate VLANs).

    For our labs, however, we'll create separate bridges that allow us to create self-contained networks, and eventually we'll implement functionality to extend our networks to additional hardware and the Internet.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#lab-preparation-changes","title":"Lab Preparation Changes","text":""},{"location":"labs/networks/general/initial-proxmox-network-configuration/#ip-addressing-recommendations","title":"IP Addressing Recommendations","text":"

    There are many ways to plan out your home lab's IP addressing, and as your skills improve your preferences will evolve along with your lab's needs. However, at the very least I strongly suggest having a separate address space from your home LAN and isolate your home lab activities from taking down the LAN that others in your home depend on.

    My personal IPv4 address plan is the following:

    • 192.168.0.0/16 for my home's LAN, split into separate subnets for secure Wi-Fi, guest Wi-Fi, IoT, etc.
    • 172.16.0.0/12 for my home's management network, also split into separate subnets for network equipment, server/storage equipment, security devices, production VMs/CTs, etc.
    • 10.0.0.0/8 for my home lab subnets, as necessary. We'll be using this address space here in the documentation, as well, so you're aware.
    • In addition to the 10/8 prefix, we'll also be using some non-RFC 1918 prefixes reserved for private use to represent public address space in our labs. This includes the TEST-NET prefixes 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, and the non-allocated prefix 128.66.0.0/16.

    Not included yet is a IPv6 address plan, which should also be considered an essential discipline for network training. Mastering IPv6 through my home labs is a personal priority of mine, so stay tuned for more on that.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#hardware-recommendations","title":"Hardware Recommendations","text":"

    The device used to install Proxmox should have at least two NICs:

    • One for vmbr0 and the management network roles described above
    • Another for lab VM access to your LAN

    Ideally, it would be better to have at least four NICs:

    • One for vmbr0
    • One for cluster communication
    • One for production VMs and CTs to access your LAN
    • One for lab VMs and CTs to access your LAN

    We'll expand on this setup in future labs, as well as upgrading your node with the necessary hardware, but for now we'll focus on a two NIC configuration.

    "},{"location":"labs/networks/general/initial-proxmox-network-configuration/#custom-mac-address-prefix","title":"Custom MAC Address Prefix","text":"

    By default, Proxmox uses unregistered and randomized MAC addresses for the virtual network devices for VMs and CTs, which are listed within the \"Hardware\" view for VMs and the \"Network\" view for CTs. There are called Locally Administered Addresses (LAAs).

    Used for server VMs and CTs, this doesn't seem to be an issue. However, I ran into and issue when installing VyOS on Proxmox where it wouldn't add all detected interfaces to the configuration because the the MAC addresses weren't Universally Administered Address (UAAs). It may also affect other network operating systems (NOSs) as well, but I haven't yet verified that.

    It won't prevent you from configuring and using VyOS on Proxmox, but it can help new users to have this functionality in place and the fix is easy: instead of using LAA MAC addresses, set a custom prefix that Promox will use as a UAA OUI for all network devices.

    To do this, click on the \"Datacenter\" your node is in, then click on \"Options\" and edit the \"MAC address prefix\" to be 00:50:56. This is the VMWare OUI used for network devices within their virtualization platforms, and VyOS (or any other OS) should properly recognize it.

    From now on all virtual network devices will be issued a UAA MAC address with the 00:50:56 OUI and a random suffix. For some labs I may have you configure specific MAC addresses for lab tasks, so maintaining consistency will be helpful.

    "},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/","title":"Initial Junos OS Configuration on a vSRX","text":"

    After installing vSRX in a VM, we\u2019re ready to perform the initial configuration. Log in as user root (no password required), and enter configuration mode with configure.

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-root-password","title":"Set root password","text":"

    Before making any changes to the factory-installed configuration, you will need to first set a password for the root user. Let\u2019s do that before making any other changes:

    1. set system root-authentication plain-text-password
    2. Enter secure password twice when prompted
    3. commit and-quit
    4. quit
    5. Log back into Junos OS using the new account credentials to verify
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#create-a-non-root-user","title":"Create a non-root user","text":"

    Using the root account for device operation is almost never a good idea, so next let\u2019s create a non-root user with all privileges using the local database:

    1. set system login user <user_name> full-name \"<full_name>\"
    2. set system login user <user_name> class super-user
    3. set system login user <user_name> authentication plain-text-password
    4. Enter secure password twice when prompted
    5. commit and-quit
    6. quit
    7. Log back into Junos OS using the new account credentials to verify
    8. Re-enter configuration mode with configure
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-management-interface","title":"Set management interface","text":"

    Every network device should have a management interface, ideally out-band-band from the rest of the interfaces, to securely operate the device. For the vSRX, it\u2019s the fxp0 interface. For now, let\u2019s have it get an address via DCHP so we can use that address to access the device from here via SSH:

    1. set interfaces fxp0 unit 0 family inet dhcp
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#enable-ssh-access","title":"Enable SSH access","text":"

    Instead of accessing vSRX using a console connection or hypervisor virtual terminal, we can now use SSH through the management interface. Enable it with:

    1. set system services ssh
    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-host-name","title":"Set host name","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-domain-name","title":"Set domain name","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-dns-servers","title":"Set DNS servers","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-static-default-route-with-no-readvertise-option","title":"Set static default route with no-readvertise option","text":"

    You should be as specific about the route as possible. You can also use the no-readvertise option for the static route used for management traffic. This marks the route ineligible for readvertisement through routing policy.

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-time-zone","title":"Set time zone","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-ntp-servers","title":"Set NTP servers","text":"","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#set-rescue-configuration","title":"Set rescue configuration","text":"

    You can configure a single logical unit for the lo0 interface for each routing instance, and each logical unit associated with a given routing instance can have multiple configured IP addresses.

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#commit-changes","title":"Commit changes","text":"

    commit comment \"Initial configuration performed\"

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/initial-junos-os-configuration-best-practices/#verification","title":"Verification","text":"
    • Using the Proxmox console, check the management network interface IP address with run show dhcp client binding fxp0.0.

      eron@vsrx-r1> show dhcp client binding fxp0.0 IP address Hardware address Expires State Interface 172.16.0.110 a2:2f:9d:45:aa:2a 263 BOUND fxp0.0

    • Using the IP address above, log into the router with the new non-root user via an SSH client with ssh <user_name>@<ip_address>.

      PS C:\\Users\\eronl> ssh eron@172.16.0.110 Password: Last login: Tue Jun 6 02:16:18 2023 from 172.16.0.53 --- JUNOS 20.3R1.8 Kernel 64-bit XEN JNPR-11.0-20200908.87c9d89_buil eron@vsrx-r1>

    ","tags":["Juniper"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/","title":"Installing Juniper vSRX on Proxmox","text":"","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-1-download-a-vsrx-image-from-juniper","title":"Step 1: Download a vSRX Image From Juniper","text":"

    Unless you have a licensed copy of vSRX, you will need to download the trial version for home lab use from Juniper's website. And in order to do that, you must have an account and authorization to download trial software.

    If you already can do this, skip ahead to step two. Otherwise, perform the following tasks:

    • Log into or register for your Juniper account.
    • Request access to the trial version of vSRX by following these instructions.
    • Once your account is authorized by JTAC, download the trial version of vSRX here. For Proxmox VE, choose the vSRX KVM Appliance.
    • Download and save your trial license, but just hold onto this for now. It shouldn't be necessary for most functionality.
    ","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-2-upload-the-vsrx-image-to-a-proxmox-ve","title":"Step 2: Upload the vSRX Image to a Proxmox VE","text":"

    Next you'll need to upload the vSRX trial image to a Proxmox VE machine in preparation for installation. In this case I did scp junos-vsrx3-x86-64-20.3R1.8.qcow2 <user>@<pve>:~ to copy the file to my Proxmox VE user's home folder, which is good enough for this step.

    Verify the file was successfully transferred, and we'll revisit this again after the next step.

    ","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-3-create-the-virtual-machine","title":"Step 3: Create the Virtual Machine","text":"

    vSRX will run as a VM on Proxmox VE, but it's not ready out of the box. You'll first have to create the VM configuration within Proxmox VE, including naming and hardware settings.

    The minimum requirements for running vSRX in KVM are

    • 2 CPUs
    • 4 GB RAM
    • 20 GB storage

    qm importdisk <vm-id> junos-vsrx3-x86-64-20.3R1.8.qcow2 local-lvm

    ","tags":["Juniper","Proxmox"]},{"location":"labs/networks/juniper/installing-vsrx-on-proxmox/#step-4-verify-vm-bootup-and-initial-login","title":"Step 4: Verify VM Bootup and Initial Login","text":"","tags":["Juniper","Proxmox"]},{"location":"labs/networks/mikrotik/default-routes/","title":"Default Routes","text":"
    • Basic default routes
    • Static default routes
    • Floating default routes
    "},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/","title":"Initial RouterOS Configuration Best Practices [DRAFT]","text":"

    After installing RouterOS in a VM, we\u2019re ready to perform the initial configuration.

    Log in as the user admin, without a password.

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#secure-the-admin-user","title":"Secure the Admin User","text":"

    Using the default account for device operation is almost never a good idea, so let\u2019s create a new admin user with all privileges and remove the vyos account.

    1. set system login user <user_name> full-name \"<full_name>\"
    2. set system login user <user_name> class super-user
    3. set system login user <user_name> authentication plain-text-password
    4. Enter secure password twice when prompted
    5. commit
    6. quit
    7. Log back into VyOS using the new account credentials to verify
    8. Re-enter configuration mode with configure
    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#configure-a-management-interface","title":"Configure a Management Interface","text":"

    Every network device should have a management interface, ideally out-band-band from the rest of the interfaces, to securely operate the device. For VyOS, let's standardize on the eth0 interface and have it get an address via DCHP so we can use that address to access the device via SSH.

    set interfaces fxp0 unit 0 family inet dhcp\n
    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#enable-ssh-access","title":"Enable SSH access","text":"

    Instead of accessing vSRX using a console connection or hypervisor virtual terminal, we can now use SSH through the management interface. Enable it with:

    1. set system services ssh
    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-host-name","title":"Set host name","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-domain-name","title":"Set domain name","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-dns-servers","title":"Set DNS servers","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-static-default-route-with-no-readvertise-option","title":"Set static default route with no-readvertise option","text":"

    You should be as specific about the route as possible. You can also use the no-readvertise option for the static route used for management traffic. This marks the route ineligible for readvertisement through routing policy.

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-time-zone","title":"Set time zone","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-ntp-servers","title":"Set NTP servers","text":"","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#set-rescue-configuration","title":"Set rescue configuration","text":"

    You can configure a single logical unit for the lo0 interface for each routing instance, and each logical unit associated with a given routing instance can have multiple configured IP addresses.

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#commit-changes","title":"Commit changes","text":"

    commit comment \"Initial configuration performed\"

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/initial-routeros-configuration-best-practices/#verification","title":"Verification","text":"
    • Using the Proxmox console, check the management network interface IP address with run show dhcp client binding fxp0.0.

      eron@vsrx-r1> show dhcp client binding fxp0.0 IP address Hardware address Expires State Interface 172.16.0.110 a2:2f:9d:45:aa:2a 263 BOUND fxp0.0

    • Using the IP address above, log into the router with the new non-root user via an SSH client with ssh <user_name>@<ip_address>.

      PS C:\\Users\\eronl> ssh eron@172.16.0.110 Password: Last login: Tue Jun 6 02:16:18 2023 from 172.16.0.53 --- JUNOS 20.3R1.8 Kernel 64-bit XEN JNPR-11.0-20200908.87c9d89_buil eron@vsrx-r1>

    ","tags":["MikroTik","RouterOS"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/","title":"Installing MikroTik RouterOS on Proxmox [DRAFT]","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#introduction","title":"Introduction","text":"

    To enable our subnets on Linux bridges to communicate within our labs across increasingly complex network topologies, we have to add Layer 3 and 4 capabilities to our setup. To do this, we're going incorporate MikroTik's RouterOS into Proxmox and serve in this capacity.

    If you're not familiar with RouterOS and why it's a fantastic platform to learn and use in your networks, check out this blog post where we cover what it is, its background and architecture, and its advantages for both practice labs and production networks.

    In this lab, we're going to cover the process to install a RouterOS virtual machine (VM) in Proxmox and prepare it for use as a full-featured router/firewall/vpn in our networks.

    We will be using the

    ","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#step-1-adding-routeros-as-an-image-in-proxmox","title":"Step 1: Adding RouterOS as an Image in Proxmox","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#step-2-creating-and-configuring-a-vm-for-routeros","title":"Step 2: Creating and Configuring a VM for RouterOS","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#step-3-installing-the-routeros-image-on-a-vm","title":"Step 3: Installing the RouterOS Image on a VM","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/installing-routeros-on-proxmox/#conclusion-and-next-lab","title":"Conclusion and Next Lab","text":"","tags":["MikroTik","RouterOS","Proxmox"]},{"location":"labs/networks/mikrotik/static-routing-between-subnets-with-routeros/","title":"Static Routing Between Subnets with RouterOS [DRAFT]","text":"","tags":["MikroTik","RouterOS","Linux","Proxmox"]},{"location":"labs/networks/mikrotik/static-routing-between-subnets-with-routeros/#lab-setup","title":"Lab Setup","text":"

    For this lab, we'll need the following to be pre-configured:

    • host1 is on vmbr1 and has an IPv4 address of 10.0.1.10/24
    • host2 is on vmbr1 and has an IPv4 address of 10.0.1.11/24
    • host3 is on vmbr1 and has an IPv4 address of 10.0.2.10/24
    • host4 is on vmbr1 and has an IPv4 address of 10.0.2.11/24
    • routeros-r1 is on vmbr1 and has an IPv4 address on ether1 of 10.0.1.1/24
    • routeros-r2 is on vmbr1 and has an IPv4 address on ether1 of 10.0.2.1/24
    ","tags":["MikroTik","RouterOS","Linux","Proxmox"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/","title":"Initial VyOS Configuration Best Practices [DRAFT]","text":"

    After installing VyOS in a VM, we\u2019re ready to perform the initial configuration.

    Log in as the user vyos and the password you created during installation (default is vyos), and enter configuration mode with configure.

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#create-a-unique-admin-user","title":"Create a Unique Admin User","text":"

    Using the default account for device operation is almost never a good idea, so let\u2019s create a new admin user with all privileges and remove the vyos account.

    1. set system login user <user_name> full-name \"<full_name>\"
    2. set system login user <user_name> class super-user
    3. set system login user <user_name> authentication plain-text-password
    4. Enter secure password twice when prompted
    5. commit
    6. quit
    7. Log back into VyOS using the new account credentials to verify
    8. Re-enter configuration mode with configure
    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#configure-a-management-interface","title":"Configure a Management Interface","text":"

    Every network device should have a management interface, ideally out-band-band from the rest of the interfaces, to securely operate the device. For VyOS, let's standardize on the eth0 interface and have it get an address via DCHP so we can use that address to access the device via SSH.

    set interfaces fxp0 unit 0 family inet dhcp\n
    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#enable-ssh-access","title":"Enable SSH access","text":"

    Instead of accessing vSRX using a console connection or hypervisor virtual terminal, we can now use SSH through the management interface. Enable it with:

    1. set system services ssh
    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-host-name","title":"Set host name","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-domain-name","title":"Set domain name","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-dns-servers","title":"Set DNS servers","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-static-default-route-with-no-readvertise-option","title":"Set static default route with no-readvertise option","text":"

    You should be as specific about the route as possible. You can also use the no-readvertise option for the static route used for management traffic. This marks the route ineligible for readvertisement through routing policy.

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-time-zone","title":"Set time zone","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-ntp-servers","title":"Set NTP servers","text":"","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#set-rescue-configuration","title":"Set rescue configuration","text":"

    You can configure a single logical unit for the lo0 interface for each routing instance, and each logical unit associated with a given routing instance can have multiple configured IP addresses.

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#commit-changes","title":"Commit changes","text":"

    commit comment \"Initial configuration performed\"

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/initial-vyos-configuration-best-practices/#verification","title":"Verification","text":"
    • Using the Proxmox console, check the management network interface IP address with run show dhcp client binding fxp0.0.

      eron@vsrx-r1> show dhcp client binding fxp0.0 IP address Hardware address Expires State Interface 172.16.0.110 a2:2f:9d:45:aa:2a 263 BOUND fxp0.0

    • Using the IP address above, log into the router with the new non-root user via an SSH client with ssh <user_name>@<ip_address>.

      PS C:\\Users\\eronl> ssh eron@172.16.0.110 Password: Last login: Tue Jun 6 02:16:18 2023 from 172.16.0.53 --- JUNOS 20.3R1.8 Kernel 64-bit XEN JNPR-11.0-20200908.87c9d89_buil eron@vsrx-r1>

    ","tags":["VyOS"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/","title":"Installing VyOS on Proxmox","text":"","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#introduction","title":"Introduction","text":"

    To enable our subnets on Linux bridges to communicate within our labs across increasingly complex network topologies, we have to add Layer 3 and 4 capabilities to our setup. To do this, we're going incorporate VyOS into Proxmox and serve in this capacity.

    If you're not familiar with VyOS and why it's a fantastic platform to learn and use in your networks, check out this blog post where we cover what it is, its background and architecture, and its advantages for both practice labs and production networks.

    In this lab, we're going to cover the process to install a VyOS virtual machine (VM) in Proxmox and prepare it for use as a full-featured router/firewall/vpn in our networks.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#step-1-adding-vyos-as-an-image-in-proxmox","title":"Step 1: Adding VyOS as an Image in Proxmox","text":"

    To create a VM in Proxmox, you'll first need an \"image\" file of the software that will run as the operating system for your VM. This can come in different formats, but it often has a .iso file extension. Let's get the VyOS image we'll use for our router/firewall VMs.

    Go to https://vyos.io and look for the \"Download\" link in the main menu. Select \u201cFree Download\u201d from the dropdown menu, and look for the list item that says \u201cvyos-rolling-latest.iso.\u201d Instead of downloading it, however, just copy the link URL.

    Info

    A quick explanation on the VyOS release models, excerpted from the project's FAQs:

    VyOS is split into two branches: long term support and rolling release.

    • The rolling release branch (git branch \u201ccurrent\u201d) includes the latest code from maintainers and all contributions from community members are merged into it. It\u2019s meant for testing and home lab/non-critical router use and is not guaranteed to be stable.

    • Long term support branches are periodically split from the current branch. They are stable, and only proven, strictly compatible changes are merged or backported into it. Use this for production networks.

    For our home lab use, we will be using the rolling releases, and in a later video, we'll cover how to regularly update to the latest rolling release as new features become available.

    Go to the \u201clocal\u201d storage view of your Proxmox hypervisor and click on \"ISO Images\". Click on the \u201cDownload from URL\u201d button and paste the link URL we just copied into the \"URL\" field of the dialog box.

    Click the \u201cQuery URL\u201d button to verify the file exists and click the \u201cDownload\u201d button to save the latest VyOS rolling release ISO file locally on your hypervisor. Keep the file name the same.

    Whenever we need to create a new VyOS VM, we'll be able to easily use this local image already stored in Proxmox. Let's do that now.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#step-2-creating-and-configuring-a-vm-for-vyos","title":"Step 2: Creating and Configuring a VM for VyOS","text":"

    The next step is to create and configure the actual VM that VyOS will run within. For this we'll model the VM after a physical router device with five ports.

    On the top-right of the Proxmox UI, click the \u201cCreate VM\u201d button to set up a blank VM configuration. This will bring up a dialog box and walk you through the initial VM setup process:

    • On the \"General\" tab, name your VM vyos-r1 in the \"Name\" field, then click the \"Next\" button.

    • On the \"OS\" tab, select Use CD/DVD disc image file (iso) with \"Storage\" as local and \"ISO Image\" as vyos-rolling-latest.iso. Click the \"Next\" button.

    • On the \"System\" tab, select VirtIO SCSI single for \"SCSI Controller\" if available (use default otherwise) and check the \"Qemu Agent\". Click the \"Next\" button.

    • On the \"Disks\" tab, change \u201cDisk size (GiB)\u201d to 10, and leave the rest as the defaults. Click the \"Next\" button.

    • On the \"CPU\" tab, use 1 for the \"Sockets and Cores\" fields. Click the \"Next\" button.

    • On the \"Memory\" tab, use 1024 for the \u201cMemory (MiB)\u201d field. Click the \"Next\" button.

    • On the \"Network\" tab, ensure \u201cNo network device\u201d is unchecked, select vmbr0 for Bridge, uncheck \"Firewall\", select VirtIO (paravirtualized) for \"Model\", and use auto for \"MAC address\". Click the \"Next\" button.

    • On the \"Confirm\" tab, review all your settings and click the \"Finish\" button to close the dialog box. The VM is now created, but there's more configuration to complete.

    Select the vyos-r1 VM and open the \"Hardware\" configuration. A router isn\u2019t very useful with just one interface, so let\u2019s add four more. Within the hardware list, click the \"Add\" drop-down button and select \u201cNetwork Device.\u201d

    Using the same configuration as before on the \"Network\" tab above, create four additional network devices, so our router will have five total ports to work with.

    Well done; you've just modeled a real-world router as a VM!

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#step-3-installing-the-vyos-image-on-a-vm","title":"Step 3: Installing the VyOS Image on a VM","text":"

    Now we\u2019re ready to install VyOS onto our VM. Click the \u201cStart\u201d button to power on the VM and boot up the VyOS installer. When VyOS is finished booting, enter the username vyos and password vyos to log in.

    The VyOS installer is also a live demo instance of a running router, but we want to get it installed in our VM. At the command prompt, type install image to begin the installation.

    The installation script will begin prompting you to for each step of the process. The options will be in parenthesis and separated with a slash, such as (Yes/No), and the default choice will also appear in square brackets, such as [Yes]. To accept the default choice, simply press the \"Enter\" key, or type out another option then press \"Enter\". At the first question prompt, press \"Enter\" to continue.

    The next prompt asks how to partition the VM drive used to store VyOS. Press \"Enter\" to accept the \"Auto\" method.

    There will only be one drive available, so press \"Enter\" to select this drive to install VyOS on. You will again be prompted to confirm any existing data on the drive could be destroyed. This time, type Yes and press \"Enter\" to continue.

    Next you will be asked what size the root partition should be. Press \"Enter\" to accept the default size.

    The VyOS filesystem will be created on the disk, then you will be prompted on what to name this VyOS installation. Press \"Enter\" to accept the default name.

    Next, you will be prompted to select which configuration template to start with. Press \"Enter\" to accept the default configuration.

    The next two prompts will be to create and confirm the password for the initial administrator user, vyos. Select something secure and document it somewhere safe, as you\u2019ll need this to log into VyOS each time, then press \"Enter\" to continue.

    Finally, the last prompt will ask which drive should be modified for the boot partition. Press \"Enter\" to access the default drive.

    At this point, VyOS is now installed. Type reboot and confirm to proceed with rebooting the VM by typing y and pressing \"Enter\". When the VM reboots, you'll be ready to perform the initial configuration.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/networks/vyos/installing-vyos-on-proxmox/#conclusion-and-next-lab","title":"Conclusion and Next Lab","text":"

    In this lab we created a VM and installed an operating system on it. Well done!

    You probably noticed there were a lot more steps to do this compared to creating the CTs we used for our network hosts. We'll detail the differences in the server labs section later, but for now, this process is enough to get good at.

    We'll be creating many router VMs, so be sure to become comfortable with this process. Feel free to practice performing the process multiple times, deleting the VM after each installation.

    We've still got work to do on our router VM before we can use it in our network, so once you're ready to move on, head over to the Initial VyOS Configuration Best Practices lab.

    ","tags":["VyOS","Proxmox"]},{"location":"labs/servers/overview/","title":"Server Labs Overview","text":""},{"location":"quickrefs/overview/","title":"Quick References Overview","text":""},{"location":"quickrefs/routeros-basic-cli/","title":"RouterOS Basic CLI Commands","text":"

    Set the identity (hostname)

    system identity set name=\"My Router\"\n
    "},{"location":"quickrefs/routeros-basic-setup-checklist/","title":"RouterOS Basic Setup Checklist","text":""},{"location":"quickrefs/routeros-basic-setup-checklist/#clear-the-factory-default-configuration","title":"Clear the Factory Default Configuration","text":""},{"location":"quickrefs/routeros-basic-setup-checklist/#disable-the-default-user","title":"Disable the Default User","text":""},{"location":"quickrefs/routeros-basic-setup-checklist/#create-a-new-user","title":"Create a New User","text":"

    Set an IP Address Setup a Bridge for the LAN Subnet Setup DHCP for the LAN Subnet Setup NAT Source Masquerade Setup the Default Gateway

    "},{"location":"quickrefs/routeros-basic-setup-checklist/#_1","title":"RouterOS Basic Setup Checklist","text":""},{"location":"blog/archive/2023/","title":"2023","text":""},{"location":"blog/category/announcements/","title":"Announcements","text":""},{"location":"tags/","title":"Content Index","text":"

    Use this page to find content by tag. Note that content may be marked with multiple tags.

    "},{"location":"tags/#juniper","title":"Juniper","text":"
    • Initial Junos OS Configuration on a vSRX
    • Installing Juniper vSRX on Proxmox
    "},{"location":"tags/#linux","title":"Linux","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#mikrotik","title":"MikroTik","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#proxmox","title":"Proxmox","text":"
    • Cloning a Network Host Template in Proxmox
    • Connecting and Configuring Network Hosts in Proxmox
    • Creating a Network Host Template in Proxmox
    • Exploring Subnets and VLANs in Proxmox
    • Exploring Subnets, Broadcast Domains, and Bridges in Proxmox
    • Installing Juniper vSRX on Proxmox
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    • Installing VyOS on Proxmox
    "},{"location":"tags/#routeros","title":"RouterOS","text":"
    • Initial RouterOS Configuration Best Practices [DRAFT]
    • Installing MikroTik RouterOS on Proxmox
    • Static Routing Between Subnets with RouterOS [DRAFT]
    "},{"location":"tags/#vyos","title":"VyOS","text":"
    • Initial VyOS Configuration Best Practices
    • Installing VyOS on Proxmox
    "}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index cc3d7ce..6c4c76c 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,187 +2,222 @@ https://labs.telecomcraft.com/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/about/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/tags/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/blog/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/blog/the-telecom-craft-homelabs-site-has-launched/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/diagrams/notes/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/fiber/overview/ - 2023-08-27 + 2023-10-07 + daily + + + https://labs.telecomcraft.com/labs/fiber/patch-cords-and-connectors/ + 2023-10-07 + daily + + + https://labs.telecomcraft.com/labs/fiber/safety-tips/ + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/overview/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/apnic/routing-labs/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/apnic/mikrotik/overview/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/general/cloning-a-network-host-template-in-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/general/connecting-and-configuring-network-hosts-in-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/general/creating-a-network-host-template-in-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/general/exploring-subnets-and-vlans-in-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/general/exploring-subnets-broadcast-domains-and-bridges-in-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/general/initial-proxmox-network-configuration/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/juniper/initial-junos-os-configuration-best-practices/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/juniper/installing-vsrx-on-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/juniper/reinstalling-vsrx-trial-on-proxmox/ - 2023-08-27 + 2023-10-07 + daily + + + https://labs.telecomcraft.com/labs/networks/mikrotik/connected-routes/ + 2023-10-07 + daily + + + https://labs.telecomcraft.com/labs/networks/mikrotik/default-routes/ + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/mikrotik/initial-routeros-configuration-best-practices/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/mikrotik/installing-routeros-on-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/mikrotik/static-routing-between-subnets-with-routeros/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/vyos/initial-vyos-configuration-best-practices/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/vyos/installing-vyos-on-proxmox/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/vyos/upgrading-vyos/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/networks/vyos/vyos-rolling-vs-lts/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/security/overview/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/servers/overview/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/labs/servers/proxmox-8-overview/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/quickrefs/iproute2/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/quickrefs/junos-os/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/quickrefs/networkmanager/ - 2023-08-27 + 2023-10-07 + daily + + + https://labs.telecomcraft.com/quickrefs/overview/ + 2023-10-07 daily https://labs.telecomcraft.com/quickrefs/ping/ - 2023-08-27 + 2023-10-07 daily - https://labs.telecomcraft.com/quickrefs/tcpdump/ - 2023-08-27 + https://labs.telecomcraft.com/quickrefs/routeros-basic-cli/ + 2023-10-07 daily - https://labs.telecomcraft.com/tags/ - 2023-08-27 + https://labs.telecomcraft.com/quickrefs/routeros-basic-setup-checklist/ + 2023-10-07 + daily + + + https://labs.telecomcraft.com/quickrefs/tcpdump/ + 2023-10-07 daily https://labs.telecomcraft.com/blog/archive/2023/ - 2023-08-27 + 2023-10-07 daily https://labs.telecomcraft.com/blog/category/announcements/ - 2023-08-27 + 2023-10-07 + daily + + + https://labs.telecomcraft.com/tags/ + 2023-10-07 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 8b7a178..eab8919 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ diff --git a/tags/index.html b/tags/index.html index 83dda1d..2266d77 100644 --- a/tags/index.html +++ b/tags/index.html @@ -17,7 +17,7 @@ - + @@ -25,10 +25,10 @@ - + - + @@ -313,6 +313,24 @@ + + + + + + +
  • + + + + Quick Refs + + +
  • + + + + @@ -415,9 +433,13 @@ -
  • + + + + + +
  • - @@ -425,7 +447,8 @@ -
  • - +
  • - +
  • + + + + + +
  • - @@ -664,7 +695,8 @@ -
  • + + + + + + + Safety Tips + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + Patch Cords and Connectors + + + + + + + + +
  • + + + + @@ -733,9 +817,13 @@ -
  • + + + + + +
  • - @@ -743,7 +831,8 @@ -
  • - +
  • - +
  • - +
  • - + @@ -1245,13 +1342,39 @@
  • - + - Installing Juniper vSRX on Proxmox + Overview + + + + + + + + +
  • + + + + + + + + + +
  • + + + + + + + MikroTik @@ -1273,31 +1396,43 @@ - - + + + +
  • + + + + + -
  • + + + + + +
  • - - + -
  • + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + - -
  • - - - - - - - - - - - - + + +
  • - - + -
  • + + @@ -1689,10 +1877,10 @@

    VyOS

    + + + Back to top + @@ -1772,6 +1960,7 @@

    VyOS

    + - + - +