PageSourceSearch

https://roadmap.sh/assets/_roadmapSlug._index-CjW8cYky.js

js roadmap.sh collected 2026-09-24 17:12:16 UTC 35,411 bytes, 1 lines download raw bytes

1import{r as d,L as K,R,f as Z,w as fe}from"./chunk-LFPYN7LY-CxYJBB4n.js";import{j as r}from"./jsx-runtime-u17CrQMm.js";import{d as V}from"./merge-meta-BNrMYBKx.js";import{u as xe,r as ge}from"./use-personalized-view-BGhC4YH-.js";import{r as S}from"./markdown-BnLBBJul.js";import{H as Y}from"./header-navigation-Zxy9HLPv.js";import{O as we}from"./open-source-banner-CTdZiymO.js";import{F as ve}from"./footer-k5Fh8SkS.js";import{i as ye}from"./official-roadmap-DA59IKw1.js";import{E as je}from"./editor-roadmap-CvgLaC48.js";import{c as C}from"./classname-DRuCqhNm.js";import{C as ee}from"./chevron-down-CnlvjBkU.js";import{a as te}from"./index-5KpBttEn.js";import{t as se}from"./tweet-BS1ZHrEd.js";import{h as be}from"./chunk-JPUPSTYD-B3Xjnybf.js";import{M as Ne}from"./map-DdKtxsw_.js";import{D as _}from"./luxon-BDx6lZXm.js";import{b as ke,c as Ce}from"./jsonld-schema-C5SJuse3.js";import{g as Ie}from"./open-graph-FUw_TNMM.js";import{R as Me}from"./roadmap-header-CipatZ-h.js";import{u as W}from"./useQuery-P35A8NL-.js";import"./js.cookie-C2b7Ongr.js";import{u as Pe,d as Se}from"./resource-progress-nXgeiNtt.js";import{u as Oe}from"./use-is-mounted-B4EJBk2e.js";import{g as Re}from"./number-zVSOld3Q.js";import{u as De}from"./use-auth-BVv6RG2G.js";import{a as Fe}from"./global-3lcJzC0w.js";import{V as Te}from"./video-modal-C_sb-w8r.js";import{D as Ae,a as Ee}from"./dialog-BMBIq-20.js";import{T as Le}from"./trophy-DSjfHrwn.js";import{C as Be}from"./credit-card-D8_Vz5Im.js";import{P as $e,M as Qe}from"./progress-detail-dialog-CNNifnRg.js";import{E as Ue}from"./ellipsis-Dp_WREZY.js";import{M as re}from"./mouse-pointer-click-DgZVGxHi.js";import{P as qe}from"./play-CHPnUHcC.js";import{U as ze}from"./users-round-CFyf4T67.js";import{X as Ve}from"./x-C_y3DjD-.js";import{u as Ye}from"./use-outside-click-Df0WsR0p.js";import{I as H}from"./info-D3sXzrq3.js";import{C as _e}from"./chevron-up-BdqLXtFH.js";import{T as We}from"./twitter-filled-icon-OiU4FZgQ.js";import{F as He,H as Ge,R as Xe}from"./share-roadmap-dropdown-Bq7ltNrH.js";import{f as Je}from"./http-CTVYXoFf.js";import{P as Ke}from"./font-ifSA_FkE.js";import{U as Ze}from"./user-progress-modal-CdVLax9l.js";import{s as et}from"./config-D7Hgu3rf.js";import"./nav-loading-bar-uURRKt_i.js";import"./index-EifBzzhN.js";import"./github-button-C_VJ60Tt.js";import"./query-client-D1G_5A9t.js";
1import"./growthbook-jYNfGpxe.js";import{ErrorBoundary as Jo}from"./root-C5OjnxDx.js";import"./preload-helper-BXl3LOEh.js";import"./index-_Dy2zPzC.js";import"./index-BTMM0QfC.js";import"./jwt-DhNkEzhq.js";import"./use-copy-to-clipboard-BGxkkwDA.js";import"./createLucideIcon-CLTT37CB.js";import"./copy-B1rqJq4x.js";import"./check-Be09DAW-.js";import"./queryOptions-C9woPjwX.js";import"./popover-D3HkGOcH.js";import"./index-1oySP5XJ.js";import"./index-D7BKGJtK.js";import"./index-BffqbdGU.js";import"./index-Dcn_uD5y.js";import"./index-BvdFR2cs.js";import"./floating-ui.react-dom-CZYZb5vz.js";import"./floating-ui.dom-BlB1qeIh.js";import"./index-DBmvM3pA.js";import"./zap-BmFxu1Ha.js";import"./index-D8c4ZMKi.js";import"./index-BzdXg-Sh.js";import"./index-CZkDnA4h.js";import"./roadmap-logo-icon-a09rxs2m.js";import"./dropdown-menu-DMYL-U3U.js";import"./index-BqOrkNal.js";import"./chevron-right-BnD0iq3A.js";import"./circle-DEGe6stZ.js";import"./billing-BFLIoaPy.js";import"./bolt-icon--lhp8oTB.js";import"./auth-BIP5_LPj.js";import"./create-roadmap-dialog-BUanP5Fi.js";import"./text-i1qKOPPZ.js";import"./index-CgZTUWtW.js";import"./input-DXX80BGV.js";import"./useMutation-B3yAdLyW.js";import"./mutation-DrjdnOUW.js";import"./removable-D_N_DFtB.js";import"./QueryClientProvider-Xk8xomy6.js";import"./loader-circle-B6CunRWs.js";import"./autogrow-textarea-nDVj9IX8.js";import"./react-textarea-autosize.browser.esm-DHkk8ZgT.js";import"./bot-BkewBLrS.js";import"./sparkles-CpABkUE0.js";import"./gift-B77t1qz2.js";import"./date-CAat6foK.js";import"./circle-check-CbArdvsM.js";import"./clock-DZHFJTkO.js";import"./send-o4tKuzpj.js";import"./arrow-left-D0Rcv34S.js";import"./teams-D4pzBOPH.js";import"./chevron-left-PCn8yt-d.js";import"./plus-Ck1XQ4uL.js";import"./users-tC2vCoRy.js";import"./user-CulfSC_Z.js";import"./database-DXjGUEgQ.js";import"./arrow-right-D2ipYrcY.js";import"./book-open-text-BDTqPtHs.js";import"./globe-nuOVr0BO.js";import"./menu-DW5bp6JP.js";import"./message-circle-fdjSrxec.js";import"./star-CaZmRDEJ.js";import"./constants-BohhKOEU.js";import"./index-UMF06FQe.js";import"./with-selector-D4xnjkNS.js";import"./index.browser-OxPLOBIU.js";import"./shallow-B8qSLTeo.js";import"./index-BwqomJjk.js";import"./editor-roadmap-renderer-Cmw1_cpc.js";import"./resource-progress-CD1Hnl4e.js";import"./use-floating-chat-DTqpvT5V.js";import"./predefined-actions-BiFa4CwB.js";import"./book-open-2GVhA0Bu.js";import"./list-B5irbYxR.js";import"./pencil-line-DpmBx-ou.js";import"./brain-DqwGBkx6.js";import"./dom-D18O2J_d.js";import"./ai-B6WgfSF2.js";import"./mutationOptions-Cd69wAAa.js";import"./use-ai-chat-scroll-eX9SvHqi.js";import"./use-ai-usage-BXZkUXIQ.js";import"./use-keydown-D77SNBzC.js";import"./spinner-icon-CuzYa3NU.js";import"./topic-details-Bo7t1TWA.js";import"./lesson-pack-section-Ba6KSQG1.js";import"./google-ad-manager-BTmP8wtU.js";import"./paid-resource-disclaimer-B9Cz8J3X.js";import"./popover-CHbt9k99.js";import"./resource-section-DYT5o_pz.js";import"./reading-time-BnrNj9gH.js";import"./circle-question-mark-B6qM3pjK.js";import"./wrench-DLYhQxYz.js";import"./arrow-up-right-CWAuz0Gp.js";import"./lock-u1gdBlyl.js";import"./heart-handshake-LDoM35M2.js";import"./ai-generate-BwtsD1Dd.js";import"./ai-credits-BJZVMesn.js";import"./markdown-D485u30Z.js";import"./index-BtVlrGzH.js";import"./index-nt904-xk.js";import"./triangle-alert-DpgbLXH6.js";import"./ai-guide-BMwzuu6A.js";import"./wand-sparkles-CrF4C6eF.js";import"./earth-ix278x-R.js";import"./topic-details-ai-BdqIS7bK.js";import"./ai-usage-lock-Bkew71PV.js";import"./use-go-to-checkout-BhPzWMeU.js";import"./upgrade-nudge-BZX_CdMy.js";import"./ai-usage-meter-V4mbIIYv.js";import"./upgrade-card-CNzmFf-O.js";import"./user-round-f9EUdvn4.js";import"./messages-_-9103L6.js";import"./index-CxHOLyYJ.js";import"./pages-HhlNrouv.js";import"./book-BDPFEGFi.js";import"./chart-column-C2aSE-lp.js";import"./external-link-Bl4Z-elI.js";import"./circle-check-big-CCkIn-0A.js";import"./graduation-cap-DNPjMS4G.js";import"./rotate-cw-BgFOs21o.js";import"./trash-CgM-wyY3.js";import"./trash-2-BqsNdxZb.js";import"./github-icon-o2o59s9s.js";import"./index-C5IjTNfD.js";import"./ai-DCsezkBR.js";import"./file-text-B1Kw2jgA.js";import"./slugger-rj1cS6co.js";import"./floating-chat-DhgxsDhr.js";import"./circle-pause-CkspgQ7x.js";/* empty css                */import"./chat-header-button-DUPOD5Tl.js";import"./roadmap-chat-messages-CCA5jfbl.js";import"./check-filled-icon-wcUYqTNf.js";import"./users-CSYwoXFM.js";import"./share-D3WL64re.js";import"./update-persona-dialog-4CAL4gnl.js";import"./useInfiniteQuery-DXf33CVO.js";import"./suspense-Cog1UVge.js";import"./query-D-YsdlQT.js";import"./infiniteQueryBehavior-BXBH9LIf.js";import"./useBaseQuery-v2Uot2mJ.js";import"./chat-history-gQSfpfu8.js";import"./list-chat-history-Ba_6VtqL.js";import"./circle-alert-uxnsX_ar.js";import"./use-debounce-Br4KLJb5.js";import"./search-BuNamwXv.js";import"./ellipsis-vertical-MG1503Nd.js";import"./is-mobile-CWj1ep7V.js";import"./history-HJeXtS7h.js";import"./user-persona-BHHUVVyZ.js";import"./select-native-Cke39XGA.js";import"./shuffle-BlbS-uBD.js";import"./person-standing-BQzwMha-.js";import"./bell-CGQWSrsy.js";import"./prefer-on-google-DVtzrs-k.js";import"./google-icon-Bh7QFlHP.js";import"./index-DBgM-eAb.js";import"./index-C6p7gkEG.js";import"./confirm-dialog-CKK4T43c.js";import"./download-CZnb3u64.js";import"./mark-favorite-BTYxx8Go.js";import"./pencil-B18XpgBn.js";import"./use-completion-Bks8aOHB.js";import"./progress-nudge-dR_8tRnl.js";import"./heading-CJKEEnQI.js";import"./account-gsaJqJyU.js";import"./download-image-BKe9oI8o.js";/* empty css                       */import"./modal-loader-DeNzE1eJ.js";import"./error-icon-Ca7zenL-.js";import"./authentication-form-B1_OVx0L.js";import"./square-pen-Djy-21QK.js";import"./interest-selector-C_BRX_ur.js";
1import"./useButton-CBTwfjYl.js";import"./index-ZjJ-nMFn.js";import"./error-Bd8YbcyR.js";import"./refresh-cw-cNFTOX44.js";import"./server-crash-D7Omz0HJ.js";import"./frown-LqFC2Eny.js";import"./site-search-COOfZrjN.js";import"./learn-formats-Bput8ZE0.js";import"./list-todo-BMwgRVHJ.js";import"./index-CBsDineo.js";function tt(a){const{question:e,isActive:t=!1,children:o,onClick:i}=a;return r.jsxs("div",{className:"faq-item rounded-md border border-gray-300 bg-white hover:bg-gray-50",children:[r.jsxs("button",{className:"flex w-full flex-row items-center justify-between p-2 sm:p-3",onClick:i,children:[r.jsx("span",{className:"text-left text-sm font-medium sm:text-base",children:e}),r.jsx(ee,{className:"hidden h-3.5 stroke-[3] text-gray-400 sm:block"})]}),t&&r.jsx("div",{className:C("answer"),children:o})]})}function st(a){const{faqs:e}=a;if(e.length===0)return null;const[t,o]=d.useState(0);return r.jsx("div",{className:"mt-8 border-t bg-gray-100",children:r.jsxs("div",{className:"page-container",children:[r.jsx("div",{className:"relative -top-5 flex justify-between",children:r.jsx("h2",{className:"rounded-md border bg-white px-3 py-1 text-sm font-medium sm:text-base",children:"Frequently Asked Questions"})}),r.jsx("div",{className:"flex flex-col gap-1 pb-14",children:e.map((i,s)=>{const n=typeof i?.description=="string"&&i?.description?.length>0;return r.jsx(tt,{isActive:s===t,question:i.title,onClick:()=>o(s),children:r.jsx("div",{className:"text-md rounded-br-md rounded-bl-md border-t border-t-gray-300 bg-gray-100 p-2 text-left text-sm leading-relaxed text-gray-800 sm:p-4 sm:text-base [&>p:not(:last-child)]:mb-3 [&>p>a]:text-blue-700 [&>p>a]:underline",...n?{dangerouslySetInnerHTML:{__html:i.description}}:{},children:n?null:te(i.description,{tweetApiUrl:se})})},i._id)})})]})})}function rt(a){const{relatedRoadmaps:e}=a;return e.length===0?null:r.jsx("div",{className:"border-t bg-gray-100",children:r.jsxs("div",{className:"page-container",children:[r.jsxs("div",{className:"relative -top-5 flex justify-between",children:[r.jsxs("span",{className:"text-md flex items-center rounded-md border bg-white px-3 py-1 font-medium",children:[r.jsx(Ne,{className:"mr-1.5 text-black",size:"17px"}),"Related ",r.jsx("span",{className:"hidden sm:inline",children:"Roadmaps"})]}),r.jsxs("a",{href:"/roadmaps",className:"text-md rounded-md border bg-white px-3 py-1 font-medium hover:bg-gray-50",children:[r.jsx("span",{className:"hidden sm:inline",children:"All Roadmaps →"}),r.jsx("span",{className:"inline sm:hidden",children:"More →"})]})]}),r.jsx("div",{className:"flex flex-col gap-1 pb-8",children:e.map(t=>r.jsxs(K,{to:be("/:roadmapSlug",{roadmapSlug:t.slug}),className:"flex flex-col gap-0.5 rounded-md border bg-white px-3.5 py-2 hover:bg-gray-50 sm:flex-row sm:gap-0",children:[r.jsx("span",{className:"inline-block min-w-[195px] font-medium",children:t.title.card}),r.jsx("span",{className:"text-gray-500",children:t.description})]}))})]})})}var F,G;function it(){if(G)return F;G=1;var a={linear:function(e,t,o,i){var s=o-t;return s*e/i+t},easeInQuad:function(e,t,o,i){var s=o-t;return s*(e/=i)*e+t},easeOutQuad:function(e,t,o,i){var s=o-t;return-s*(e/=i)*(e-2)+t},easeInOutQuad:function(e,t,o,i){var s=o-t;return(e/=i/2)<1?s/2*e*e+t:-s/2*(--e*(e-2)-1)+t},easeInCubic:function(e,t,o,i){var s=o-t;return s*(e/=i)*e*e+t},easeOutCubic:function(e,t,o,i){var s=o-t;return s*((e=e/i-1)*e*e+1)+t},easeInOutCubic:function(e,t,o,i){var s=o-t;return(e/=i/2)<1?s/2*e*e*e+t:s/2*((e-=2)*e*e+2)+t},easeInQuart:function(e,t,o,i){var s=o-t;return s*(e/=i)*e*e*e+t},easeOutQuart:function(e,t,o,i){var s=o-t;return-s*((e=e/i-1)*e*e*e-1)+t},easeInOutQuart:function(e,t,o,i){var s=o-t;return(e/=i/2)<1?s/2*e*e*e*e+t:-s/2*((e-=2)*e*e*e-2)+t},easeInQuint:function(e,t,o,i){var s=o-t;return s*(e/=i)*e*e*e*e+t},easeOutQuint:function(e,t,o,i){var s=o-t;return s*((e=e/i-1)*e*e*e*e+1)+t},easeInOutQuint:function(e,t,o,i){var s=o-t;return(e/=i/2)<1?s/2*e*e*e*e*e+t:s/2*((e-=2)*e*e*e*e+2)+t},easeInSine:function(e,t,o,i){var s=o-t;return-s*Math.cos(e/i*(Math.PI/2))+s+t},easeOutSine:function(e,t,o,i){var s=o-t;return s*Math.sin(e/i*(Math.PI/2))+t},easeInOutSine:function(e,t,o,i){var s=o-t;return-s/2*(Math.cos(Math.PI*e/i)-1)+t},easeInExpo:function(e,t,o,i){var s=o-t;return e==0?t:s*Math.pow(2,10*(e/i-1))+t},easeOutExpo:function(e,t,o,i){var s=o-t;return e==i?t+s:s*(-Math.pow(2,-10*e/i)+1)+t},easeInOutExpo:function(e,t,o,i){var s=o-t;return e===0?t:e===i?t+s:(e/=i/2)<1?s/2*Math.pow(2,10*(e-1))+t:s/2*(-Math.pow(2,-10*--e)+2)+t},easeInCirc:function(e,t,o,i){var s=o-t;return-s*(Math.sqrt(1-(e/=i)*e)-1)+t},easeOutCirc:function(e,t,o,i){var s=o-t;return s*Math.sqrt(1-(e=e/i-1)*e)+t},easeInOutCirc:function(e,t,o,i){var s=o-t;return(e/=i/2)<1?-s/2*(Math.sqrt(1-e*e)-1)+t:s/2*(Math.sqrt(1-(e-=2)*e)+1)+t},easeInElastic:function(e,t,o,i){var s=o-t,n,c,l;return l=1.70158,c=0,n=s,e===0?t:(e/=i)===1?t+s:(c||(c=i*.3),n<Math.abs(s)?(n=s,l=c/4):l=c/(2*Math.PI)*Math.asin(s/n),-(n*Math.pow(2,10*(e-=1))*Math.sin((e*i-l)*(2*Math.PI)/c))+t)},easeOutElastic:function(e,t,o,i){var s=o-t,n,c,l;return l=1.70158,c=0,n=s,e===0?t:(e/=i)===1?t+s:(c||(c=i*.3),n<Math.abs(s)?(n=s,l=c/4):l=c/(2*Math.PI)*Math.asin(s/n),n*Math.pow(2,-10*e)*Math.sin((e*i-l)*(2*Math.PI)/c)+s+t)},easeInOutElastic:function(e,t,o,i){var s=o-t,n,c,l;return l=1.70158,c=0,n=s,e===0?t:(e/=i/2)===2?t+s:(c||(c=i*(.3*1.5)),n<Math.abs(s)?(n=s,l=c/4):l=c/(2*Math.PI)*Math.asin(s/n),e<1?-.5*(n*Math.pow(2,10*(e-=1))*Math.sin((e*i-l)*(2*Math.PI)/c))+t:n*Math.pow(2,-10*(e-=1))*Math.sin((e*i-l)*(2*Math.PI)/c)*.5+s+t)},easeInBack:function(e,t,o,i,s){var n=o-t;return s===void 0&&(s=1.70158),n*(e/=i)*e*((s+1)*e-s)+t},easeOutBack:function(e,t,o,i,s){var n=o-t;return s===void 0&&(s=1.70158),n*((e=e/i-1)*e*((s+1)*e+s)+1)+t},easeInOutBack:function(e,t,o,i,s){var n=o-t;return s===void 0&&(s=1.70158),(e/=i/2)<1?n/2*(e*e*(((s*=1.525)+1)*e-s))+t:n/2*((e-=2)*e*(((s*=1.525)+1)*e+s)+2)+t},easeInBounce:function(e,t,o,i){var s=o-t,n;return n=a.easeOutBounce(i-e,0,s,i),s-n+t},easeOutBounce:function(e,t,o,i){var s=o-t;return(e/=i)<1/2.75?s*(7.5625*e*e)+t:e<2/2.75?s*(7.5625*(e-=1.5/2.75)*e+.75)+t:e<2.5/2.75?s*(7.5625*(e-=2.25/2.75)*e+.9375)+t:s*(7.5625*(e-=2.625/2.75)*e+.984375)+t},easeInOutBounce:function(e,t,o,i){var s=o-t,n;return e<i/2?(n=a.easeInBounce(e*2,0,s,i),n*.5+t):(n=a.easeOutBounce(e*2-i,0,s,i),n*.5+s*.5+t)}};return F=a,F}var ot=it();function nt(a){return a*Math.PI/180}function g(a,e){return a+Math.random()*(e-a)}function at(a,e){return Math.floor(a+Math.random()*(e-a+1))}var O;(function(a){a[a.Circle=0]="Circle",a[a.Square=1]="Square",a[a.Strip=2]="Strip"})(O||(O={}));var k;(function(a){a[a.Positive=1]="Positive",a[a.Negative=-1]="Negative"})(k||(k={}));const ct=1e3/60;class lt{constructor(e,t,o,i){this.getOptions=t;const{colors:s,initialVelocityX:n,initialVelocityY:c}=this.getOptions();this.context=e,this.x=o,this.y=i,this.w=g(5,20),this.h=g(5,20),this.radius=g(5,10),this.vx=typeof n=="number"?g(-n,n):g(n.min,n.max),this.vy=typeof c=="number"?g(-c,0):g(c.min,
1c.max),this.shape=at(0,2),this.angle=nt(g(0,360)),this.angularSpin=g(-.2,.2),this.color=s[Math.floor(Math.random()*s.length)],this.rotateY=g(0,1),this.rotationDirection=g(0,1)?k.Positive:k.Negative}update(e){const{gravity:t,wind:o,friction:i,opacity:s,drawShape:n}=this.getOptions(),c=e/ct;this.x+=this.vx*c,this.y+=this.vy*c,this.vy+=t*c,this.vx+=o*c,this.vx*=i**c,this.vy*=i**c,this.rotateY>=1&&this.rotationDirection===k.Positive?this.rotationDirection=k.Negative:this.rotateY<=-1&&this.rotationDirection===k.Negative&&(this.rotationDirection=k.Positive);const l=.1*this.rotationDirection*c;if(this.rotateY+=l,this.angle+=this.angularSpin,this.context.save(),this.context.translate(this.x,this.y),this.context.rotate(this.angle),this.context.scale(1,this.rotateY),this.context.rotate(this.angle),this.context.beginPath(),this.context.fillStyle=this.color,this.context.strokeStyle=this.color,this.context.globalAlpha=s,this.context.lineCap="round",this.context.lineWidth=2,n&&typeof n=="function")n.call(this,this.context);else switch(this.shape){case O.Circle:{this.context.beginPath(),this.context.arc(0,0,this.radius,0,2*Math.PI),this.context.fill();break}case O.Square:{this.context.fillRect(-this.w/2,-this.h/2,this.w,this.h);break}case O.Strip:{this.context.fillRect(-this.w/6,-this.h/2,this.w/3,this.h);break}}this.context.closePath(),this.context.restore()}}class mt{constructor(e,t){this.x=0,this.y=0,this.w=0,this.h=0,this.lastNumberOfPieces=0,this.tweenProgress=0,this.tweenFrom=0,this.particles=[],this.particlesGenerated=0,this.removeParticleAt=i=>{this.particles.splice(i,1)},this.getParticle=()=>{const i=g(this.x,this.w+this.x),s=g(this.y,this.h+this.y);return new lt(this.context,this.getOptions,i,s)},this.animate=i=>{const{canvas:s,context:n,particlesGenerated:c,lastNumberOfPieces:l}=this,{run:m,recycle:h,numberOfPieces:u,debug:x,tweenFunction:y,tweenDuration:w}=this.getOptions();if(!m)return!1;const j=this.particles.length,v=h?j:c;if(v<u){l!==u&&(this.tweenProgress=0,this.tweenFrom=v,this.lastNumberOfPieces=u),this.tweenProgress=Math.min(w,Math.max(0,this.tweenProgress+i));const f=y(this.tweenProgress,this.tweenFrom,u,w),p=Math.round(f-v);for(let b=0;b<p;b++)this.particles.push(this.getParticle());this.particlesGenerated+=p}x&&(n.font="12px sans-serif",n.fillStyle="#333",n.textAlign="right",n.fillText(`Particles: ${j}`,s.width-10,s.height-20));for(let f=this.particles.length-1;f>=0;f--){const p=this.particles[f];p.update(i),(p.y>s.height||p.y<-100||p.x>s.width+100||p.x<-100)&&(h&&v<=u?this.particles[f]=this.getParticle():this.removeParticleAt(f))}return j>0||v<u},this.canvas=e;const o=this.canvas.getContext("2d");if(!o)throw new Error("Could not get canvas context");this.context=o,this.getOptions=t}}const A={width:typeof window<"u"?window.innerWidth:300,height:typeof window<"u"?window.innerHeight:200,numberOfPieces:200,friction:.99,wind:0,gravity:.1,initialVelocityX:4,initialVelocityY:10,colors:["#f44336","#e91e63","#9c27b0","#673ab7","#3f51b5","#2196f3","#03a9f4","#00bcd4","#009688","#4CAF50","#8BC34A","#CDDC39","#FFEB3B","#FFC107","#FF9800","#FF5722","#795548"],opacity:1,debug:!1,tweenFunction:ot.easeInOutQuad,tweenDuration:5e3,recycle:!0,run:!0};let pt=class{constructor(e,t){this.lastFrameTime=0,this.setOptionsWithDefaults=i=>{const s={confettiSource:{x:0,y:0,w:this.canvas.width,h:0}};this._options={...s,...A,...i},Object.assign(this,i.confettiSource)},this.update=(i=0)=>{const{options:{run:s,onConfettiComplete:n,frameRate:c},canvas:l,context:m}=this,h=Math.min(i-this.lastFrameTime,50);if(c&&h<1e3/c){this.rafId=requestAnimationFrame(this.update);return}this.lastFrameTime=i-(c?h%c:0),s&&(m.fillStyle="white",m.clearRect(0,0,l.width,l.height)),this.generator.animate(h)?this.rafId=requestAnimationFrame(this.update):(n&&typeof n=="function"&&this.generator.particlesGenerated>0&&n.call(this,this),this._options.run=!1)},this.reset=()=>{this.generator&&this.generator.particlesGenerated>0&&(this.generator.particlesGenerated=0,this.generator.particles=[],this.generator.lastNumberOfPieces=0)},this.stop=()=>{this.options={run:!1},this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=void 0)},this.canvas=e;const o=this.canvas.getContext("2d");if(!o)throw new Error("Could not get canvas context");this.context=o,this.generator=new mt(this.canvas,()=>this.options),this.options=t,this.update()}get options(){return this._options}set options(e){const t=this._options?.run,o=this._options?.recycle;this.setOptionsWithDefaults(e),this.generator&&(Object.assign(this.generator,this.options.confettiSource),typeof e.recycle=="boolean"&&e.recycle&&o===!1&&(this.generator.lastNumberOfPieces=this.generator.particles.length)),typeof e.run=="boolean"&&e.run&&t===!1&&this.update()}};const ut=R.createRef();class E extends R.Component{constructor(e){super(e),this.canvas=R.createRef(),this.canvas=e.canvasRef||ut}componentDidMount(){if(this.canvas.current){const e=T(this.props)[0];this.confetti=new pt(this.canvas.current,e)}}componentDidUpdate(){const e=T(this.props)[0];
1this.confetti&&(this.confetti.options=e)}componentWillUnmount(){this.confetti&&this.confetti.stop(),this.confetti=void 0}render(){const[e,t]=T(this.props),o={zIndex:2,position:"absolute",pointerEvents:"none",top:0,left:0,bottom:0,right:0,...t.style};return r.jsx("canvas",{width:e.width,height:e.height,ref:this.canvas,...t,style:o})}}E.defaultProps={...A};E.displayName="ReactConfetti";function T(a){const e={},t={},o={},i=[...Object.keys(A),"confettiSource","drawShape","onConfettiComplete","frameRate"],s=["canvasRef"];for(const n in a){const c=a[n];i.includes(n)?e[n]=c:s.includes(n)?s[n]=c:o[n]=c}return[e,o,t]}const dt=R.forwardRef((a,e)=>r.jsx(E,{canvasRef:e,...a}));function ht(a){const{element:e=document.body,onDone:t=()=>null,pieces:o=40}=a,[i,s]=d.useState();function n(c){const l=c.getBoundingClientRect();s({x:l?.x||0,y:(l?.y||0)+window.scrollY,w:l?.width||0,h:l?.height||0})}return d.useEffect(()=>{if(!e){s(void 0);return}n(e)},[e]),i?r.jsx(dt,{height:document.body.scrollHeight,numberOfPieces:o,recycle:!1,onConfettiComplete:c=>{s(void 0),t()},initialVelocityX:4,initialVelocityY:8,tweenDuration:10,confettiSource:{x:i.x,y:i.y,w:i.w,h:i.h}}):null}const ft={25:{heading:"You're making great progress!",body:"You've completed a quarter of the roadmap. Keep the momentum going!"},50:{heading:"Halfway there!",body:"You've reached the halfway mark. You're doing amazing!"},75:{heading:"Almost there!",body:"Just a little more to go. The finish line is in sight!"},100:{heading:"Congratulations!",body:"You've completed the entire roadmap. What an achievement!"}};function xt(a){const{milestone:e,resourceTitle:t,onClose:o}=a,[i,s]=d.useState(!0),n=ft[e];return n?r.jsxs(Ae,{open:!0,onOpenChange:o,children:[r.jsx(Ee,{className:"max-w-sm sm:rounded-xl py-8",overlayClassName:"bg-black/40",showCloseButton:!1,children:r.jsxs("div",{className:"flex flex-col items-center text-center",children:[r.jsx("div",{className:"mb-3 flex h-16 w-16 items-center justify-center rounded-full bg-yellow-50",children:r.jsx(Le,{className:"h-8 w-8 text-yellow-500"})}),r.jsx("h2",{className:"text-xl font-bold text-gray-900",children:n.heading}),r.jsxs("p",{className:"mt-1.5 text-sm text-gray-500",children:[r.jsxs("span",{className:"font-medium text-gray-700",children:[e,"%"]})," of"," ",r.jsx("span",{className:"font-medium text-gray-700",children:t})," ",e===100?"completed":"done","."," ",n.body]}),r.jsxs("div",{className:"mt-5 flex w-full flex-col gap-2",children:[r.jsxs(K,{to:"/account/road-card",className:"flex items-center justify-center gap-2 rounded-lg bg-yellow-400 px-4 py-2.5 text-sm font-semibold text-black transition-colors hover:bg-yellow-500",onClick:o,children:[r.jsx(Be,{className:"h-4 w-4"}),"Share your Road Card"]}),r.jsx("button",{className:"rounded-lg px-4 py-2.5 text-sm font-medium text-gray-500 transition-colors hover:text-gray-900",onClick:o,children:"Keep Learning"})]})]})}),i&&r.jsx(ht,{pieces:e===100?500:200,onDone:()=>s(!1)})]}):null}const X=[25,50,75,100];function gt(a,e){for(let t=X.length-1;t>=0;t--){const o=X[t];if(a<o&&e>=o)return o}return null}function ie(a,e){return`milestone-${a}-${e}`}function wt(a,e){try{return localStorage.getItem(ie(a,e))==="1"}catch{return!1}}function vt(a,e){try{localStorage.setItem(ie(a,e),"1")}catch{}}const J="Mark any topic to start tracking";function yt(a){const{progressPercentage:e,doneCount:t,totalCount:o,onDismiss:i,onClick:s}=a;return r.jsxs("div",{className:"flex items-center rounded-full bg-stone-900 shadow-lg",children:[r.jsxs("button",{className:"flex cursor-pointer items-center gap-2.5 rounded-l-full py-2 pr-3 pl-3 transition-colors hover:bg-white/10",onClick:s,children:[r.jsxs("span",{className:"shrink-0 text-xs font-semibold text-white tabular-nums",children:[e,"%"]}),r.jsx("div",{className:"h-2 w-28 overflow-hidden rounded-full bg-white/20 sm:w-36",children:r.jsx("div",{className:"h-full rounded-full bg-yellow-400 transition-all duration-500",style:{width:`${e}%`}})}),r.jsxs("span",{className:"shrink-0 text-xs text-gray-400 tabular-nums",children:[t," of ",o," done"]})]}),r.jsx(oe,{onDismiss:i})]})}function jt(a){const{label:e,onDismiss:t,onClick:o}=a;return r.jsxs("div",{className:"flex items-center rounded-full bg-gray-900 shadow-lg",children:[r.jsxs("button",{className:"flex cursor-pointer items-center gap-1.5 rounded-l-full py-2 pr-3 pl-3 text-xs text-gray-300 transition-colors hover:bg-white/10",onClick:o,children:[r.jsx(re,{className:"size-3.5 shrink-0 stroke-[2px] text-yellow-400"}),r.jsx("span",{children:e})]}),r.jsx(oe,{onDismiss:t})]})}function oe(a){const{onDismiss:e}=a;return r.jsx("button",{className:"flex cursor-pointer items-center justify-center self-stretch rounded-r-full pr-3 pl-2 text-gray-500 transition-colors hover:bg-white/10 hover:text-gray-300",onClick:e,children:r.jsx(Ve,{className:"size-3.5"})})}
1function bt(a){return`${a.toLocaleString()}+`}function Nt(a){const{trackerCount:e,onSignUp:t,hasQuestion:o}=a;return r.jsxs("button",{className:C("flex flex-1 cursor-pointer items-center justify-between gap-2 rounded-t-md bg-yellow-50 px-3 text-xs outline-none hover:bg-yellow-100",{"rounded-t-md":o,"rounded-md":!o}),onClick:t,children:[r.jsxs("div",{className:"flex items-center gap-1.5 text-yellow-800",children:[r.jsx(ze,{className:"size-3.5 shrink-0 stroke-[2px]"}),e>=100?r.jsxs("span",{children:["Join"," ",r.jsx("span",{className:"font-semibold",children:bt(e)})," ",r.jsx("span",{className:"hidden sm:inline",children:"others tracking their progress on this roadmap"}),r.jsx("span",{className:"sm:hidden",children:"tracking this roadmap"})]}):r.jsx("span",{children:"Sign up to track your learning progress"})]}),r.jsx("span",{className:"shrink-0 rounded-full bg-gray-900 px-3 py-1 text-[11px] font-medium text-white hover:bg-gray-800",children:"Sign up free"})]})}function kt(a){const{resourceId:e,resourceType:t,resourceTitle:o,hasQuestion:i}=a,s=De(),[n]=xe(),[c]=Z(),m=c.get("r")||e,h=Oe(),[u,x]=d.useState(!1),[y,w]=d.useState(!1),[j,v]=d.useState(()=>{if(typeof window>"u")return!1;try{return sessionStorage.getItem(`sticky-dismissed-${m}`)==="1"}catch{return!1}}),[f,p]=d.useState(null),{data:b,isLoading:ne}=W(Pe(t,m)),{data:ae,isLoading:ce}=W(Se(t,m)),D=b?.done?.length??0,le=b?.learning?.length??0,L=b?.skipped?.length??0+(n==="personalized"?b?.personalized?.topicIds?.length??0:0),I=b?.totalTopicCount??0,B=D+L,M=Re(B,I),$=d.useRef(null);d.useEffect(()=>{if(!s?.id||I===0)return;const P=$.current;if($.current=M,P===null)return;const N=gt(P,M);N&&!wt(m,N)&&p(N)},[M,I,s?.id,m]);const Q=ne||ce||!h,U=d.useRef(null),[me,pe]=d.useState(!1);d.useEffect(()=>{const P=U.current;if(!P)return;const N=new IntersectionObserver(([he])=>{pe(!he.isIntersecting)},{threshold:0});return N.observe(P),()=>N.disconnect()},[]);const q=I>0&&B>0,ue=!!s?.id,de=me&&!Q&&!j&&I>0;function z(){v(!0);try{sessionStorage.setItem(`sticky-dismissed-${m}`,"1")}catch{}}return r.jsxs(r.Fragment,{children:[f&&r.jsx(xt,{milestone:f,resourceTitle:o||m,onClose:()=>{vt(m,f),p(null)}}),u&&r.jsx(Te,{videoId:"D1llnW29dWE",title:"How to use roadmap.sh for Learning",description:"A quick walkthrough of how to follow a roadmap and track your progress.",onClose:()=>x(!1)}),y&&r.jsx($e,{progressPercentage:M,doneCount:D,learningCount:le,skippedCount:L,totalCount:I,resourceId:m,resourceTitle:o,onClose:()=>w(!1)}),de&&r.jsx("div",{className:"fixed top-0 right-0 left-0 z-[91] flex justify-center py-2.5",children:q?r.jsx(yt,{progressPercentage:M,doneCount:D,totalCount:I,onDismiss:z,onClick:()=>w(!0)}):r.jsx(jt,{label:J,onDismiss:z,onClick:()=>x(!0)})}),r.jsx("div",{ref:U,className:"flex h-11 items-stretch overflow-hidden",children:Q?r.jsx("div",{className:"flex flex-1 items-center gap-1 rounded-md bg-white px-3",children:Array.from({length:4}).map((P,N)=>r.jsx("div",{className:"striped-loader h-7 flex-1 rounded-sm bg-gray-100"},N))}):q?r.jsxs("button",{className:C("flex flex-1 cursor-pointer items-center gap-1.5 bg-white px-3 outline-none",{"rounded-md":!i,"rounded-t-md":i}),onClick:()=>w(!0),children:[r.jsx("div",{className:"flex-1",children:r.jsx(Qe,{progressPercentage:M})}),r.jsx("span",{className:"flex h-6 w-8 shrink-0 items-center justify-center rounded-sm bg-gray-100 text-gray-400 hover:bg-gray-200 hover:text-black",children:r.jsx(Ue,{className:"size-4"})})]}):ue?r.jsxs("button",{className:C("flex flex-1 cursor-pointer items-center justify-between bg-yellow-50 px-3 text-xs outline-none hover:bg-yellow-100",{"rounded-md":!i,"rounded-t-md":i}),onClick:()=>x(!0),children:[r.jsxs("div",{className:"flex items-center gap-1.5 text-yellow-800",children:[r.jsx(re,{className:"size-3.5 shrink-0 stroke-[2px]"}),r.jsx("span",{children:J})]}),r.jsxs("div",{className:"flex shrink-0 items-center gap-1 text-yellow-600",children:[r.jsx(qe,{className:"size-3 fill-current"}),r.jsx("span",{children:"Watch demo"})]})]}):r.jsx(Nt,{trackerCount:ae?.count??0,onSignUp:()=>Fe(),hasQuestion:i})})]})}function Ct(a){const{question:e,answer:t}
1=a,[o,i]=d.useState(!1),s=d.useRef(null),n=d.useRef(null);return Ye(s,()=>{i(!1)}),r.jsxs("div",{className:C("relative block rounded-b-[5px] border-t bg-white text-sm font-medium hover:bg-gray-50 sm:block",{"rounded-0 -mx-4 sm:mx-0":o}),children:[r.jsxs("h2",{className:"z-50 flex cursor-pointer items-center px-2 py-2 text-sm font-medium select-none","aria-expanded":o?"true":"false",onClick:c=>{c.preventDefault(),i(!o)},children:[r.jsxs("span",{className:"flex grow items-center select-none",children:[r.jsx(H,{className:"mr-1.5 inline-block h-4 w-4",strokeWidth:2.5}),e]}),r.jsx("span",{className:"relative -top-px shrink-0 text-gray-400",children:r.jsx(ee,{className:"inline-block h-5 w-5"})})]}),o&&r.jsx("div",{className:"pointer-events-none fixed top-0 right-0 left-0 z-100 h-full bg-black/50"}),r.jsxs("div",{className:C("absolute top-0 right-0 left-0 z-100 mt-0 border bg-white",o?"rounded-0 block sm:rounded-md":"hidden"),ref:s,children:[o&&r.jsxs("h2",{className:"sticky top-0 flex cursor-pointer items-center rounded-t-md border-b bg-white px-[7px] py-[9px] text-base font-medium select-none",onClick:()=>{i(!1);const c=n.current,l=s.current;if(!c||!l)return;const m=c.getBoundingClientRect().top;window.scrollY>m&&l.scrollIntoView()},ref:n,children:[r.jsxs("span",{className:"flex grow items-center",children:[r.jsx(H,{className:"mr-2 inline-block h-4 w-4",strokeWidth:2.5}),e]}),r.jsx("span",{className:"relative -top-px shrink-0 text-gray-400",children:r.jsx(_e,{className:"inline-block h-5 w-5"})})]}),r.jsx("div",{className:"bg-gray-100 p-3 text-base [&>h2]:mt-5 [&>h2]:mb-2 [&>h2]:text-[17px] [&>h2]:font-medium [&>p]:mb-3 [&>p]:leading-relaxed [&>p]:font-normal [&>p]:text-gray-800 [&>p:last-child]:mb-0 [&>p>a]:font-semibold [&>p>a]:underline [&>p>a]:underline-offset-2 [&>ul>li]:mb-2 [&>ul>li]:font-normal",children:te(t,{tweetApiUrl:se})})]})]})}function It(a){const{pageUrl:e,description:t,resourceType:o,resourceId:i}=a,s=d.useRef(null),n=`https://twitter.com/intent/tweet?text=${t}&url=${e}`,c=`https://www.facebook.com/sharer/sharer.php?quote=${t}&u=${e}`,l=`https://news.ycombinator.com/submitlink?t=${t}&u=${e}`,m=`https://www.reddit.com/submit?title=${t}&url=${e}`,h=[{url:n,icon:r.jsx(We,{className:"size-[24px]"})},{url:c,icon:r.jsx(He,{className:"size-[26px]"})},{url:l,icon:r.jsx(Ge,{className:"size-[26px]"})},{url:m,icon:r.jsx(Xe,{className:"size-[26px]"})}];return d.useEffect(()=>{const u=s.current;if(!u)return;const x=()=>{if(window.scrollY<100||window.innerWidth<1050)return u.classList.add("hidden"),null;u.classList.remove("hidden")};return x(),window.addEventListener("scroll",x),()=>{window.removeEventListener("scroll",x)}},[]),i.startsWith("private-")?null:r.jsx("div",{className:"absolute top-[110px] left-[-18px] hidden h-full",ref:s,children:r.jsx("div",{className:"sticky top-[100px] flex flex-col items-center gap-1.5",children:h.map((u,x)=>{const y=new URL(u.url).host;return r.jsx("a",{href:u.url,target:"_blank",className:C("text-gray-500 hover:text-gray-700",x===0&&"mt-0.5"),onClick:()=>{Je({category:"RoadmapShareLink",action:`Share Roadmap / ${o} / ${i} / ${y}`,label:u.url})},children:u.icon},x)})})})}const _o=a=>{const e=a?.loaderData?.roadmap;if(!e)return V({title:"Not Found",description:"Not Found"});let t=[];const o=_.fromJSDate(new Date(e?.createdAt)).toFormat("yyyy-MM-dd"),i=_.fromJSDate(new Date(e?.updatedAt)).toFormat("yyyy-MM-dd"),s=e?.slug,n=S(e?.seo?.title||e?.title?.page),c=S(e?.description);t.push(Ce({url:`https://roadmap.sh/${s}`,headline:n,description:c,datePublished:o,dateModified:i,imageUrl:`${et.appUrl}/roadmaps/${s}.png`}));const l=ge(e?.openGraph?.image)||Ie({group:"roadmap",resourceId:s}),m=e?.questions?.filter(h=>h.type==="faq")||[];return m.length&&t.push(ke(m)),[...V({title:n,description:c,permalink:`/${s}`,ogImage:l,keywords:e?.seo?.keywords||void 0,jsonLd:t})]},Wo=()=>[Ke],Ho=fe(function(e){const{starCount:t,repoRank:o,discordInfo:i,roadmap:s,officialRoadmaps:n,projects:c}=e.loaderData,[l]=Z(),m=l.get("secret")||"",h=s?.questions?.find(p=>p.type==="main"),u=s?.questions?.filter(p=>p.type==="faq")||[],x=n.filter(p=>p.relatedRoadmaps?.includes(p.slug)).map(p=>
1({slug:p.slug,title:p.title,description:S(p.description)})),y=S(s.title.page),w=S(s.description),j=ye(s.createdAt),v=s.type==="best-practice",f=s.slug.startsWith("private-");return f&&m!=="l3tm31n@roadmapsh"?r.jsxs("div",{className:"flex min-h-screen flex-col",children:[r.jsx(Y,{}),r.jsxs("div",{className:"page-container flex max-w-2xl grow flex-col items-center justify-center text-center",children:[r.jsx("h1",{className:"mb-4 text-7xl font-bold",children:"🔒️"}),r.jsx("h1",{className:"mb-4 text-3xl font-semibold text-balance",children:"Private page!"}),r.jsx("p",{className:"text-balance text-gray-600",children:"You do not have access to view this roadmap. If you believe this is a mistake, please contact the roadmap owner."})]})]}):r.jsxs(r.Fragment,{children:[r.jsx(Y,{}),r.jsxs("main",{className:"bg-gray-50",children:[r.jsx(Me,{title:y,description:w,partner:s.partner,roadmapId:s.slug,isForkable:!0,isNew:j,hasFeedbackAlert:!f&&j,projectCount:c.length,coursesCount:s.courses?.length??0,hasAIChat:!0,canPersonalize:!v}),r.jsx("div",{className:"page-container mt-2.5",children:r.jsxs("div",{className:"rounded-md border bg-white",children:[r.jsx(kt,{resourceId:s.slug,resourceType:"roadmap",resourceTitle:y,hasQuestion:!!h?.title}),h?.title&&r.jsx(Ct,{question:h?.title,answer:h?.description})]})}),r.jsxs("div",{className:C("page-container relative max-w-[1000px]!",f&&"max-w-[1050px]! pb-7"),children:[r.jsx(It,{resourceId:s.slug,resourceType:"roadmap",pageUrl:`https://roadmap.sh/${s.slug}`,description:w}),r.jsx(je,{roadmapSlug:s.slug,dimensions:s.dimensions})]}),s.slug==="docker"&&r.jsx("div",{className:"pb-8 sm:pb-12",children:r.jsx("p",{className:"px-5 text-center text-xs text-gray-400",children:"Roadmap owner Insight Partners is an investor in Docker."})}),r.jsx(st,{faqs:u}),r.jsx(rt,{relatedRoadmaps:x})]}),r.jsx(Ze,{resourceId:s.slug,resourceType:"roadmap",renderer:"editor"}),r.jsx(we,{starCount:t,repoRank:o,discordInfo:i}),r.jsx(ve,{})]})});export{Jo as ErrorBoundary,Ho as default,Wo as links,_o as meta};

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