From 8adb8e3d7d9f747a3acb7b4febaaf7643fc72e02 Mon Sep 17 00:00:00 2001
From: squick i&&s.push(r(n,i,d));let{value:h}=c[u];s.push(t(n,{start:d,end:i=m,value:h}))}return i{let o=n.data;switch(o.type){case 1:na.value=!0;break;case 3:typeof o.data.pagination.prev<"u"?it.value=He(H({},it.value),{pagination:o.data.pagination,items:[...it.value.items,...o.data.items]}):(it.value=o.data,so(0));break}},qt(()=>{lr.value&&r.postMessage({type:0,data:lr.value})}),qt(()=>{na.value&&r.postMessage({type:2,data:Oe.value})})}var oa={container:"p",hidden:"v"};function ku(e){return z("div",{class:zt(oa.container,{[oa.hidden]:e.hidden}),onClick:()=>Dt()})}var ia={container:"r",disabled:"c"};function co(e){return z("button",{class:zt(ia.container,{[ia.disabled]:!e.onClick}),onClick:e.onClick,children:e.children})}var aa=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Au=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,r,n)=>n?n.toUpperCase():r.toLowerCase()),sa=e=>{let t=Au(e);return t.charAt(0).toUpperCase()+t.slice(1)},Cu=(...e)=>e.filter((t,r,n)=>!!t&&t.trim()!==""&&n.indexOf(t)===r).join(" ").trim(),Hu={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},$u=c=>{var l=c,{color:e="currentColor",size:t=24,strokeWidth:r=2,absoluteStrokeWidth:n,children:o,iconNode:i,class:a=""}=l,s=_r(l,["color","size","strokeWidth","absoluteStrokeWidth","children","iconNode","class"]);return Wt("svg",H(He(H({},Hu),{width:String(t),height:t,stroke:e,"stroke-width":n?Number(r)*24/Number(t):r,class:["lucide",a].join(" ")}),s),[...i.map(([u,p])=>Wt(u,p)),...Hr(o)])},go=(e,t)=>{let r=a=>{var s=a,{class:n="",children:o}=s,i=_r(s,["class","children"]);return Wt($u,He(H({},i),{iconNode:t,class:Cu(`lucide-${aa(sa(e))}`,`lucide-${aa(e)}`,n)}),o)};return r.displayName=sa(e),r},Pu=go("corner-down-left",[["path",{d:"M20 4v7a4 4 0 0 1-4 4H4",key:"6o5b7l"}],["path",{d:"m9 10-5 5 5 5",key:"1kshq7"}]]),Iu=go("list-filter",[["path",{d:"M2 5h20",key:"1fs1ex"}],["path",{d:"M6 12h12",key:"8npq4p"}],["path",{d:"M9 19h6",key:"456am0"}]]),Ru=go("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]),Gx=dl(hl(),1);function ju({threshold:e=0,root:t=null,rootMargin:r="0%",freezeOnceVisible:n=!1,initialIsIntersecting:o=!1,onChange:i}={}){var a;let[s,c]=no(null),[l,u]=no(()=>({isIntersecting:o,entry:void 0})),p=Vt();p.current=i;let d=((a=l.entry)==null?void 0:a.isIntersecting)&&n;St(()=>{if(!s||!("IntersectionObserver"in window)||d)return;let v,O=new IntersectionObserver(x=>{let w=Array.isArray(O.thresholds)?O.thresholds:[O.thresholds];x.forEach(_=>{let de=_.isIntersecting&&w.some(be=>_.intersectionRatio>=be);u({isIntersecting:de,entry:_}),p.current&&p.current(de,_),de&&n&&v&&(v(),v=void 0)})},{threshold:e,root:t,rootMargin:r});return O.observe(s),()=>{O.disconnect()}},[s,JSON.stringify(e),t,r,d,n]);let m=Vt(null);St(()=>{var v;!s&&(v=l.entry)!=null&&v.target&&!n&&!d&&m.current!==l.entry.target&&(m.current=l.entry.target,u({isIntersecting:o,entry:void 0}))},[s,l.entry,n,d,o]);let h=[c,!!l.isIntersecting,l.entry];return h.ref=h[0],h.isIntersecting=h[1],h.entry=h[2],h}var ut={container:"n",hidden:"l",content:"u",pop:"d",badge:"y",sidebar:"i",controls:"w",results:"k",loadmore:"z"};function Fu(e){let{isIntersecting:t,ref:r}=ju({threshold:0});St(()=>{t&&su()},[t]);let n=Vt(null);St(()=>{n.current&&typeof Oe.value.page>"u"&&n.current.scrollTo({top:0,behavior:"smooth"})},[Oe.value]);let o=za();return z("div",{class:zt(ut.container,{[ut.hidden]:e.hidden}),children:[z("div",{class:ut.content,children:[z("div",{class:ut.controls,children:[z(co,{onClick:Dt,children:z(Ru,{})}),z(Nu,{focus:!e.hidden}),z(co,{onClick:Wa,children:[z(Iu,{}),o.length>0&&z("span",{class:ut.badge,children:o.length})]})]}),z("div",{class:ut.results,ref:n,children:[z(Du,{keyboard:!e.hidden}),z("div",{class:ut.loadmore,ref:r})]})]}),z("div",{class:zt(ut.sidebar,{[ut.hidden]:mu()}),children:z(Uu,{})})]})}var Tt={container:"X",list:"j",heading:"F",title:"I",item:"o",active:"g",value:"R",count:"q"};function Uu(e){let t=fu();return t.sort((r,n)=>n.node.count-r.node.count),z("div",{class:Tt.container,children:[z("h3",{class:Tt.heading,children:"Filters"}),z("h4",{class:Tt.title,children:"Tags"}),z("ol",{class:Tt.list,children:t.map(r=>z("li",{class:zt(Tt.item,{[Tt.active]:cu(r.node.value)}),onClick:()=>lu(r.node.value),children:[z("span",{class:Tt.value,children:r.node.value}),z("span",{class:Tt.count,children:r.node.count})]}))})]})}var ca={container:"f"};function Nu(e){let t=Vt(null);return St(()=>{var r,n;e.focus?(r=t.current)==null||r.focus():(n=t.current)==null||n.blur()},[e.focus]),z("div",{class:ca.container,children:z("input",{ref:t,type:"text",class:ca.content,value:vn(bo()),onInput:r=>Va(yu(r.currentTarget.value)),autocapitalize:"off",autocomplete:"off",autocorrect:"off",placeholder:"Search",spellcheck:!1,role:"combobox"})})}var pt={container:"b",heading:"A",item:"a",active:"h",wrapper:"B",actions:"s",title:"x",path:"t"};function Du(e){var a;let t=au(),r=uu(),n=hn(),o=Vt([]);St(()=>{let s=o.current[n];s&&s.scrollIntoView({block:"center",behavior:"smooth"})},[n]),Aa(e.keyboard,s=>{let c=hn();s.key==="ArrowDown"?(s.preventDefault(),so(Math.min(c+1,r.length-1))):s.key==="ArrowUp"&&(s.preventDefault(),so(Math.max(c-1,0)))},[e.keyboard]);let i=(a=pu())!=null?a:0;return z(mt,{children:[r.length>0&&z("h3",{class:pt.heading,children:[z("span",{class:pt.bubble,children:new Intl.NumberFormat("en-US").format(i)})," ","results"]}),z("ol",{class:pt.container,children:r.map((s,c)=>{var d;let l=Ka(t[s.id].title,s.matches.find(({field:m})=>m==="title")),u=Mu((d=t[s.id].path)!=null?d:[],s.matches.find(({field:m})=>m==="path")),p=t[s.id].location;if(du()){let m=encodeURIComponent(bo()),[h,v]=p.split("#",2);p=`${h}?h=${m.replace(/%20/g,"+")}`,typeof v<"u"&&(p+=`#${v}`)}return z("li",{children:z("a",{ref:m=>{o.current[c]=m},href:p,onClick:()=>Dt(),class:zt(pt.item,{[pt.active]:c===hn()}),children:[z("div",{class:pt.wrapper,children:[z("h2",{class:pt.title,children:l}),z("menu",{class:pt.path,children:u.map(m=>z("li",{children:m}))})]}),z("nav",{class:pt.actions,children:z(co,{children:z(Pu,{})})})]})})})})]})}var Wu={container:"e"};function Vu(e){return Aa(!0,t=>{var r,n,o;if((t.metaKey||t.ctrlKey)&&t.key==="k")t.preventDefault(),Dt();else if((t.metaKey||t.ctrlKey)&&t.key==="j")document.body.classList.toggle("dark");else if(t.key==="Enter"&&!sr()){t.preventDefault(),Dt();let i=hn(),a=(n=(r=it.value)==null?void 0:r.items[i])==null?void 0:n.id;(o=lr.value)!=null&&o.items[a].location&&(window.location.href=lr.value.items[a].location)}else t.key==="Escape"&&!sr()&&(t.preventDefault(),Dt())},[]),z("div",{class:Wu.container,children:[z(ku,{hidden:sr()}),z(Fu,{hidden:sr()})]})}function Ya(e,t){iu(e),wl(z(Vu,{}),t)}function _o(){Dt()}function zu(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 qu(){return R(b(window,"compositionstart").pipe(f(()=>!0)),b(window,"compositionend").pipe(f(()=>!1))).pipe(J(!1))}function Ga(){let e=b(window,"keydown").pipe(f(t=>({mode:sr()?"global":"search",type:t.key,meta:t.ctrlKey||t.metaKey,claim(){t.preventDefault(),t.stopPropagation()}})),L(({mode:t,type:r})=>{if(t==="global"){let n=xt();if(typeof n!="undefined")return!zu(n,r)}return!0}),xe());return qu().pipe(g(t=>t?y:e))}function Ye(){return new URL(location.href)}function dt(e,t=!1){if(X("navigation.instant")&&!t){let r=A("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function Ja(){return new I}function Xa(){return location.hash.slice(1)}function Za(e){let t=A("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function yo(e){return R(b(window,"hashchange"),e).pipe(f(Xa),J(Xa()),L(t=>t.length>0),se(1))}function Qa(e){return yo(e).pipe(f(t=>Le(`[id="${t}"]`)),L(t=>typeof t!="undefined"))}function Rr(e){let t=matchMedia(e);return sn(r=>t.addListener(()=>r(t.matches))).pipe(J(t.matches))}function es(){let e=matchMedia("print");return R(b(window,"beforeprint").pipe(f(()=>!0)),b(window,"afterprint").pipe(f(()=>!1))).pipe(J(e.matches))}function xo(e,t){return e.pipe(g(r=>r?t():y))}function wo(e,t){return new U(r=>{let n=new XMLHttpRequest;return n.open("GET",`${e}`),n.responseType="blob",n.addEventListener("load",()=>{n.status>=200&&n.status<300?(r.next(n.response),r.complete()):r.error(new Error(n.statusText))}),n.addEventListener("error",()=>{r.error(new Error("Network error"))}),n.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(n.addEventListener("progress",o=>{var i;if(o.lengthComputable)t.progress$.next(o.loaded/o.total*100);else{let a=(i=n.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(o.loaded/+a*100)}}),t.progress$.next(5)),n.send(),()=>n.abort()})}function et(e,t){return wo(e,t).pipe(g(r=>r.text()),f(r=>JSON.parse(r)),se(1))}function wn(e,t){let r=new DOMParser;return wo(e,t).pipe(g(n=>n.text()),f(n=>r.parseFromString(n,"text/html")),se(1))}function ts(e,t){let r=new DOMParser;return wo(e,t).pipe(g(n=>n.text()),f(n=>r.parseFromString(n,"text/xml")),se(1))}var Eo={drawer:G("[data-md-toggle=drawer]"),search:G("[data-md-toggle=search]")};function To(e,t){Eo[e].checked!==t&&Eo[e].click()}function mr(e){let t=Eo[e];return b(t,"change").pipe(f(()=>t.checked),J(t.checked))}function rs(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function ns(){return R(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(f(rs),J(rs()))}function os(){return{width:innerWidth,height:innerHeight}}function is(){return b(window,"resize",{passive:!0}).pipe(f(os),J(os()))}function as(){return ee([ns(),is()]).pipe(f(([e,t])=>({offset:e,size:t})),se(1))}function En(e,{viewport$:t,header$:r}){let n=t.pipe(fe("size")),o=ee([n,r]).pipe(f(()=>wt(e)));return ee([r,t,o]).pipe(f(([{height:i},{offset:a,size:s},{x:c,y:l}])=>({offset:{x:a.x-c,y:a.y-l+i},size:s})))}var Ku=G("#__config"),dr=JSON.parse(Ku.textContent);dr.base=`${new URL(dr.base,Ye())}`;function Ue(){return dr}function X(e){return dr.features.includes(e)}function Bt(e,t){return typeof t!="undefined"?dr.translations[e].replace("#",t.toString()):dr.translations[e]}function ht(e,t=document){return G(`[data-md-component=${e}]`,t)}function Ee(e,t=document){return P(`[data-md-component=${e}]`,t)}function Bu(e){let t=G(".md-typeset > :first-child",e);return b(t,"click",{once:!0}).pipe(f(()=>G(".md-typeset",e)),f(r=>({hash:__md_hash(r.innerHTML)})))}function ss(e){if(!X("announce.dismiss")||!e.childElementCount)return y;if(!e.hidden){let t=G(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return j(()=>{let t=new I;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Bu(e).pipe($(r=>t.next(r)),V(()=>t.complete()),f(r=>H({ref:e},r)))})}function Yu(e,{target$:t}){return t.pipe(f(r=>({hidden:r!==e})))}function cs(e,t){let r=new I;return r.subscribe(({hidden:n})=>{e.hidden=n}),Yu(e,t).pipe($(n=>r.next(n)),V(()=>r.complete()),f(n=>H({ref:e},n)))}function Oo(e,t){return t==="inline"?A("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},A("div",{class:"md-tooltip__inner md-typeset"})):A("div",{class:"md-tooltip",id:e,role:"tooltip"},A("div",{class:"md-tooltip__inner md-typeset"}))}function Tn(...e){return A("div",{class:"md-tooltip2",role:"dialog"},A("div",{class:"md-tooltip2__inner md-typeset"},e))}function ls(...e){return A("div",{class:"md-tooltip2",role:"tooltip"},A("div",{class:"md-tooltip2__inner md-typeset"},e))}function us(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return A("aside",{class:"md-annotation",tabIndex:0},Oo(t),A("a",{href:r,class:"md-annotation__index",tabIndex:-1},A("span",{"data-md-annotation-id":e})))}else return A("aside",{class:"md-annotation",tabIndex:0},Oo(t),A("span",{class:"md-annotation__index",tabIndex:-1},A("span",{"data-md-annotation-id":e})))}function ps(e){return A("button",{class:"md-code__button",title:Bt("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function fs(){return A("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function ms(){return A("nav",{class:"md-code__nav"})}var Xu=yr(So());function hs(e){return A("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>A("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?Li(r):r)))}function Lo(e){let t=`tabbed-control tabbed-control--${e}`;return A("div",{class:t,hidden:!0},A("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function vs(e){return A("div",{class:"md-typeset__scrollwrap"},A("div",{class:"md-typeset__table"},e))}function Zu(e){var n;let t=Ue(),r=new URL(`../${e.version}/`,t.base);return A("li",{class:"md-version__item"},A("a",{href:`${r}`,class:"md-version__link"},e.title,((n=t.version)==null?void 0:n.alias)&&e.aliases.length>0&&A("span",{class:"md-version__alias"},e.aliases[0])))}function bs(e,t){var n;let r=Ue();return e=e.filter(o=>{var i;return!((i=o.properties)!=null&&i.hidden)}),A("div",{class:"md-version"},A("button",{class:"md-version__current","aria-label":Bt("select.version")},t.title,((n=r.version)==null?void 0:n.alias)&&t.aliases.length>0&&A("span",{class:"md-version__alias"},t.aliases[0])),A("ul",{class:"md-version__list"},e.map(Zu)))}var Qu=0;function ep(e,t=250){let r=ee([ir(e),Ft(e,t)]).pipe(f(([o,i])=>o||i),ie()),n=j(()=>Ai(e)).pipe(oe(Ut),Mr(1),Ze(r),f(()=>Ci(e)));return r.pipe(Sr(o=>o),g(()=>ee([r,n])),f(([o,i])=>({active:o,offset:i})),xe())}function jr(e,t,r=250){let{content$:n,viewport$:o}=t,i=`__tooltip2_${Qu++}`;return j(()=>{let a=new I,s=new Fn(!1);a.pipe(he(),ye(!1)).subscribe(s);let c=s.pipe(Or(u=>ze(+!u*250,Dn)),ie(),g(u=>u?n:y),$(u=>u.id=i),xe());ee([a.pipe(f(({active:u})=>u)),c.pipe(g(u=>Ft(u,250)),J(!1))]).pipe(f(u=>u.some(p=>p))).subscribe(s);let l=s.pipe(L(u=>u),le(c,o),f(([u,p,{size:d}])=>{let m=e.getBoundingClientRect(),h=m.width/2;if(p.role==="tooltip")return{x:h,y:8+m.height};if(m.y>=d.height/2){let{height:v}=Ae(p);return{x:h,y:-16-v}}else return{x:h,y:16+m.height}}));return ee([c,a,l]).subscribe(([u,{offset:p},d])=>{u.style.setProperty("--md-tooltip-host-x",`${p.x}px`),u.style.setProperty("--md-tooltip-host-y",`${p.y}px`),u.style.setProperty("--md-tooltip-x",`${d.x}px`),u.style.setProperty("--md-tooltip-y",`${d.y}px`),u.classList.toggle("md-tooltip2--top",d.y<0),u.classList.toggle("md-tooltip2--bottom",d.y>=0)}),s.pipe(L(u=>u),le(c,(u,p)=>p),L(u=>u.role==="tooltip")).subscribe(u=>{let p=Ae(G(":scope > *",u));u.style.setProperty("--md-tooltip-width",`${p.width}px`),u.style.setProperty("--md-tooltip-tail","0px")}),s.pipe(ie(),Ie(je),le(c)).subscribe(([u,p])=>{p.classList.toggle("md-tooltip2--active",u)}),ee([s.pipe(L(u=>u)),c]).subscribe(([u,p])=>{p.role==="dialog"?(e.setAttribute("aria-controls",i),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",i)}),s.pipe(L(u=>!u)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),ep(e,r).pipe($(u=>a.next(u)),V(()=>a.complete()),f(u=>H({ref:e},u)))})}function Ge(e,{viewport$:t},r=document.body){return jr(e,{content$:new U(n=>{let o=e.title,i=ls(o);return n.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",o)}}),viewport$:t},0)}function tp(e,t){let r=j(()=>ee([Hi(e),Ut(t)])).pipe(f(([{x:n,y:o},i])=>{let{width:a,height:s}=Ae(e);return{x:n-i.x+a/2,y:o-i.y+s/2}}));return ir(e).pipe(g(n=>r.pipe(f(o=>({active:n,offset:o})),Me(+!n||1/0))))}function gs(e,t,{target$:r}){let[n,o]=Array.from(e.children);return j(()=>{let i=new I,a=i.pipe(he(),ye(!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")}}),Et(e).pipe(Q(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),R(i.pipe(L(({active:s})=>s)),i.pipe(Be(250),L(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(n):n.remove()},complete(){e.prepend(n)}}),i.pipe(Xe(16,je)).subscribe(({active:s})=>{n.classList.toggle("md-tooltip--active",s)}),i.pipe(Mr(125,je),L(()=>!!e.offsetParent),f(()=>e.offsetParent.getBoundingClientRect()),f(({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")}}),b(o,"click").pipe(Q(a),L(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),b(o,"mousedown").pipe(Q(a),le(i)).subscribe(([s,{active:c}])=>{var l;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(c){s.preventDefault();let u=e.parentElement.closest(".md-annotation");u instanceof HTMLElement?u.focus():(l=xt())==null||l.blur()}}),r.pipe(Q(a),L(s=>s===n),lt(125)).subscribe(()=>e.focus()),tp(e,t).pipe($(s=>i.next(s)),V(()=>i.complete()),f(s=>H({ref:e},s)))})}function rp(e){let t=Ue();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(t.annotate){let n=e.closest("[class|=language]");if(n)for(let o of Array.from(n.classList)){if(!o.startsWith("language-"))continue;let[,i]=o.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return P(r.join(", "),e)}function np(e){let t=[];for(let r of rp(e)){let n=[],o=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=o.nextNode();i;i=o.nextNode())n.push(i);for(let i of n){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,c]=a;if(typeof c=="undefined"){let l=i.splitText(a.index);i=l.splitText(s.length),t.push(l)}else{i.textContent=s,t.push(i);break}}}}return t}function _s(e,t){t.append(...Array.from(e.childNodes))}function On(e,t,{target$:r,print$:n}){let o=t.closest("[id]"),i=o==null?void 0:o.id,a=new Map;for(let s of np(t)){let[,c]=s.textContent.match(/\((\d+)\)/);Le(`:scope > li:nth-child(${c})`,e)&&(a.set(c,us(c,i)),s.replaceWith(a.get(c)))}return a.size===0?y:j(()=>{let s=new I,c=s.pipe(he(),ye(!0)),l=[];for(let[u,p]of a)l.push([G(".md-typeset",p),G(`:scope > li:nth-child(${u})`,e)]);return n.pipe(Q(c)).subscribe(u=>{e.hidden=!u,e.classList.toggle("md-annotation-list",u);for(let[p,d]of l)u?_s(p,d):_s(d,p)}),R(...[...a].map(([,u])=>gs(u,t,{target$:r}))).pipe(V(()=>s.complete()),xe())})}function ys(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return ys(t)}}function xs(e,t){return j(()=>{let r=ys(e);return typeof r!="undefined"?On(r,e,t):y})}var Es=yr(ko());var op=0,ws=R(b(window,"keydown").pipe(f(()=>!0)),R(b(window,"keyup"),b(window,"contextmenu")).pipe(f(()=>!1))).pipe(J(!1),se(1));function Ts(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Ts(t)}}function ip(e){return Re(e).pipe(f(({width:t})=>({scrollable:kr(e).width>t})),fe("scrollable"))}function Os(e,t){let{matches:r}=matchMedia("(hover)"),n=j(()=>{let o=new I,i=o.pipe(Yn(1));o.subscribe(({scrollable:m})=>{m&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[],s=e.closest("pre"),c=s.closest("[id]"),l=c?c.id:op++;s.id=`__code_${l}`;let u=[],p=e.closest(".highlight");if(p instanceof HTMLElement){let m=Ts(p);if(typeof m!="undefined"&&(p.classList.contains("annotate")||X("content.code.annotate"))){let h=On(m,e,t);u.push(Re(p).pipe(Q(i),f(({width:v,height:O})=>v&&O),ie(),g(v=>v?h:y)))}}let d=P(":scope > span[id]",e);if(d.length&&(e.classList.add("md-code__content"),e.closest(".select")||X("content.code.select")&&!e.closest(".no-select"))){let m=+d[0].id.split("-").pop(),h=fs();a.push(h),X("content.tooltips")&&u.push(Ge(h,{viewport$}));let v=b(h,"click").pipe(Lr(M=>!M,!1),$(()=>h.blur()),xe());v.subscribe(M=>{h.classList.toggle("md-code__button--active",M)});let O=me(d).pipe(oe(M=>Ft(M).pipe(f(S=>[M,S]))));v.pipe(g(M=>M?O:y)).subscribe(([M,S])=>{let N=Le(".hll.select",M);if(N&&!S)N.replaceWith(...Array.from(N.childNodes));else if(!N&&S){let te=document.createElement("span");te.className="hll select",te.append(...Array.from(M.childNodes).slice(1)),M.append(te)}});let x=me(d).pipe(oe(M=>b(M,"mousedown").pipe($(S=>S.preventDefault()),f(()=>M)))),w=v.pipe(g(M=>M?x:y),le(ws),f(([M,S])=>{var te;let N=d.indexOf(M)+m;if(S===!1)return[N,N];{let ue=P(".hll",e).map(ce=>d.indexOf(ce.parentElement)+m);return(te=window.getSelection())==null||te.removeAllRanges(),[Math.min(N,...ue),Math.max(N,...ue)]}})),_=yo(y).pipe(L(M=>M.startsWith(`__codelineno-${l}-`)));_.subscribe(M=>{let[,,S]=M.split("-"),N=S.split(":").map(ue=>+ue-m+1);N.length===1&&N.push(N[0]);for(let ue of P(".hll:not(.select)",e))ue.replaceWith(...Array.from(ue.childNodes));let te=d.slice(N[0]-1,N[1]);for(let ue of te){let ce=document.createElement("span");ce.className="hll",ce.append(...Array.from(ue.childNodes).slice(1)),ue.append(ce)}}),_.pipe(Me(1),Ie(ge)).subscribe(M=>{if(M.includes(":")){let S=document.getElementById(M.split(":")[0]);S&&setTimeout(()=>{let N=S,te=-64;for(;N!==document.body;)te+=N.offsetTop,N=N.offsetParent;window.scrollTo({top:te})},1)}});let be=me(P('a[href^="#__codelineno"]',p)).pipe(oe(M=>b(M,"click").pipe($(S=>S.preventDefault()),f(()=>M)))).pipe(Q(i),le(ws),f(([M,S])=>{let te=+G(`[id="${M.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(S===!1)return[te,te];{let ue=P(".hll",e).map(ce=>+ce.parentElement.id.split("-").pop());return[Math.min(te,...ue),Math.max(te,...ue)]}}));R(w,be).subscribe(M=>{let S=`#__codelineno-${l}-`;M[0]===M[1]?S+=M[0]:S+=`${M[0]}:${M[1]}`,history.replaceState({},"",S),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+S,oldURL:window.location.href}))})}if(Es.default.isSupported()&&(e.closest(".copy")||X("content.code.copy")&&!e.closest(".no-copy"))){let m=ps(s.id);a.push(m),X("content.tooltips")&&u.push(Ge(m,{viewport$}))}if(a.length){let m=ms();m.append(...a),s.insertBefore(m,e)}return ip(e).pipe($(m=>o.next(m)),V(()=>o.complete()),f(m=>H({ref:e},m)),Rt(R(...u).pipe(Q(i))))});return X("content.lazy")?Et(e).pipe(L(o=>o),Me(1),g(()=>n)):n}function ap(e,{target$:t,print$:r}){let n=!0;return R(t.pipe(f(o=>o.closest("details:not([open])")),L(o=>e===o),f(()=>({action:"open",reveal:!0}))),r.pipe(L(o=>o||!n),$(()=>n=e.open),f(o=>({action:o?"open":"close"}))))}function Ss(e,t){return j(()=>{let r=new I;return r.subscribe(({action:n,reveal:o})=>{e.toggleAttribute("open",n==="open"),o&&e.scrollIntoView()}),ap(e,t).pipe($(n=>r.next(n)),V(()=>r.complete()),f(n=>H({ref:e},n)))})}var Ls=0,Ms=new Map;function sp(e){let t=document.createElement("h3");t.innerHTML=e.innerHTML;let r=[t],n=e.nextElementSibling;for(;n&&!(n instanceof HTMLHeadingElement);)r.push(n.cloneNode(!0)),n=n.nextElementSibling;return r}function cp(e,t){for(let r of P("[href], [src]",e))for(let n of["href","src"]){let o=r.getAttribute(n);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){r[n]=new URL(r.getAttribute(n),t).toString();break}}for(let r of P("[name^=__], [for]",e))for(let n of["id","for","name"]){let o=r.getAttribute(n);o&&r.setAttribute(n,`${o}$preview_${Ls}`)}return Ls++,K(e)}function lp(e){let t=Ms.get(e.toString());return t?K(t):wn(e).pipe(g(r=>cp(r,e)),f(r=>(Ms.set(e.toString(),r),r)))}function ks(e,t){let{sitemap$:r}=t;if(!(e instanceof HTMLAnchorElement))return y;if(!(X("navigation.instant.preview")||e.hasAttribute("data-preview")))return y;e.removeAttribute("title");let n=ee([ir(e),Ft(e).pipe(ke(1))]).pipe(f(([i,a])=>i||a),ie(),L(i=>i));return Pt([r,n]).pipe(g(([i])=>{let a=new URL(e.href);return a.search=a.hash="",i.has(`${a}`)?K(a):y}),g(i=>lp(i)),g(i=>{let a=e.hash?`article [id="${e.hash.slice(1)}"]`:"article h1",s=Le(a,i);return typeof s=="undefined"?y:K(sp(s))})).pipe(g(i=>{let a=new U(s=>{let c=Tn(...i);return s.next(c),document.body.append(c),()=>c.remove()});return jr(e,H({content$:a},t))}))}var As=".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}.flowchartTitleText{fill:var(--md-mermaid-label-fg-color)}.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 p,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel p{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.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}.classDiagramTitleText{fill:var(--md-mermaid-label-fg-color)}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 marker.marker.composition.class path,defs marker.marker.dependency.class path,defs marker.marker.extension.class path{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs marker.marker.aggregation.class path{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}.statediagramTitleText{fill:var(--md-mermaid-label-fg-color)}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,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.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)}[id^=entity] path,[id^=entity] rect{fill:var(--md-default-bg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs .marker.oneOrMore.er *,defs .marker.onlyOne.er *,defs .marker.zeroOrMore.er *,defs .marker.zeroOrOne.er *{stroke:var(--md-mermaid-edge-color)!important}text:not([class]):last-child{fill:var(--md-mermaid-label-fg-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 Ao,pp=0;function fp(){return typeof mermaid=="undefined"||mermaid instanceof Element?ar("https://unpkg.com/mermaid@11/dist/mermaid.min.js"):K(void 0)}function Cs(e){return e.classList.remove("mermaid"),Ao||(Ao=fp().pipe($(()=>mermaid.initialize({startOnLoad:!1,themeCSS:As,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),f(()=>{}),se(1))),Ao.subscribe(()=>Uo(null,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${pp++}`,r=A("div",{class:"mermaid"}),n=e.textContent,{svg:o,fn:i}=yield mermaid.render(t,n),a=r.attachShadow({mode:"closed"});a.innerHTML=o,e.replaceWith(r),i==null||i(a)})),Ao.pipe(f(()=>({ref:e})))}var Hs=A("table");function $s(e){return e.replaceWith(Hs),Hs.replaceWith(vs(e)),K({ref:e})}function mp(e){let t=e.find(r=>r.checked)||e[0];return R(...e.map(r=>b(r,"change").pipe(f(()=>G(`label[for="${r.id}"]`))))).pipe(J(G(`label[for="${t.id}"]`)),f(r=>({active:r})))}function Ps(e,{viewport$:t,target$:r}){let n=G(".tabbed-labels",e),o=P(":scope > input",e),i=Lo("prev");e.append(i);let a=Lo("next");return e.append(a),j(()=>{let s=new I,c=s.pipe(he(),ye(!0));ee([s,Re(e),Et(e)]).pipe(Q(c),Xe(1,je)).subscribe({next([{active:l},u]){let p=wt(l),{width:d}=Ae(l);e.style.setProperty("--md-indicator-x",`${p.x}px`),e.style.setProperty("--md-indicator-width",`${d}px`);let m=un(n);(p.x Depuis le début, beaucoup de commandes on été utilisées, du coup je note ici les commandes utilisées depuis le début et a quoi elles servent en gros sudo : lance une commande avec les superdroits, peut manipuler tout le pc avec en gros
+ ls : liste les fichiers d'un dossier
+ cd : changer de dossier
+ pwd : affiche le répertoire actuel
+ touch : affiche le contenu d'un fichier
+ nano : éditeur de texte
+ mkdir : supprime ce qu'on lui donne
+ rm : supprime ce qu'on lui donne
+ cp : copie...
+ mv : ...et déplace
+ exemple : liste tout un répertoire, mais n'affiche que les résultats qui sont "feur"
+ Pour envoyer un projet git, c'est comme envoyer un colis à la poste, d'abord, on met nos affaires dans le colis Plusieures possibilités ☝️ Ajoute TOUS les fichiers du dossier via l'option -A ou --all ->
+ Ajoute SEULEMENT les modifications et suppressions (donc pas de nouveaux fichiers) ->
+ Ensuite, on rempli l'étiquette du colis et on la colle au colis Enfin pour push, c'est a dire déposer le colis au bureau de poste pour l'envoi, on fait : Info -u veut dire ce que dit la doc en gros Dans le cas ou un fichier/dossier a été supprimé autre part avant de push nos modifs Dans le cas ou l'on veut travailler avec une seconde branche Pour switch de branche de travail ->
+ Pour merge en ecrasant la branche souhaitée ⬇️
+ Utile de créer donc un environnement pour chaque projet afin de en pas perturber d'autres projets avec des milliers de packages inutiles en gros pip est le packages manager de python, en l'appelant, on peut installer des packages comme uvicorn par exemple, utile pour grabber Pour en apprendre plus : le git du projet Le modèle MVC est une façon de concevoir un projet logiciel, en gros on sépare celui-ci en trois grandes parties distinctes séparant la logique de la vue et rend le travail plus facile. Modèle MVC en prenant celui de grabber par exemple : celle de grabber pour l'exemple Note Ici on crée une table dans laquelle on stockera des données (des PC que l'on grab par exemple) Note Pour ajouter une donnée dans une tableau, on INSERE dans le TABLEAU donné les VALEURS dans les Colonnes Note On recommence comme à l'étape 2, en ajoutant une clé étrangère foreign key, qui lie une clé extérieure, PcId ici, dans notre second Tableau -> cheatsheets (Notes sur les outils dev du quotidien) -> cours (Notes sur les cours) -> projects (Notes sur des nouveaux projets) -> liens cools (mes sites favoris) Warning Page en travaux, doit être finie avec toutes les informations que j'ai sur Linux en général Info Avant de manipuler des fichiers, il faut comprendre le fonctionnement des modules qui s'en occuperont, l'asynchrone. Asynchrone permet de ne pas bloquer le code même si il n'a pas de résultat mais avec promesse, il laisse le code continuer pour trouver une réponse et la rapporter comme promis. Rien de mieux qu'un exemple concret et gourmand en amont ! Résultat : La file d'attente sort du restaurant. Si la cuisson prend 10 minutes, tout le restaurant est bloqué pendant 10 minutes. Bien guez. ☝️🤓 Node.js fonctionne sur un principe de thread unique (monothread)... En gros, il ne peut effectuer qu'une seule tâche à la fois. Pour éviter de bloquer le programme pendant de longues opérations (comme lire des données au fin fond du disque dur), il délègue ces tâches a l'ordinateur et utilise un mécanisme de Promesses. Dans notre exemple, la Promise, c'est le bipeur. Ce boîtier est une promesse. Le restaurant te dit : "Je n'ai pas ton crousty tout de suite, mais je te promets que je te préviendrai dès qu'il y a du nouveau." Une Promise a toujours 3 états possibles, et seulement 3 : On peut également demander spécifiquement d'attendre le retour d'une promesse avec Pour manipuler des fichiers avec Node.JS, il existe un module appelé Node.JS fs, fs pour fiché S. Avec cette librairie on peut manipuler de plusieurs manière nos fichiers, les lire, écrire ou réécrire, demander les infos d'un fichier, copier et pleinnn de choses encore ! Ici on se concentrera sur les fonctions qu'on utilise dans le TP 2 de JS Avant tout, pour utiliser ce module, il faut l'appeler via une constante :
+ Pour lire des fichiers, on utilise la fonction Une fois que le système d'exploitation a fini de lire le fichier, il notifie le programme. La Promesse change d'état et déclenche l'une des deux fonctions suivantes : Le Succès ( L'Erreur ( Parfois, l'asynchronisme pur est difficile à gérer (besoin d'ordre précis). La syntaxe Le mot-clé Lorsqu'il s'agit d'écrire des données sur le disque, le choix de la méthode détermine comment le fichier est manipulé au niveau basique : Dans un contexte Ce script a pour but de récupérer automatiquement les informations matérielles (CPU, RAM, Stockage) et logicielles (OS, Kernel, Environnement de bureau) de la machine. Il formate ensuite ces données et les enregistre dans un fichier Note Pendant la création de cette note j'ai immigré mkdocs à Zensicle (maj de mkdocs en meilleur) et donc j'utilise une config qui réutilise les fichiers et la structure mkdocs. Pour héberger mon site de documentation en ligne, j'utilise Github via Github Actions qui est la solution parfaite pour un projet léger comme celui-ci. avant le 28/11 y'a rien a gratter, j'installais linux pour la 9387e fois -> cheatsheets (Notes sur les outils dev du quotidien) -> cours (Notes sur les cours) -> projects (Notes sur des nouveaux projets) -> liens cools (mes sites favoris) mon big ass qui fait sudo rm -rf / sans réfléchir Depuis le début, beaucoup de commandes on été utilisées, du coup je note ici les commandes utilisées depuis le début et a quoi elles servent en gros sudo : lance une commande avec les superdroits, peut manipuler tout le pc avec en gros ls : liste les fichiers d'un dossier
+*mon big ass qui fait sudo rm -rf / sans réfléchir*
+
+# Commandes *sh pour les idiots (28/11/25)
+
+## Cheatsheet de plein de commandes
+
+> Depuis le début, beaucoup de commandes on été utilisées, du coup je note ici les commandes utilisées depuis le début et a quoi elles servent en gros
+
+### Commandes de base
+
+1. **sudo** : lance une commande avec les superdroits, peut manipuler tout le pc avec en gros
+```bash
+sudo [commande]
+```
+
+2. **ls** : liste les fichiers d'un dossier
+```bash
+# -a pour afficher les fichiers cachés / -l pour afficher en liste avec plus d'infos
+ls [options] [fichier|dir]
+```
+
+3. **cd** : changer de dossier
+```bash
+# ~ pour aller au répertoire home / .. pour revenir en arriere
+cd [dir]
+```
+
+4. **pwd** : affiche le répertoire actuel
+```bash
+pwd
+```
+
+5. **touch** : affiche le contenu d'un fichier
+```bash
+touch [fichier]
+```
+
+6. **nano** : éditeur de texte
+```bash
+nano [fichier]
+```
+
+7. **mkdir** : supprime ce qu'on lui donne
+```bash
+mkdir [options] [fichier|dir]
+```
+
+8. **rm** : supprime ce qu'on lui donne
+```bash
+# -r pour supprimer un dossier et son contenu (recursive) (`rmdir` le fait aussi)
+# -f force la commande
+rm [options] [fichier|dir]
+```
+
+9. **cp** : copie...
+```bash
+cp [options] [source] [destination]
+```
+
+10. **mv** : ...et déplace
+```bash
+mv [options] [source] [destination]
+```
+
+### Les caractères d'associations
+
+`|` (le pipe) -> prend le résultat de la commande de gauche et le donne à celle de droite
+
+*exemple : liste tout un répertoire, mais n'affiche que les résultats qui sont "feur"*
+```bash
+ls -la | grep "feur"
+```
+
+`>` et `>>`
+
+- envoie le résultat d'une commande dans un fichier texte
+- `>` écrase le fichier / `>>` ajoute à la fin sans effacer
+- ex: `echo "coucou" > fichier.txt`
+
+### Permissions et Utilisateurs
+
+`chmod [droits] [fichier]`
+- change les permissions d'un fichier (qui peut lire/écrire/exécuter)
+- `chmod +x [fichier]` rend un script exécutable (très important)
+- `chmod 777 [fichier]` donne tous les droits à tout le monde (dangereux mais ça dépanne)
+
+`chown [user]:[groupe] [fichier]`
+- change le propriétaire du fichier (si t'as copié un truc en sudo et que tu peux plus le toucher)
+
+### Lecture et recherche dans les fichiers
+
+`cat [fichier]`
+- affiche tout le contenu d'un fichier d'un coup dans le terminal
+- utile pour les petits fichiers, sinon ça inonde l'écran
+
+`less [fichier]`
+- affiche le contenu page par page (on peut scroller)
+- appuyer sur `q` pour quitter
+
+`head [fichier]` / `tail [fichier]`
+- affiche juste le début (`head`) ou la fin (`tail`) d'un fichier
+- `tail -f [fichier]` hyper utile pour voir les logs en direct (ça attend les nouvelles lignes)
+
+`grep [mot] [fichier]`
+- cherche un mot ou une phrase spécifique dans un fichier (le ctrl+f du terminal)
+- -r pour chercher dans tous les dossiers (recursive) / -i pour ignorer les majuscules
\ No newline at end of file
diff --git a/docs/cheatsheets/2025-12-12.md b/docs/cheatsheets/2025-12-12.md
new file mode 100644
index 0000000..21f195e
--- /dev/null
+++ b/docs/cheatsheets/2025-12-12.md
@@ -0,0 +1,69 @@
+
+*completement zehef pcq t'as pas git push*
+
+# Git pour les neuilles (12/12/25)
+
+## Créer un git
+
+### -> Si le projet existe deja
+
+- On clone le projet au sein d'un dossier, celui-ci sera dans son dossier de travail. ->
+`git clone (url du projet git)`
+
+### -> Sinon créer le projet
+
+- Crée le projet git à partir de ce dossier. ->
+`git init (dossier de travail)`
+
+## Ignorer des fichiers/dossiers
+
+- Ajouter des interdictions dans .gitignore
+
+`echo gbvenv/ >> .gitignore` <- on indique via un echo qui écrira dans le fichier .gitignore qu'on ne veut pas push le dossier "gbvenv" ici, un fichier on ne mettera pas le slash (logique en amont)
+
+## Une fois que de fichiers sont dispos, empaqueter !
+> Pour envoyer un projet git, c'est comme envoyer un colis à la poste, d'abord, on met nos affaires dans le colis
+
+_Plusieures possibilités ☝️_
+
+- Ajoute TOUS les fichiers du dossier via l'option -A ou --all ->
+`git add -A`
+
+- Ajoute SEULEMENT les modifications et suppressions (donc pas de nouveaux fichiers) ->
+`git add -u`
+
+## Etiqueter le paquet
+> Ensuite, on rempli l'étiquette du colis et on la colle au colis
+
+- On écrit une note recap courte du commit sur le git ->
+`git commit -m "(message du commit)"`
+
+## Déposer le colis
+> Enfin pour push, c'est a dire déposer le colis au bureau de poste pour l'envoi, on fait :
+
+- On envoie le paquet de l'origine à la branche souhaitée dans le git ->
+`git push -u origin (branche souhaitée)`
+
+!!! info
+
+ -u veut dire [ce que dit la doc en gros](https://git-scm.com/docs/git-push/fr#git-push---set-upstream)
+
+### -> SI ERREUR
+> Dans le cas ou un fichier/dossier a été supprimé autre part avant de push nos modifs
+
+- Merge de force les deux branches pour ne faire qu'une branche
+`git config pull.rebase false`
+
+## Utiliser deux branches différentes
+> Dans le cas ou l'on veut travailler avec une seconde branche
+
+- Pour switch de branche de travail ->
+`git checkout (branche souhaitée)`
+
+- Pour merge en ecrasant la branche souhaitée ⬇️
+```bash
+git merge -s ours main
+git checkout main
+git merge (branche à merge)
+```
+
diff --git a/docs/cheatsheets/2026-01-16.md b/docs/cheatsheets/2026-01-16.md
new file mode 100644
index 0000000..83b3a3e
--- /dev/null
+++ b/docs/cheatsheets/2026-01-16.md
@@ -0,0 +1,34 @@
+
+*7alouf ouvre grabber apres 9h brainrot tsunami*
+
+# pip et environnements virtuels pour les caca (16/01/26)
+
+## Python et ses environnements virtuels
+
+- En python, on peut travailler dans des "sandboxes" ou toutes les libraires installées resteront contenues dedans
+
+> Utile de créer donc un environnement pour chaque projet afin de en pas perturber d'autres projets avec des milliers de packages inutiles en gros
+
+`python3 -m venv gbvenv` <- permet de créer un environnement (venv crée l'environnement "gbvenv")
+
+`source gbvenv/bin/activate` <- lance cet environnement pour travailler dedans
+
+- En parlant de packages, parlons de ✨pip✨
+
+> pip est le packages manager de python, en l'appelant, on peut installer des packages comme uvicorn par exemple, utile pour grabber
+
+`pip install --upgrade pip` <- update les packages
+
+`python -m pip install ***` <- installe le package qu'on notera a la place des ***
+
+`pip freeze >> requirements.txt` <- commande super utile pour partager les dependances necessaires pour faire fonctionner son projet sur un autre environnement
+
+`deactivate` <- désactive l'environnement virtuel
+
+## Script de roi qui automatise le process
+
+- J'ai codé un script qui automatise ce process avec une seule commande :
+
+`bash <(curl -fsSL https://raw.githubusercontent.com/buchtioof/venv-setup/main/venvsetup.sh)`
+
+> Pour en apprendre plus : [le git du projet](https://github.com/buchtioof/venv-setup)
\ No newline at end of file
diff --git a/docs/cheatsheets/2026-01-22.md b/docs/cheatsheets/2026-01-22.md
new file mode 100644
index 0000000..aebc8b9
--- /dev/null
+++ b/docs/cheatsheets/2026-01-22.md
@@ -0,0 +1,72 @@
+
+*florian quand je lui demande de l'aide*
+
+# SQL pour les tung tung tung sahur (22/01/26)
+
+## Modèle MVC
+> Le modèle MVC est une façon de concevoir un projet logiciel, en gros on sépare celui-ci en trois grandes parties distinctes séparant la logique de la vue et rend le travail plus facile.
+
+
+
+Modèle MVC en prenant celui de grabber par exemple :
+
+ - Model = Base De Donnée (ex: EMPLOYEES, COMPUTERS)
+ - View = Tableau de bord, Site
+ - Controller = Cerveau qui dirige les deux parties Model et View (ex: app.py)
+
+## TUTO : COMMENT CR2ER UNE BDD SQL FACILEMENT EN 2 MINUTES (SUPER FACILE)
+
+### Structure d'une Base De Données
+*celle de grabber pour l'exemple*
+
+```
+BDD (Etape 1) - grabberman
+├── TABLES (Etape 2) - COMPUTERS
+│ ├── Colonne (Etape 3) - PcId, entier/clé primaire
+│ │ └── Donnée (Etape 4)
+│ ├── Colonne (Etape 3) - Hostname, chaîne de charactère
+│ └── Colonne (Etape 3) - MacAddress, chaîne de charactère
+└── TABLES (Etape 2) - EMPLOYEES
+ ├── Colonne (Etape 3) - UserId, entier/clé primaire
+ ├── Colonne (Etape 3) - Username, chaîne de charactère
+ └── Colonne (Etape 3) - PcId, clé secondaire
+```
+### Etape 1 : Créer une BDD
+
+`sqlite3 grabberman.db` <- Commande qui crée une DB qu'on appellera ici "grabberman"
+
+### Etape 2 : Créer une table
+
+```sql
+CREATE TABLE "COMPUTERS"
+(
+ PcId INTEGER PRIMARY KEY AUTOINCREMENT,
+ Hostname VARCHAR(50) NOT NULL,
+ MacAddress VARCHAR(50)
+);
+```
+!!! note
+
+ Ici on crée une table dans laquelle on stockera des données (des PC que l'on grab par exemple)
+
+### Etape 3 : Ajouter des données dans une table
+
+`INSERT into COMPUTERS (Hostname, MacAddress) VALUES ('mypc', '1B:12:F0:FL:94');`
+!!! note
+
+ Pour ajouter une donnée dans une tableau, on **INSERE** dans le **TABLEAU** donné les **VALEURS** dans les **Colonnes**
+
+### Etape 4 : Créer un autre tableau avec une clé liée (foreign key)
+
+```sql
+CREATE TABLE "EMPLOYEES"
+(
+ UserId INTEGER PRIMARY KEY AUTOINCREMENT,
+ Username VARCHAR(50) NOT NULL,
+ FOREIGN KEY (PcId) REFERENCES COMPUTERS(PcId)
+);
+```
+
+!!! note
+
+ On recommence comme à l'étape 2, en ajoutant une clé étrangère **foreign key**, qui lie une clé extérieure, **PcId** ici, dans notre second Tableau
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..73bebda
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,14 @@
+
+*avant le 28/11 y'a rien a gratter, j'installais linux pour la 9387e fois*
+
+# Bienvenue dans les notes de ramzouille
+
+## Structure
+
+-> cheatsheets (Notes sur les outils dev du quotidien)
+
+-> cours (Notes sur les cours)
+
+-> projects (Notes sur des nouveaux projets)
+
+-> liens cools (mes sites favoris)
\ No newline at end of file
diff --git a/docs/learn/2025-10-30.md b/docs/learn/2025-10-30.md
new file mode 100644
index 0000000..8dd2cf3
--- /dev/null
+++ b/docs/learn/2025-10-30.md
@@ -0,0 +1,31 @@
+
+
+# C koi linux ? (30/10/25)
+
+!!! warning
+
+ Page en travaux, doit être finie avec toutes les informations que j'ai sur Linux en général
+
+## Arborescence type sur UNIX
+
+- On découvre l'arborescence des fichiers sur un Linux
+
+```
+/ # Racine du disque
+├── /bin/ # Contient les commandes de base
+├── /boot/ # Fichiers de demarrage
+├── /dev/ # Tout ce qui est lié aux périphériques
+├── /etc/ # Fichiers de configuration
+├── /home/ # Répertoires utilisateurs
+├── /lib/ # Bibliothèques logicielles
+├── /mnt/ # Point de montage pour les systèmes de fichier temporaires
+├── /media/ # Point de montage pour les disques temporaires
+├── /opt/ # Logiciels optionnels, la ou on installera des programmes maison
+├── /root/ # Répertoire du user root
+├── /var/ # Variable, contient des logs, ect...
+├── /usr/ # Contient sensiblement la même chose que la racine mais sans être utile au fonctionnement du système
+├── /srv/ # Services hébergés sur le systèmes (FTP, HTTP, ect...)
+├── /run/ # Emplacement mémoire des programmes
+└── /tmp/ # Temporaire
+```
+[source de l'arbo.](https://fr.wikipedia.org/wiki/Filesystem_Hierarchy_Standard#Arborescence_des_r%C3%A9pertoires)
\ No newline at end of file
diff --git a/docs/learn/javascript.md b/docs/learn/javascript.md
new file mode 100644
index 0000000..6688dc3
--- /dev/null
+++ b/docs/learn/javascript.md
@@ -0,0 +1,6 @@
+# Javascript en gros
+
+## Sommaire
+
+- [Cours 1 : ](javascript/2026-01-30.md)
+- [Cours 2 : Asynchrone et Manip de fichiers](javascript/2026-02-06.md)
\ No newline at end of file
diff --git a/docs/learn/javascript/2026-01-30.md b/docs/learn/javascript/2026-01-30.md
new file mode 100644
index 0000000..041dca2
--- /dev/null
+++ b/docs/learn/javascript/2026-01-30.md
@@ -0,0 +1 @@
+# Javascript en gros pt.1 (30/01/26)
\ No newline at end of file
diff --git a/docs/learn/javascript/2026-02-06.md b/docs/learn/javascript/2026-02-06.md
new file mode 100644
index 0000000..e43b713
--- /dev/null
+++ b/docs/learn/javascript/2026-02-06.md
@@ -0,0 +1,79 @@
+
+
+# JS en gros pt.2 : Asynchrone et promesses, Manip de fichiers (06/02/26)
+
+!!! info
+ Avant de manipuler des fichiers, il faut comprendre le fonctionnement des modules qui s'en occuperont, **l'asynchrone**.
+
+## Asynchrone et promesses (promise)
+
+### C'est quoi Asynchrone ?
+
+Asynchrone permet de ne pas bloquer le code même si il n'a pas de résultat mais avec promesse, il laisse le code continuer pour trouver une réponse et la rapporter comme promis.
+
+*Rien de mieux qu'un exemple concret et gourmand en amont !*
+
+#### 1. SANS Asynchrone
+
+1. Tu commandes un Tasty Crousty.
+2. Ce neuille de caissier part en cuisine.
+3. Il fait cuire le riz lui-même.
+4. Il coupe les tenders.
+5. Il met tout dans la barquette puis sauce.
+6. Et revient pour te donner le Tasty Crousty 67 doro party.
+7. **SEULEMENT MAINTENANT**, il prend la commande du gwer suivant.
+
+**Résultat :** La file d'attente sort du restaurant. Si la cuisson prend 10 minutes, tout le restaurant est bloqué pendant 10 minutes. Bien guez.
+
+---
+
+#### 2. AVEC Asynchrone
+
+1. Tu commandes un Tasty Crouspy.
+2. La caissière crie en cuisine "Un Crousty piquant sucré supplément poulet !".
+3. Elle te donne un bipeur, faisant donc **la promesse** de te servir un délicieux Crouspy Tasty.
+4. Puis elle passe **directement** au client suivant.
+5. Toi, tu vas t'asseoir et tu attends.
+
+### Mais c'est quoi cette promesse ? (Promise)
+
+☝️🤓 Node.js fonctionne sur un principe de **thread unique** (monothread)... En gros, il ne peut effectuer qu'une seule tâche à la fois.
+
+> Pour éviter de bloquer le programme pendant de longues opérations (comme lire des données au fin fond du disque dur), il délègue ces tâches a l'ordinateur et utilise un mécanisme de **Promesses**.
+
+Dans notre exemple, **la Promise, c'est le bipeur.**
+
+Ce boîtier est une promesse. Le restaurant te dit : *"Je n'ai pas ton crousty tout de suite, mais je te promets que je te préviendrai dès qu'il y a du nouveau."*
+
+Une Promise a toujours **3 états possibles**, et seulement 3 :
+
+1. **En attente (Pending) :** Le boîtier ne fait rien. Le cuisinier travaille. Tu attends.
+2. **Succès (Resolved) :** Le boîtier vibre ! La promesse est tenue, tu as ton chicken (la donnée est arrivée).
+3. **Échec (Rejected) :** Le manager arrive et te dit *"Désolé, la cuisine a pris feu, pas de délicieux crousty pour ce soir"*. La promesse est rompue (il y a une erreur).
+
+### Exemples async et await
+
+#### Exemple d'un async (exo du TP 2 de JS)
+
+```javascript
+files.forEach((fileName) => {
+ fs.readFile(fileName, 'utf8').then((content) => {
+ ...
+ })
+});
+```
+
+* **`fs.readFile`** : Envoie le job de lire un fichier à l'ordinateur avec des parametres et quand c'est pret, enrengistre son résultat dans `content`.
+* **La Promise** : En lançant fs.readFile, celui-ci promet que dès qu'il a un résultat, il le renverra dans `content`
+
+#### Exemple concret await (exo du TP 2 de JS)
+
+On peut également demander spécifiquement d'attendre le retour d'une promesse avec `await`
+
+```javascript
+const stats = await fs.stat(filename);
+```
+
+* **`fs.stat`** : Envoie le job de récupérer les stats d'un fichier à l'ordinateur et quand c'est pret, enrengistre son résultat dans `stats`.
+* **La Promise** : On te promet un résultat dans `stats`
+* `**await**` : Tant que l'on a pas de résultat, on "fige" à cette ligne jusqu'à ce que la promesse est reçue.
\ No newline at end of file
diff --git a/docs/links.md b/docs/links.md
new file mode 100644
index 0000000..2e2fd37
--- /dev/null
+++ b/docs/links.md
@@ -0,0 +1,10 @@
+
+
+
+
+# Liens cools de ma poche
+
+## 🎨 Design
+
+
+## 💽 Developpement
\ No newline at end of file
diff --git a/docs/projects/2025-12-05.md b/docs/projects/2025-12-05.md
new file mode 100644
index 0000000..274abe3
--- /dev/null
+++ b/docs/projects/2025-12-05.md
@@ -0,0 +1,51 @@
+# Grabber pt.1 (05/12/25)
+Ce script a pour but de récupérer automatiquement les informations matérielles (CPU, RAM, Stockage) et logicielles (OS, Kernel, Environnement de bureau) de la machine. Il formate ensuite ces données et les enregistre dans un fichier `summary.txt` situé dans le dossier `/opt/grabber`.
+
+## Commandes et explications
+
+### 1. Variables et chemins
+
+`DIR=/opt/grabber`
+- Définit le répertoire de travail principal pour le script.
+
+`SUM="$DIR/summary.txt"`
+- Définit le chemin absolu du fichier de sortie où les informations seront écrites.
+
+### 2. Récupération Hardware (Matériel)
+
+`lscpu -eMODELNAME | tail -n1`
+- Affiche les détails du CPU et isole la dernière ligne pour obtenir uniquement le nom du modèle.
+
+`sudo dmidecode -t processor | grep ID`
+- Utilise l'outil `dmidecode` (nécessite les privilèges root) pour extraire l'identifiant unique du processeur.
+
+`lsmem | grep 'Mémoire partagée'`
+- Récupère la taille de la mémoire vive (RAM) disponible sur le système.
+
+`lsblk -dnb`
+- Liste les périphériques de blocs (disques) sans afficher les partitions, en excluant les boucles (`loop`) et le boot, pour calculer le stockage total.
+
+`numfmt --to iec $STOCKAGE_TOTAL`
+- Convertit la taille totale du stockage (calculée en octets) vers un format lisible par l'humain (ex: 500G, 1T).
+
+### 3. Récupération Software (Logiciel)
+
+`lsb_release -a`
+- Affiche les informations spécifiques à la distribution Linux installée (Description, Release).
+
+`uname -a`
+- Récupère l'architecture du système (ex: x86_64).
+
+`uname -r`
+- Affiche la version actuelle du noyau (Kernel) Linux.
+
+### 4. Fonctions d'écriture (Logique)
+
+`echo "[HARDWARE]" > $SUM`
+- Initialise le fichier de résumé en écrivant l'en-tête. Le signe `>` écrase tout contenu précédent pour repartir à zéro.
+
+`echo "VAR = $VAR" >> $SUM`
+- Ajoute les lignes d'informations (CPU, RAM, OS, etc.) à la suite du fichier. Le signe `>>` permet d'ajouter du texte sans effacer ce qui existe déjà.
+
+`hardware` et `software`
+- Appelle les deux fonctions définies précédemment pour exécuter la collecte et l'écriture des données.
\ No newline at end of file
diff --git a/docs/projects/2026-01-23.md b/docs/projects/2026-01-23.md
new file mode 100644
index 0000000..978b49b
--- /dev/null
+++ b/docs/projects/2026-01-23.md
@@ -0,0 +1,28 @@
+
+*celui qui pete fort dans la classe jv te grabber*
+
+# Site de notes avec Zensical (23/01/26)
+
+!!! note
+
+ Pendant la création de cette note j'ai immigré mkdocs à Zensicle (maj de mkdocs en meilleur) et donc j'utilise une config qui réutilise les fichiers et la structure mkdocs.
+
+## Pourquoi faire ?
+
+- Tester de créer un nouvel environnement en python
+- Travailler avec des modules pip pour améliorer le projet
+- Changer un peu de grabber
+
+## Comment Zensicle marche
+
+- mkdocs.yml est la navbar du site
+- dossier docs est la racine du site mkdocs
+
+## Hébergement via Github (Github Actions)
+
+> Pour héberger mon site de documentation en ligne, j'utilise Github via Github Actions qui est la solution parfaite pour un projet léger comme celui-ci.
+
+[Docs pour host sur Github](https://zensical.org/docs/publish-your-site/)
+
+
+
diff --git a/docs/stylesheets/index.css b/docs/stylesheets/index.css
new file mode 100644
index 0000000..d5db0ac
--- /dev/null
+++ b/docs/stylesheets/index.css
@@ -0,0 +1,13 @@
+@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap');
+
+.md-typeset h1 {
+ font-family: "Instrument Serif";
+ font-style: italic;
+ font-weight: 800;
+ font-size: 42px;
+}
+
+img {
+ width: 100%;
+ border-radius: 12px;
+}
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..bee9d50
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,74 @@
+site_name: Les incroyables notes de ramzouille
+repo_name: buchtioof/notes
+repo_url: https://github.com/buchtioof/notes
+
+theme:
+ palette:
+ # Palette toggle for automatic mode
+ - media: "(prefers-color-scheme)"
+ toggle:
+ icon: lucide/sun-moon
+ name: Switch to light mode
+
+ # Palette toggle for light mode
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ primary: pink
+ accent: deep purple
+ toggle:
+ icon: lucide/sun
+ name: Switch to dark mode
+
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ primary: pink
+ accent: purple
+ toggle:
+ icon: lucide/moon
+ name: Switch to light mode
+ icon:
+ repo: fontawesome/brands/git-alt
+ admonition:
+ note: fontawesome/solid/note-sticky
+ abstract: fontawesome/solid/book
+ info: fontawesome/solid/circle-info
+ tip: fontawesome/solid/bullhorn
+ success: fontawesome/solid/check
+ question: fontawesome/solid/circle-question
+ warning: fontawesome/solid/triangle-exclamation
+ failure: fontawesome/solid/bomb
+ danger: fontawesome/solid/skull
+ bug: fontawesome/solid/robot
+ example: fontawesome/solid/flask
+ quote: fontawesome/solid/quote-left
+
+extra_css:
+ - stylesheets/index.css
+
+nav:
+ - Accueil: index.md
+ - Cheatsheets:
+ - cheatsheets/2025-11-28.md
+ - cheatsheets/2025-12-12.md
+ - cheatsheets/2026-01-16.md
+ - cheatsheets/2026-01-22.md
+ - Cours:
+ - learn/2025-10-30.md
+ - learn/javascript.md
+ - Projets:
+ - projects/2025-12-05.md
+ - projects/2026-01-23.md
+ - Liens cools: links.md
+
+
+markdown_extensions:
+ - tables
+ - admonition
+ - pymdownx.details
+ - pymdownx.superfences
+ - attr_list
+ - pymdownx.emoji:
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
+
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..5ece7c1
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,7 @@
+click==8.3.1
+deepmerge==2.0
+Markdown==3.10.1
+Pygments==2.19.2
+pymdown-extensions==10.20.1
+PyYAML==6.0.3
+zensical==0.0.21
diff --git a/site/404.html b/site/404.html
new file mode 100644
index 0000000..c17fea9
--- /dev/null
+++ b/site/404.html
@@ -0,0 +1,814 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 404 - Not found
+
+ =t.count.fields)return{documents:r,terms:l};let o=t.shards[n];return e.forEach(a=>{let{occurrences:s}=o.terms[a];for(let u=0;u
+mon big ass qui fait sudo rm -rf / sans réfléchirCommandes *sh pour les idiots (28/11/25)
+Cheatsheet de plein de commandes
+
+
+Commandes de base
+
+
+sudo [commande]
+# -a pour afficher les fichiers cachés / -l pour afficher en liste avec plus d'infos
+ls [options] [fichier|dir]
+# ~ pour aller au répertoire home / .. pour revenir en arriere
+cd [dir]
+pwd
+touch [fichier]
+nano [fichier]
+mkdir [options] [fichier|dir]
+# -r pour supprimer un dossier et son contenu (recursive) (`rmdir` le fait aussi)
+# -f force la commande
+rm [options] [fichier|dir]
+cp [options] [source] [destination]
+mv [options] [source] [destination]
+Les caractères d'associations
+| (le pipe) -> prend le résultat de la commande de gauche et le donne à celle de droitels -la | grep "feur"
+> et >>
+
+> écrase le fichier / >> ajoute à la fin sans effacerecho "coucou" > fichier.txtPermissions et Utilisateurs
+chmod [droits] [fichier]
+- change les permissions d'un fichier (qui peut lire/écrire/exécuter)
+- chmod +x [fichier] rend un script exécutable (très important)
+- chmod 777 [fichier] donne tous les droits à tout le monde (dangereux mais ça dépanne)chown [user]:[groupe] [fichier]
+- change le propriétaire du fichier (si t'as copié un truc en sudo et que tu peux plus le toucher)Lecture et recherche dans les fichiers
+cat [fichier]
+- affiche tout le contenu d'un fichier d'un coup dans le terminal
+- utile pour les petits fichiers, sinon ça inonde l'écranless [fichier]
+- affiche le contenu page par page (on peut scroller)
+- appuyer sur q pour quitterhead [fichier] / tail [fichier]
+- affiche juste le début (head) ou la fin (tail) d'un fichier
+- tail -f [fichier] hyper utile pour voir les logs en direct (ça attend les nouvelles lignes)grep [mot] [fichier]
+- cherche un mot ou une phrase spécifique dans un fichier (le ctrl+f du terminal)
+- -r pour chercher dans tous les dossiers (recursive) / -i pour ignorer les majuscules
+completement zehef pcq t'as pas git pushGit pour les neuilles (12/12/25)
+Créer un git
+-> Si le projet existe deja
+
+
+git clone (url du projet git)-> Sinon créer le projet
+
+
+git init (dossier de travail)Ignorer des fichiers/dossiers
+
+
+echo gbvenv/ >> .gitignore <- on indique via un echo qui écrira dans le fichier .gitignore qu'on ne veut pas push le dossier "gbvenv" ici, un fichier on ne mettera pas le slash (logique en amont)Une fois que de fichiers sont dispos, empaqueter !
+
+
+
+
+git add -Agit add -uEtiqueter le paquet
+
+
+
+
+git commit -m "(message du commit)"Déposer le colis
+
+
+
+
+git push -u origin (branche souhaitée)-> SI ERREUR
+
+
+
+
+git config pull.rebase falseUtiliser deux branches différentes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ git checkout (branche souhaitée)git merge -s ours main
+git checkout main
+git merge (branche à merge)
+
+7alouf ouvre grabber apres 9h brainrot tsunamipip et environnements virtuels pour les caca (16/01/26)
+Python et ses environnements virtuels
+
+
+
+
+python3 -m venv gbvenv <- permet de créer un environnement (venv crée l'environnement "gbvenv")source gbvenv/bin/activate <- lance cet environnement pour travailler dedans
+
+
+
+pip install --upgrade pip <- update les packagespython -m pip install *** <- installe le package qu'on notera a la place des ***pip freeze >> requirements.txt <- commande super utile pour partager les dependances necessaires pour faire fonctionner son projet sur un autre environnementdeactivate <- désactive l'environnement virtuelScript de roi qui automatise le process
+
+
+bash <(curl -fsSL https://raw.githubusercontent.com/buchtioof/venv-setup/main/venvsetup.sh)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+florian quand je lui demande de l'aideSQL pour les tung tung tung sahur (22/01/26)
+Modèle MVC
+
+
+
+- Model = Base De Donnée (ex: EMPLOYEES, COMPUTERS)
+- View = Tableau de bord, Site
+- Controller = Cerveau qui dirige les deux parties Model et View (ex: app.py)
+TUTO : COMMENT CR2ER UNE BDD SQL FACILEMENT EN 2 MINUTES (SUPER FACILE)
+Structure d'une Base De Données
+BDD (Etape 1) - grabberman
+├── TABLES (Etape 2) - COMPUTERS
+│ ├── Colonne (Etape 3) - PcId, entier/clé primaire
+│ │ └── Donnée (Etape 4)
+│ ├── Colonne (Etape 3) - Hostname, chaîne de charactère
+│ └── Colonne (Etape 3) - MacAddress, chaîne de charactère
+└── TABLES (Etape 2) - EMPLOYEES
+ ├── Colonne (Etape 3) - UserId, entier/clé primaire
+ ├── Colonne (Etape 3) - Username, chaîne de charactère
+ └── Colonne (Etape 3) - PcId, clé secondaire
+Etape 1 : Créer une BDD
+sqlite3 grabberman.db <- Commande qui crée une DB qu'on appellera ici "grabberman"Etape 2 : Créer une table
+CREATE TABLE "COMPUTERS"
+(
+ PcId INTEGER PRIMARY KEY AUTOINCREMENT,
+ Hostname VARCHAR(50) NOT NULL,
+ MacAddress VARCHAR(50)
+);
+Etape 3 : Ajouter des données dans une table
+INSERT into COMPUTERS (Hostname, MacAddress) VALUES ('mypc', '1B:12:F0:FL:94');Etape 4 : Créer un autre tableau avec une clé liée (foreign key)
+CREATE TABLE "EMPLOYEES"
+(
+ UserId INTEGER PRIMARY KEY AUTOINCREMENT,
+ Username VARCHAR(50) NOT NULL,
+ FOREIGN KEY (PcId) REFERENCES COMPUTERS(PcId)
+);
+
+avant le 28/11 y'a rien a gratter, j'installais linux pour la 9387e foisBienvenue dans les notes de ramzouille
+Structure
+
C koi linux ? (30/10/25)
+Arborescence type sur UNIX
+
+
+/ # Racine du disque
+├── /bin/ # Contient les commandes de base
+├── /boot/ # Fichiers de demarrage
+├── /dev/ # Tout ce qui est lié aux périphériques
+├── /etc/ # Fichiers de configuration
+├── /home/ # Répertoires utilisateurs
+├── /lib/ # Bibliothèques logicielles
+├── /mnt/ # Point de montage pour les systèmes de fichier temporaires
+├── /media/ # Point de montage pour les disques temporaires
+├── /opt/ # Logiciels optionnels, la ou on installera des programmes maison
+├── /root/ # Répertoire du user root
+├── /var/ # Variable, contient des logs, ect...
+├── /usr/ # Contient sensiblement la même chose que la racine mais sans être utile au fonctionnement du système
+├── /srv/ # Services hébergés sur le systèmes (FTP, HTTP, ect...)
+├── /run/ # Emplacement mémoire des programmes
+└── /tmp/ # Temporaire
+Javascript en gros pt.1 (30/01/26)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JS en gros pt.2 : Asynchrone et promesses, Manip de fichiers (06/02/26)
+Asynchrone et promesses (promise)
+C'est quoi Asynchrone ?
+1. SANS Asynchrone
+
+
+
+2. AVEC Asynchrone
+
+
+Mais c'est quoi cette promesse ? (Promise)
+
+
+
+
+Exemples async et await
+Exemple d'un async (exo du TP 2 de JS)
+files.forEach((fileName) => {
+ fs.readFile(fileName, 'utf8').then((content) => {
+ ...
+ })
+});
+
+
+fs.readFile : Envoie le job de lire un fichier à l'ordinateur avec des parametres et quand c'est pret, enrengistre son résultat dans content.contentExemple concret await (exo du TP 2 de JS)
+awaitconst stats = await fs.stat(filename);
+
+
+fs.stat : Envoie le job de récupérer les stats d'un fichier à l'ordinateur et quand c'est pret, enrengistre son résultat dans stats.stats**await** : Tant que l'on a pas de résultat, on "fige" à cette ligne jusqu'à ce que la promesse est reçue.Manipulation de fichiers
+const fs = require('fs').promises; // fs prendra l'appel du module en utilisant les promesses de tout à l'heure
+Lecture de fichiers (fs.readFile)
+fs.readFile. Lorsque cette commande est exécutée, le moteur JavaScript ne lit pas le fichier lui-même. Il envoie une requête au système d'exploitation (l'OS) pour qu'il s'en charge.
+
+2. La Résolution (Le Callback)
+
+
+.then) :
+ Déclenché si l'opération a réussi. Le système injecte les données lues (le contenu du fichier) dans la fonction définie ici. C'est ici que le traitement des données commence..catch) :
+ Déclenché si l'opération a échoué (fichier introuvable, permissions refusées). Le système injecte un objet Error contenant les détails du problème. Cela permet de capturer l'exception sans faire planter l'application.
+PARTIE 2 : Le Traitement Séquentiel (Le modèle
+async/await)async/await permet de forcer un comportement séquentiel au sein d'une fonction asynchrone.1. La Suspension de l'Exécution (
+await)await placé devant une Promesse (comme fs.readFile) modifie le flux d'exécution.
+* Concrètement : L'interpréteur met en pause uniquement l'exécution de la fonction actuelle. Il attend que la Promesse soit résolue (terminée) avant de passer à la ligne suivante.
+* L'encodage (utf8) : Spécifie au système de convertir directement le flux binaire (Buffer) en chaîne de caractères lisible (String) avant de renvoyer le résultat.2. Le Mode d'Écriture (
+appendFile vs writeFile)
+
+fs.writeFile (Écrasement) :
+ Cette méthode ouvre le fichier et place le curseur au tout début (index 0). Si le fichier contient déjà des données, elles sont tronquées (supprimées) et remplacées par le nouveau contenu.fs.appendFile (Ajout) :
+ Cette méthode ouvre le fichier et place le curseur directement à la fin du fichier (EOF - End Of File). Les nouvelles données sont écrites à la suite des existantes, préservant ainsi l'historique.3. L'Itération (La boucle)
+async/await, une boucle permet de traiter une liste d'éléments un par un.
+* Concrètement : Le système traite le premier fichier, attend la fin complète de l'opération (lecture + écriture), et seulement ensuite passe à l'itération suivante. Cela garantit l'ordre des opérations.
+📝 En Résumé Technique
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ await) : Force le code à attendre la résolution d'une promesse avant de continuer, simulant un code synchrone pour plus de lisibilité et de contrôle.Javascript en gros
+Sommaire
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Liens cools de ma poche
+🎨 Design
+💽 Developpement
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Grabber pt.1 (05/12/25)
+summary.txt situé dans le dossier /opt/grabber.Commandes et explications
+1. Variables et chemins
+DIR=/opt/grabber
+- Définit le répertoire de travail principal pour le script.SUM="$DIR/summary.txt"
+- Définit le chemin absolu du fichier de sortie où les informations seront écrites.2. Récupération Hardware (Matériel)
+lscpu -eMODELNAME | tail -n1
+- Affiche les détails du CPU et isole la dernière ligne pour obtenir uniquement le nom du modèle.sudo dmidecode -t processor | grep ID
+- Utilise l'outil dmidecode (nécessite les privilèges root) pour extraire l'identifiant unique du processeur.lsmem | grep 'Mémoire partagée'
+- Récupère la taille de la mémoire vive (RAM) disponible sur le système.lsblk -dnb
+- Liste les périphériques de blocs (disques) sans afficher les partitions, en excluant les boucles (loop) et le boot, pour calculer le stockage total.numfmt --to iec $STOCKAGE_TOTAL
+- Convertit la taille totale du stockage (calculée en octets) vers un format lisible par l'humain (ex: 500G, 1T).3. Récupération Software (Logiciel)
+lsb_release -a
+- Affiche les informations spécifiques à la distribution Linux installée (Description, Release).uname -a
+- Récupère l'architecture du système (ex: x86_64).uname -r
+- Affiche la version actuelle du noyau (Kernel) Linux.4. Fonctions d'écriture (Logique)
+echo "[HARDWARE]" > $SUM
+- Initialise le fichier de résumé en écrivant l'en-tête. Le signe > écrase tout contenu précédent pour repartir à zéro.echo "VAR = $VAR" >> $SUM
+- Ajoute les lignes d'informations (CPU, RAM, OS, etc.) à la suite du fichier. Le signe >> permet d'ajouter du texte sans effacer ce qui existe déjà.hardware et software
+- Appelle les deux fonctions définies précédemment pour exécuter la collecte et l'écriture des données.
+celui qui pete fort dans la classe jv te grabberSite de notes avec Zensical (23/01/26)
+Pourquoi faire ?
+
+
+Comment Zensicle marche
+
+
+Hébergement via Github (Github Actions)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
sudo [commande]\n# -a pour afficher les fichiers cachés / -l pour afficher en liste avec plus d'infos\nls [options] [fichier|dir]\n
cd : changer de dossier
# ~ pour aller au répertoire home / .. pour revenir en arriere\ncd [dir]\n pwd : affiche le répertoire actuel
pwd\n touch : affiche le contenu d'un fichier
touch [fichier]\n nano : éditeur de texte
nano [fichier]\n mkdir : supprime ce qu'on lui donne
mkdir [options] [fichier|dir]\n rm : supprime ce qu'on lui donne
# -r pour supprimer un dossier et son contenu (recursive) (`rmdir` le fait aussi)\n# -f force la commande\nrm [options] [fichier|dir]\n cp : copie...
cp [options] [source] [destination]\n mv : ...et déplace
mv [options] [source] [destination]\n | (le pipe) -> prend le résultat de la commande de gauche et le donne à celle de droite
exemple : liste tout un répertoire, mais n'affiche que les résultats qui sont \"feur\"
ls -la | grep \"feur\"\n > et >>
> écrase le fichier / >> ajoute à la fin sans effacerecho \"coucou\" > fichier.txtchmod [droits] [fichier] - change les permissions d'un fichier (qui peut lire/écrire/exécuter) - chmod +x [fichier] rend un script exécutable (très important) - chmod 777 [fichier] donne tous les droits à tout le monde (dangereux mais ça dépanne)
chown [user]:[groupe] [fichier] - change le propriétaire du fichier (si t'as copié un truc en sudo et que tu peux plus le toucher)
cat [fichier] - affiche tout le contenu d'un fichier d'un coup dans le terminal - utile pour les petits fichiers, sinon ça inonde l'écran
less [fichier] - affiche le contenu page par page (on peut scroller) - appuyer sur q pour quitter
head [fichier] / tail [fichier] - affiche juste le début (head) ou la fin (tail) d'un fichier - tail -f [fichier] hyper utile pour voir les logs en direct (ça attend les nouvelles lignes)
grep [mot] [fichier] - cherche un mot ou une phrase spécifique dans un fichier (le ctrl+f du terminal) - -r pour chercher dans tous les dossiers (recursive) / -i pour ignorer les majuscules
completement zehef pcq t'as pas git push
","path":["Cheatsheets","Git pour les neuilles (12/12/25)"],"tags":[]},{"location":"cheatsheets/2025-12-12/#git-pour-les-neuilles-121225","level":1,"title":"Git pour les neuilles (12/12/25)","text":"","path":["Cheatsheets","Git pour les neuilles (12/12/25)"],"tags":[]},{"location":"cheatsheets/2025-12-12/#creer-un-git","level":2,"title":"Créer un git","text":"","path":["Cheatsheets","Git pour les neuilles (12/12/25)"],"tags":[]},{"location":"cheatsheets/2025-12-12/#-si-le-projet-existe-deja","level":3,"title":"-> Si le projet existe deja","text":"git clone (url du projet git)git init (dossier de travail)echo gbvenv/ >> .gitignore <- on indique via un echo qui écrira dans le fichier .gitignore qu'on ne veut pas push le dossier \"gbvenv\" ici, un fichier on ne mettera pas le slash (logique en amont)
Pour envoyer un projet git, c'est comme envoyer un colis à la poste, d'abord, on met nos affaires dans le colis
Plusieures possibilités ☝️
Ajoute TOUS les fichiers du dossier via l'option -A ou --all -> git add -A
Ajoute SEULEMENT les modifications et suppressions (donc pas de nouveaux fichiers) -> git add -u
Ensuite, on rempli l'étiquette du colis et on la colle au colis
git commit -m \"(message du commit)\"Enfin pour push, c'est a dire déposer le colis au bureau de poste pour l'envoi, on fait :
git push -u origin (branche souhaitée)Info
-u veut dire ce que dit la doc en gros
","path":["Cheatsheets","Git pour les neuilles (12/12/25)"],"tags":[]},{"location":"cheatsheets/2025-12-12/#-si-erreur","level":3,"title":"-> SI ERREUR","text":"Dans le cas ou un fichier/dossier a été supprimé autre part avant de push nos modifs
git config pull.rebase falseDans le cas ou l'on veut travailler avec une seconde branche
Pour switch de branche de travail -> git checkout (branche souhaitée)
Pour merge en ecrasant la branche souhaitée ⬇️
git merge -s ours main\ngit checkout main\ngit merge (branche à merge)\n 7alouf ouvre grabber apres 9h brainrot tsunami
","path":["Cheatsheets","pip et environnements virtuels pour les caca (16/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-16/#pip-et-environnements-virtuels-pour-les-caca-160126","level":1,"title":"pip et environnements virtuels pour les caca (16/01/26)","text":"","path":["Cheatsheets","pip et environnements virtuels pour les caca (16/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-16/#python-et-ses-environnements-virtuels","level":2,"title":"Python et ses environnements virtuels","text":"Utile de créer donc un environnement pour chaque projet afin de en pas perturber d'autres projets avec des milliers de packages inutiles en gros
python3 -m venv gbvenv <- permet de créer un environnement (venv crée l'environnement \"gbvenv\")
source gbvenv/bin/activate <- lance cet environnement pour travailler dedans
pip est le packages manager de python, en l'appelant, on peut installer des packages comme uvicorn par exemple, utile pour grabber
pip install --upgrade pip <- update les packages
python -m pip install *** <- installe le package qu'on notera a la place des ***
pip freeze >> requirements.txt <- commande super utile pour partager les dependances necessaires pour faire fonctionner son projet sur un autre environnement
deactivate <- désactive l'environnement virtuel
bash <(curl -fsSL https://raw.githubusercontent.com/buchtioof/venv-setup/main/venvsetup.sh)
Pour en apprendre plus : le git du projet
","path":["Cheatsheets","pip et environnements virtuels pour les caca (16/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/","level":1,"title":"SQL pour les tung tung tung sahur (22/01/26)","text":"florian quand je lui demande de l'aide
","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/#sql-pour-les-tung-tung-tung-sahur-220126","level":1,"title":"SQL pour les tung tung tung sahur (22/01/26)","text":"","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/#modele-mvc","level":2,"title":"Modèle MVC","text":"Le modèle MVC est une façon de concevoir un projet logiciel, en gros on sépare celui-ci en trois grandes parties distinctes séparant la logique de la vue et rend le travail plus facile.
Modèle MVC en prenant celui de grabber par exemple :
- Model = Base De Donnée (ex: EMPLOYEES, COMPUTERS)\n- View = Tableau de bord, Site\n- Controller = Cerveau qui dirige les deux parties Model et View (ex: app.py)\n","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/#tuto-comment-cr2er-une-bdd-sql-facilement-en-2-minutes-super-facile","level":2,"title":"TUTO : COMMENT CR2ER UNE BDD SQL FACILEMENT EN 2 MINUTES (SUPER FACILE)","text":"","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/#structure-dune-base-de-donnees","level":3,"title":"Structure d'une Base De Données","text":"celle de grabber pour l'exemple
BDD (Etape 1) - grabberman\n├── TABLES (Etape 2) - COMPUTERS\n│ ├── Colonne (Etape 3) - PcId, entier/clé primaire\n│ │ └── Donnée (Etape 4)\n│ ├── Colonne (Etape 3) - Hostname, chaîne de charactère\n│ └── Colonne (Etape 3) - MacAddress, chaîne de charactère\n└── TABLES (Etape 2) - EMPLOYEES\n ├── Colonne (Etape 3) - UserId, entier/clé primaire\n ├── Colonne (Etape 3) - Username, chaîne de charactère\n └── Colonne (Etape 3) - PcId, clé secondaire\n","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/#etape-1-creer-une-bdd","level":3,"title":"Etape 1 : Créer une BDD","text":"sqlite3 grabberman.db <- Commande qui crée une DB qu'on appellera ici \"grabberman\"
CREATE TABLE \"COMPUTERS\" \n(\n PcId INTEGER PRIMARY KEY AUTOINCREMENT, \n Hostname VARCHAR(50) NOT NULL, \n MacAddress VARCHAR(50)\n);\n Note
Ici on crée une table dans laquelle on stockera des données (des PC que l'on grab par exemple)
","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/#etape-3-ajouter-des-donnees-dans-une-table","level":3,"title":"Etape 3 : Ajouter des données dans une table","text":"INSERT into COMPUTERS (Hostname, MacAddress) VALUES ('mypc', '1B:12:F0:FL:94');
Note
Pour ajouter une donnée dans une tableau, on INSERE dans le TABLEAU donné les VALEURS dans les Colonnes
","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"cheatsheets/2026-01-22/#etape-4-creer-un-autre-tableau-avec-une-cle-liee-foreign-key","level":3,"title":"Etape 4 : Créer un autre tableau avec une clé liée (foreign key)","text":"CREATE TABLE \"EMPLOYEES\" \n(\n UserId INTEGER PRIMARY KEY AUTOINCREMENT, \n Username VARCHAR(50) NOT NULL, \n FOREIGN KEY (PcId) REFERENCES COMPUTERS(PcId)\n);\n Note
On recommence comme à l'étape 2, en ajoutant une clé étrangère foreign key, qui lie une clé extérieure, PcId ici, dans notre second Tableau
","path":["Cheatsheets","SQL pour les tung tung tung sahur (22/01/26)"],"tags":[]},{"location":"learn/2025-10-30/","level":1,"title":"C koi linux ? (30/10/25)","text":"","path":["Cours","C koi linux ? (30/10/25)"],"tags":[]},{"location":"learn/2025-10-30/#c-koi-linux-301025","level":1,"title":"C koi linux ? (30/10/25)","text":"Warning
Page en travaux, doit être finie avec toutes les informations que j'ai sur Linux en général
","path":["Cours","C koi linux ? (30/10/25)"],"tags":[]},{"location":"learn/2025-10-30/#arborescence-type-sur-unix","level":2,"title":"Arborescence type sur UNIX","text":"/ # Racine du disque\n├── /bin/ # Contient les commandes de base\n├── /boot/ # Fichiers de demarrage\n├── /dev/ # Tout ce qui est lié aux périphériques\n├── /etc/ # Fichiers de configuration\n├── /home/ # Répertoires utilisateurs\n├── /lib/ # Bibliothèques logicielles\n├── /mnt/ # Point de montage pour les systèmes de fichier temporaires\n├── /media/ # Point de montage pour les disques temporaires\n├── /opt/ # Logiciels optionnels, la ou on installera des programmes maison\n├── /root/ # Répertoire du user root\n├── /var/ # Variable, contient des logs, ect...\n├── /usr/ # Contient sensiblement la même chose que la racine mais sans être utile au fonctionnement du système\n├── /srv/ # Services hébergés sur le systèmes (FTP, HTTP, ect...)\n├── /run/ # Emplacement mémoire des programmes\n└── /tmp/ # Temporaire\n source de l'arbo.","path":["Cours","C koi linux ? (30/10/25)"],"tags":[]},{"location":"learn/javascript/","level":1,"title":"Javascript en gros","text":"","path":["Cours","Javascript en gros"],"tags":[]},{"location":"learn/javascript/#sommaire","level":2,"title":"Sommaire","text":"Info
Avant de manipuler des fichiers, il faut comprendre le fonctionnement des modules qui s'en occuperont, l'asynchrone.
","path":["JS en gros pt.2 : Asynchrone et promesses, Manip de fichiers (06/02/26)"],"tags":[]},{"location":"learn/javascript/2026-02-06/#asynchrone-et-promesses-promise","level":2,"title":"Asynchrone et promesses (promise)","text":"","path":["JS en gros pt.2 : Asynchrone et promesses, Manip de fichiers (06/02/26)"],"tags":[]},{"location":"learn/javascript/2026-02-06/#cest-quoi-asynchrone","level":3,"title":"C'est quoi Asynchrone ?","text":"Asynchrone permet de ne pas bloquer le code même si il n'a pas de résultat mais avec promesse, il laisse le code continuer pour trouver une réponse et la rapporter comme promis.
Rien de mieux qu'un exemple concret et gourmand en amont !
","path":["JS en gros pt.2 : Asynchrone et promesses, Manip de fichiers (06/02/26)"],"tags":[]},{"location":"learn/javascript/2026-02-06/#1-sans-asynchrone","level":4,"title":"1. SANS Asynchrone","text":"Résultat : La file d'attente sort du restaurant. Si la cuisson prend 10 minutes, tout le restaurant est bloqué pendant 10 minutes. Bien guez.
","path":["JS en gros pt.2 : Asynchrone et promesses, Manip de fichiers (06/02/26)"],"tags":[]},{"location":"learn/javascript/2026-02-06/#2-avec-asynchrone","level":4,"title":"2. AVEC Asynchrone","text":"☝️🤓 Node.js fonctionne sur un principe de thread unique (monothread)... En gros, il ne peut effectuer qu'une seule tâche à la fois.
Pour éviter de bloquer le programme pendant de longues opérations (comme lire des données au fin fond du disque dur), il délègue ces tâches a l'ordinateur et utilise un mécanisme de Promesses.
Dans notre exemple, la Promise, c'est le bipeur.
Ce boîtier est une promesse. Le restaurant te dit : \"Je n'ai pas ton crousty tout de suite, mais je te promets que je te préviendrai dès qu'il y a du nouveau.\"
Une Promise a toujours 3 états possibles, et seulement 3 :
files.forEach((fileName) => {\n fs.readFile(fileName, 'utf8').then((content) => {\n ...\n })\n});\n fs.readFile : Envoie le job de lire un fichier à l'ordinateur avec des parametres et quand c'est pret, enrengistre son résultat dans content.contentOn peut également demander spécifiquement d'attendre le retour d'une promesse avec await
const stats = await fs.stat(filename);\n fs.stat : Envoie le job de récupérer les stats d'un fichier à l'ordinateur et quand c'est pret, enrengistre son résultat dans stats.stats**await** : Tant que l'on a pas de résultat, on \"fige\" à cette ligne jusqu'à ce que la promesse est reçue.Pour manipuler des fichiers avec Node.JS, il existe un module appelé Node.JS fs, fs pour fiché S. Avec cette librairie on peut manipuler de plusieurs manière nos fichiers, les lire, écrire ou réécrire, demander les infos d'un fichier, copier et pleinnn de choses encore !
Ici on se concentrera sur les fonctions qu'on utilise dans le TP 2 de JS
Avant tout, pour utiliser ce module, il faut l'appeler via une constante :
const fs = require('fs').promises; // fs prendra l'appel du module en utilisant les promesses de tout à l'heure\n","path":["JS en gros pt.2 : Asynchrone et promesses, Manip de fichiers (06/02/26)"],"tags":[]},{"location":"learn/javascript/2026-02-06/#lecture-de-fichiers-fsreadfile","level":2,"title":"Lecture de fichiers (fs.readFile)","text":"Pour lire des fichiers, on utilise la fonction fs.readFile. Lorsque cette commande est exécutée, le moteur JavaScript ne lit pas le fichier lui-même. Il envoie une requête au système d'exploitation (l'OS) pour qu'il s'en charge.
Une fois que le système d'exploitation a fini de lire le fichier, il notifie le programme. La Promesse change d'état et déclenche l'une des deux fonctions suivantes :
Le Succès (.then) : Déclenché si l'opération a réussi. Le système injecte les données lues (le contenu du fichier) dans la fonction définie ici. C'est ici que le traitement des données commence.
L'Erreur (.catch) : Déclenché si l'opération a échoué (fichier introuvable, permissions refusées). Le système injecte un objet Error contenant les détails du problème. Cela permet de capturer l'exception sans faire planter l'application.
async/await)","text":"Parfois, l'asynchronisme pur est difficile à gérer (besoin d'ordre précis). La syntaxe async/await permet de forcer un comportement séquentiel au sein d'une fonction asynchrone.
await)","text":"Le mot-clé await placé devant une Promesse (comme fs.readFile) modifie le flux d'exécution. * Concrètement : L'interpréteur met en pause uniquement l'exécution de la fonction actuelle. Il attend que la Promesse soit résolue (terminée) avant de passer à la ligne suivante. * L'encodage (utf8) : Spécifie au système de convertir directement le flux binaire (Buffer) en chaîne de caractères lisible (String) avant de renvoyer le résultat.
appendFile vs writeFile)","text":"Lorsqu'il s'agit d'écrire des données sur le disque, le choix de la méthode détermine comment le fichier est manipulé au niveau basique :
fs.writeFile (Écrasement) : Cette méthode ouvre le fichier et place le curseur au tout début (index 0). Si le fichier contient déjà des données, elles sont tronquées (supprimées) et remplacées par le nouveau contenu.
fs.appendFile (Ajout) : Cette méthode ouvre le fichier et place le curseur directement à la fin du fichier (EOF - End Of File). Les nouvelles données sont écrites à la suite des existantes, préservant ainsi l'historique.
Dans un contexte async/await, une boucle permet de traiter une liste d'éléments un par un. * Concrètement : Le système traite le premier fichier, attend la fin complète de l'opération (lecture + écriture), et seulement ensuite passe à l'itération suivante. Cela garantit l'ordre des opérations.
await) : Force le code à attendre la résolution d'une promesse avant de continuer, simulant un code synchrone pour plus de lisibilité et de contrôle.Ce script a pour but de récupérer automatiquement les informations matérielles (CPU, RAM, Stockage) et logicielles (OS, Kernel, Environnement de bureau) de la machine. Il formate ensuite ces données et les enregistre dans un fichier summary.txt situé dans le dossier /opt/grabber.
DIR=/opt/grabber - Définit le répertoire de travail principal pour le script.
SUM=\"$DIR/summary.txt\" - Définit le chemin absolu du fichier de sortie où les informations seront écrites.
lscpu -eMODELNAME | tail -n1 - Affiche les détails du CPU et isole la dernière ligne pour obtenir uniquement le nom du modèle.
sudo dmidecode -t processor | grep ID - Utilise l'outil dmidecode (nécessite les privilèges root) pour extraire l'identifiant unique du processeur.
lsmem | grep 'Mémoire partagée' - Récupère la taille de la mémoire vive (RAM) disponible sur le système.
lsblk -dnb - Liste les périphériques de blocs (disques) sans afficher les partitions, en excluant les boucles (loop) et le boot, pour calculer le stockage total.
numfmt --to iec $STOCKAGE_TOTAL - Convertit la taille totale du stockage (calculée en octets) vers un format lisible par l'humain (ex: 500G, 1T).
lsb_release -a - Affiche les informations spécifiques à la distribution Linux installée (Description, Release).
uname -a - Récupère l'architecture du système (ex: x86_64).
uname -r - Affiche la version actuelle du noyau (Kernel) Linux.
echo \"[HARDWARE]\" > $SUM - Initialise le fichier de résumé en écrivant l'en-tête. Le signe > écrase tout contenu précédent pour repartir à zéro.
echo \"VAR = $VAR\" >> $SUM - Ajoute les lignes d'informations (CPU, RAM, OS, etc.) à la suite du fichier. Le signe >> permet d'ajouter du texte sans effacer ce qui existe déjà.
hardware et software - Appelle les deux fonctions définies précédemment pour exécuter la collecte et l'écriture des données.
celui qui pete fort dans la classe jv te grabber
","path":["Projets","Site de notes avec Zensical (23/01/26)"],"tags":[]},{"location":"projects/2026-01-23/#site-de-notes-avec-zensical-230126","level":1,"title":"Site de notes avec Zensical (23/01/26)","text":"Note
Pendant la création de cette note j'ai immigré mkdocs à Zensicle (maj de mkdocs en meilleur) et donc j'utilise une config qui réutilise les fichiers et la structure mkdocs.
","path":["Projets","Site de notes avec Zensical (23/01/26)"],"tags":[]},{"location":"projects/2026-01-23/#pourquoi-faire","level":2,"title":"Pourquoi faire ?","text":"Pour héberger mon site de documentation en ligne, j'utilise Github via Github Actions qui est la solution parfaite pour un projet léger comme celui-ci.
Docs pour host sur Github
","path":["Projets","Site de notes avec Zensical (23/01/26)"],"tags":[]}]} \ No newline at end of file diff --git a/site/sitemap.xml b/site/sitemap.xml new file mode 100644 index 0000000..0f8724e --- /dev/null +++ b/site/sitemap.xml @@ -0,0 +1,3 @@ + +