@epic-web/workshop-app 4.20.0 → 4.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/client/assets/{_-DYArYM0Z.js → _-Dfo2h4rl.js} +2 -2
- package/build/client/assets/{_-DYArYM0Z.js.map → _-Dfo2h4rl.js.map} +1 -1
- package/build/client/assets/{_exerciseNumber-BLQUCLPr.js → _exerciseNumber-CfKoF9W0.js} +2 -2
- package/build/client/assets/{_exerciseNumber-BLQUCLPr.js.map → _exerciseNumber-CfKoF9W0.js.map} +1 -1
- package/build/client/assets/{_exerciseNumber_._stepNumber-Ct5BCuA1.js → _exerciseNumber_._stepNumber-DpAxO0AM.js} +2 -2
- package/build/client/assets/{_exerciseNumber_._stepNumber-Ct5BCuA1.js.map → _exerciseNumber_._stepNumber-DpAxO0AM.js.map} +1 -1
- package/build/client/assets/{_exerciseNumber_.finished-C9TSc48F.js → _exerciseNumber_.finished-czQBjiVF.js} +2 -2
- package/build/client/assets/{_exerciseNumber_.finished-C9TSc48F.js.map → _exerciseNumber_.finished-czQBjiVF.js.map} +1 -1
- package/build/client/assets/{_layout-DLIzcS5v.js → _layout-BUs3av-e.js} +2 -2
- package/build/client/assets/{_layout-DLIzcS5v.js.map → _layout-BUs3av-e.js.map} +1 -1
- package/build/client/assets/{_layout-CZ3fjUvs.js → _layout-BrGbNrqb.js} +2 -2
- package/build/client/assets/{_layout-CZ3fjUvs.js.map → _layout-BrGbNrqb.js.map} +1 -1
- package/build/client/assets/{_layout-DhP5RhPk.js → _layout-DBCEqk3b.js} +2 -2
- package/build/client/assets/{_layout-DhP5RhPk.js.map → _layout-DBCEqk3b.js.map} +1 -1
- package/build/client/assets/_layout-IOROGN78.js +6 -0
- package/build/client/assets/_layout-IOROGN78.js.map +1 -0
- package/build/client/assets/{account-LnI_Eq0t.js → account-CQNVYlpT.js} +2 -2
- package/build/client/assets/{account-LnI_Eq0t.js.map → account-CQNVYlpT.js.map} +1 -1
- package/build/client/assets/{button-BA3iiLRs.js → button-DcWUKEqR.js} +2 -2
- package/build/client/assets/{button-BA3iiLRs.js.map → button-DcWUKEqR.js.map} +1 -1
- package/build/client/assets/{client-hints-DLYDs4RF.js → client-hints-DWL_Mq1C.js} +2 -2
- package/build/client/assets/{client-hints-DLYDs4RF.js.map → client-hints-DWL_Mq1C.js.map} +1 -1
- package/build/client/assets/{components-wgHiPsTg.js → components-C17zb3Us.js} +2 -2
- package/build/client/assets/{components-wgHiPsTg.js.map → components-C17zb3Us.js.map} +1 -1
- package/build/client/assets/{diff-4FQLirNf.js → diff-CCCucBoq.js} +2 -2
- package/build/client/assets/{diff-4FQLirNf.js.map → diff-CCCucBoq.js.map} +1 -1
- package/build/client/assets/diff-DBQZWFaQ.js +2 -0
- package/build/client/assets/{diff-CPrD1rHd.js.map → diff-DBQZWFaQ.js.map} +1 -1
- package/build/client/assets/{discord-BgaWmFRC.js → discord-CBGQw7I4.js} +2 -2
- package/build/client/assets/{discord-BgaWmFRC.js.map → discord-CBGQw7I4.js.map} +1 -1
- package/build/client/assets/discord-CULpXzAC.js +2 -0
- package/build/client/assets/discord-CULpXzAC.js.map +1 -0
- package/build/client/assets/{entry.client-Cs8lBz8l.js → entry.client-C1yl0iQe.js} +2 -2
- package/build/client/assets/{entry.client-Cs8lBz8l.js.map → entry.client-C1yl0iQe.js.map} +1 -1
- package/build/client/assets/{epic-video-CfelX9-n.js → epic-video-DGVKtAan.js} +2 -2
- package/build/client/assets/{epic-video-CfelX9-n.js.map → epic-video-DGVKtAan.js.map} +1 -1
- package/build/client/assets/{error-boundary-BVTbN8PZ.js → error-boundary-yAXgvsPR.js} +2 -2
- package/build/client/assets/{error-boundary-BVTbN8PZ.js.map → error-boundary-yAXgvsPR.js.map} +1 -1
- package/build/client/assets/{finished-C0mN8TiU.js → finished-DQ70NSmN.js} +2 -2
- package/build/client/assets/{finished-C0mN8TiU.js.map → finished-DQ70NSmN.js.map} +1 -1
- package/build/client/assets/{index-Czg1ruVn.js → index-1cKOJFpX.js} +2 -2
- package/build/client/assets/{index-Czg1ruVn.js.map → index-1cKOJFpX.js.map} +1 -1
- package/build/client/assets/{index-DjzedX4O.js → index-B9w5akmN.js} +2 -2
- package/build/client/assets/{index-DjzedX4O.js.map → index-B9w5akmN.js.map} +1 -1
- package/build/client/assets/{index-C6ToujzV.js → index-DC4pM5aW.js} +2 -2
- package/build/client/assets/{index-C6ToujzV.js.map → index-DC4pM5aW.js.map} +1 -1
- package/build/client/assets/{index-yEAxvbDV.js → index-Dc-1lfub.js} +2 -2
- package/build/client/assets/{index-yEAxvbDV.js.map → index-Dc-1lfub.js.map} +1 -1
- package/build/client/assets/{index-D6ukHE4T.js → index-Dx5GmdYq.js} +2 -2
- package/build/client/assets/{index-D6ukHE4T.js.map → index-Dx5GmdYq.js.map} +1 -1
- package/build/client/assets/{index-De7yI02n.js → index-yQg0GLtS.js} +2 -2
- package/build/client/assets/{index-De7yI02n.js.map → index-yQg0GLtS.js.map} +1 -1
- package/build/client/assets/{loading-B0uKxERz.js → loading-C4Cc1EBG.js} +2 -2
- package/build/client/assets/{loading-B0uKxERz.js.map → loading-C4Cc1EBG.js.map} +1 -1
- package/build/client/assets/{login-SJlLMYmL.js → login-Bimq6Ilz.js} +2 -2
- package/build/client/assets/{login-SJlLMYmL.js.map → login-Bimq6Ilz.js.map} +1 -1
- package/build/client/assets/manifest-8371b608.js +1 -0
- package/build/client/assets/{mdx-CQW0I4So.js → mdx-Cb7iYGhg.js} +2 -2
- package/build/client/assets/{mdx-CQW0I4So.js.map → mdx-Cb7iYGhg.js.map} +1 -1
- package/build/client/assets/{misc-S5ZD98sI.js → misc-Bt-_bj1O.js} +2 -2
- package/build/client/assets/{misc-S5ZD98sI.js.map → misc-Bt-_bj1O.js.map} +1 -1
- package/build/client/assets/{nav-chevrons-DaXg0NPS.js → nav-chevrons-DIhkJv4W.js} +2 -2
- package/build/client/assets/{nav-chevrons-DaXg0NPS.js.map → nav-chevrons-DIhkJv4W.js.map} +1 -1
- package/build/client/assets/{onboarding-BXGyEPXy.js → onboarding-CU7IWhDE.js} +2 -2
- package/build/client/assets/{onboarding-BXGyEPXy.js.map → onboarding-CU7IWhDE.js.map} +1 -1
- package/build/client/assets/{presence-CW1_eiIo.js → presence-DgSzsRAv.js} +2 -2
- package/build/client/assets/{presence-CW1_eiIo.js.map → presence-DgSzsRAv.js.map} +1 -1
- package/build/client/assets/{progress-BwanvUpB.js → progress-C1WSMZl4.js} +2 -2
- package/build/client/assets/{progress-BwanvUpB.js.map → progress-C1WSMZl4.js.map} +1 -1
- package/build/client/assets/{progress-bar-wMXWRGq0.js → progress-bar-DMef_aq8.js} +2 -2
- package/build/client/assets/{progress-bar-wMXWRGq0.js.map → progress-bar-DMef_aq8.js.map} +1 -1
- package/build/client/assets/{request-info-DHtGM4FI.js → request-info-DU15ezmn.js} +2 -2
- package/build/client/assets/{request-info-DHtGM4FI.js.map → request-info-DU15ezmn.js.map} +1 -1
- package/build/client/assets/{root-BUqeXmeK.js → root-CX2PgcP9.js} +3 -3
- package/build/client/assets/root-CX2PgcP9.js.map +1 -0
- package/build/client/assets/{support-DilzTPHE.js → support-D6UIcaNu.js} +2 -2
- package/build/client/assets/{support-DilzTPHE.js.map → support-D6UIcaNu.js.map} +1 -1
- package/build/client/assets/{tooltip-BtzSIxlB.js → tooltip-Cqh5cQvd.js} +2 -2
- package/build/client/assets/{tooltip-BtzSIxlB.js.map → tooltip-Cqh5cQvd.js.map} +1 -1
- package/build/client/assets/{use-event-source-ySol3hbz.js → use-event-source-A_0lEOPX.js} +2 -2
- package/build/client/assets/{use-event-source-ySol3hbz.js.map → use-event-source-A_0lEOPX.js.map} +1 -1
- package/build/client/assets/use-hydrated-Citou692.js +2 -0
- package/build/client/assets/use-hydrated-Citou692.js.map +1 -0
- package/build/client/assets/{user-CdUDQ7a8.js → user-MNzkRgJ3.js} +2 -2
- package/build/client/assets/{user-CdUDQ7a8.js.map → user-MNzkRgJ3.js.map} +1 -1
- package/build/server/index.js +20 -16
- package/build/server/index.js.map +1 -1
- package/package.json +3 -3
- package/build/client/assets/_layout-B789acDk.js +0 -6
- package/build/client/assets/_layout-B789acDk.js.map +0 -1
- package/build/client/assets/diff-CPrD1rHd.js +0 -2
- package/build/client/assets/discord-Dk1wbXOn.js +0 -2
- package/build/client/assets/discord-Dk1wbXOn.js.map +0 -1
- package/build/client/assets/manifest-73106676.js +0 -1
- package/build/client/assets/root-BUqeXmeK.js.map +0 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{r as d,j as e,O as We,b as ne}from"./index-1cKOJFpX.js";import{c as b}from"./clsx-B-dksMZM.js";import{u as Fe}from"./use-hydrated-Citou692.js";import{c as m,I as v}from"./misc-Bt-_bj1O.js";import{c as Oe,u as z,P as I,a as k,b as U,d as Ve,D as He,e as ze,f as Ue,g as F,S,T as Ye,h as K,i as q,j as Z}from"./tooltip-Cqh5cQvd.js";import{R as Be,h as Ge,u as Me,F as Qe,P as Je}from"./index-DC4pM5aW.js";import{b as A}from"./user-MNzkRgJ3.js";import{a as Y}from"./presence-DgSzsRAv.js";import{b as Ke,s as ae,c as qe,d as Ze,e as se,m as x,u as Xe,f as et}from"./progress-C1WSMZl4.js";import{T as re}from"./index-Dc-1lfub.js";import{L as f,u as oe,N as T}from"./components-C17zb3Us.js";import"./request-info-DU15ezmn.js";import"./client-hints-DWL_Mq1C.js";function tt(t){t.values.forEach(n=>n.stop())}function V(t,n){[...n].reverse().forEach(s=>{const o=t.getVariant(s);o&&ae(t,o),t.variantChildren&&t.variantChildren.forEach(r=>{V(r,n)})})}function nt(t,n){if(Array.isArray(n))return V(t,n);if(typeof n=="string")return V(t,[n]);ae(t,n)}function at(){const t=new Set,n={subscribe(a){return t.add(a),()=>void t.delete(a)},start(a,s){const o=[];return t.forEach(r=>{o.push(Ke(r,a,{transitionOverride:s}))}),Promise.all(o)},set(a){return t.forEach(s=>{nt(s,a)})},stop(){t.forEach(a=>{tt(a)})},mount(){return()=>{n.stop()}}};return n}function H(){const t=qe(at);return Ze(t.mount,[]),t}function st(t,n){function a(){return window.matchMedia(t).matches}function s(o){const r=window.matchMedia(t);return r.addEventListener("change",o),()=>{r.removeEventListener("change",o)}}return function(){return d.useSyncExternalStore(s,a,()=>n)}}var B="Dialog",[ie,Ft]=Oe(B),[rt,j]=ie(B),le=t=>{const{__scopeDialog:n,children:a,open:s,defaultOpen:o,onOpenChange:r,modal:c=!0}=t,i=d.useRef(null),l=d.useRef(null),[p=!1,h]=Ue({prop:s,defaultProp:o,onChange:r});return e.jsx(rt,{scope:n,triggerRef:i,contentRef:l,contentId:F(),titleId:F(),descriptionId:F(),open:p,onOpenChange:h,onOpenToggle:d.useCallback(()=>h(g=>!g),[h]),modal:c,children:a})};le.displayName=B;var ce="DialogTrigger",de=d.forwardRef((t,n)=>{const{__scopeDialog:a,...s}=t,o=j(ce,a),r=z(n,o.triggerRef);return e.jsx(I.button,{type:"button","aria-haspopup":"dialog","aria-expanded":o.open,"aria-controls":o.contentId,"data-state":Q(o.open),...s,ref:r,onClick:k(t.onClick,o.onOpenToggle)})});de.displayName=ce;var G="DialogPortal",[ot,ue]=ie(G,{forceMount:void 0}),fe=t=>{const{__scopeDialog:n,forceMount:a,children:s,container:o}=t,r=j(G,n);return e.jsx(ot,{scope:n,forceMount:a,children:d.Children.map(s,c=>e.jsx(U,{present:a||r.open,children:e.jsx(Je,{asChild:!0,container:o,children:c})}))})};fe.displayName=G;var $="DialogOverlay",he=d.forwardRef((t,n)=>{const a=ue($,t.__scopeDialog),{forceMount:s=a.forceMount,...o}=t,r=j($,t.__scopeDialog);return r.modal?e.jsx(U,{present:s||r.open,children:e.jsx(it,{...o,ref:n})}):null});he.displayName=$;var it=d.forwardRef((t,n)=>{const{__scopeDialog:a,...s}=t,o=j($,a);return e.jsx(Be,{as:Ve,allowPinchZoom:!0,shards:[o.contentRef],children:e.jsx(I.div,{"data-state":Q(o.open),...s,ref:n,style:{pointerEvents:"auto",...s.style}})})}),y="DialogContent",me=d.forwardRef((t,n)=>{const a=ue(y,t.__scopeDialog),{forceMount:s=a.forceMount,...o}=t,r=j(y,t.__scopeDialog);return e.jsx(U,{present:s||r.open,children:r.modal?e.jsx(lt,{...o,ref:n}):e.jsx(ct,{...o,ref:n})})});me.displayName=y;var lt=d.forwardRef((t,n)=>{const a=j(y,t.__scopeDialog),s=d.useRef(null),o=z(n,a.contentRef,s);return d.useEffect(()=>{const r=s.current;if(r)return Ge(r)},[]),e.jsx(pe,{...t,ref:o,trapFocus:a.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:k(t.onCloseAutoFocus,r=>{var c;r.preventDefault(),(c=a.triggerRef.current)==null||c.focus()}),onPointerDownOutside:k(t.onPointerDownOutside,r=>{const c=r.detail.originalEvent,i=c.button===0&&c.ctrlKey===!0;(c.button===2||i)&&r.preventDefault()}),onFocusOutside:k(t.onFocusOutside,r=>r.preventDefault())})}),ct=d.forwardRef((t,n)=>{const a=j(y,t.__scopeDialog),s=d.useRef(!1),o=d.useRef(!1);return e.jsx(pe,{...t,ref:n,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:r=>{var c,i;(c=t.onCloseAutoFocus)==null||c.call(t,r),r.defaultPrevented||(s.current||(i=a.triggerRef.current)==null||i.focus(),r.preventDefault()),s.current=!1,o.current=!1},onInteractOutside:r=>{var l,p;(l=t.onInteractOutside)==null||l.call(t,r),r.defaultPrevented||(s.current=!0,r.detail.originalEvent.type==="pointerdown"&&(o.current=!0));const c=r.target;((p=a.triggerRef.current)==null?void 0:p.contains(c))&&r.preventDefault(),r.detail.originalEvent.type==="focusin"&&o.current&&r.preventDefault()}})}),pe=d.forwardRef((t,n)=>{const{__scopeDialog:a,trapFocus:s,onOpenAutoFocus:o,onCloseAutoFocus:r,...c}=t,i=j(y,a),l=d.useRef(null),p=z(n,l);return Me(),e.jsxs(e.Fragment,{children:[e.jsx(Qe,{asChild:!0,loop:!0,trapped:s,onMountAutoFocus:o,onUnmountAutoFocus:r,children:e.jsx(He,{role:"dialog",id:i.contentId,"aria-describedby":i.descriptionId,"aria-labelledby":i.titleId,"data-state":Q(i.open),...c,ref:p,onDismiss:()=>i.onOpenChange(!1)})}),e.jsxs(e.Fragment,{children:[e.jsx(dt,{titleId:i.titleId}),e.jsx(ft,{contentRef:l,descriptionId:i.descriptionId})]})]})}),M="DialogTitle",xe=d.forwardRef((t,n)=>{const{__scopeDialog:a,...s}=t,o=j(M,a);return e.jsx(I.h2,{id:o.titleId,...s,ref:n})});xe.displayName=M;var ge="DialogDescription",be=d.forwardRef((t,n)=>{const{__scopeDialog:a,...s}=t,o=j(ge,a);return e.jsx(I.p,{id:o.descriptionId,...s,ref:n})});be.displayName=ge;var ve="DialogClose",je=d.forwardRef((t,n)=>{const{__scopeDialog:a,...s}=t,o=j(ve,a);return e.jsx(I.button,{type:"button",...s,ref:n,onClick:k(t.onClick,()=>o.onOpenChange(!1))})});je.displayName=ve;function Q(t){return t?"open":"closed"}var we="DialogTitleWarning",[Ot,Ne]=ze(we,{contentName:y,titleName:M,docsSlug:"dialog"}),dt=({titleId:t})=>{const n=Ne(we),a=`\`${n.contentName}\` requires a \`${n.titleName}\` for the component to be accessible for screen reader users.
|
|
2
|
+
|
|
3
|
+
If you want to hide the \`${n.titleName}\`, you can wrap it with our VisuallyHidden component.
|
|
4
|
+
|
|
5
|
+
For more information, see https://radix-ui.com/primitives/docs/components/${n.docsSlug}`;return d.useEffect(()=>{t&&(document.getElementById(t)||console.error(a))},[a,t]),null},ut="DialogDescriptionWarning",ft=({contentRef:t,descriptionId:n})=>{const s=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${Ne(ut).contentName}}.`;return d.useEffect(()=>{var r;const o=(r=t.current)==null?void 0:r.getAttribute("aria-describedby");n&&o&&(document.getElementById(n)||console.warn(s))},[s,t,n]),null},ht=le,mt=de,pt=fe,ye=he,Ee=me,xt=xe,De=be,gt=je;const bt=ht,vt=mt,jt=pt;function Ce({className:t,ref:n,...a}){return e.jsx(ye,{ref:n,className:m("fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...a})}Ce.displayName=ye.displayName;function Pe({className:t,children:n,ref:a,...s}){return e.jsxs(jt,{children:[e.jsx(Ce,{}),e.jsxs(Ee,{ref:a,className:m("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",t),...s,children:[n,e.jsxs(gt,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none",children:[e.jsx(v,{name:"Close"}),e.jsx("span",{className:"sr-only",children:"Close"})]})]})]})}Pe.displayName=Ee.displayName;function _e({className:t,...n}){return e.jsx("div",{className:m("flex flex-col space-y-1.5 text-center sm:text-left",t),...n})}_e.displayName="DialogHeader";xt.displayName;function ke({className:t,ref:n,...a}){return e.jsx(De,{ref:n,className:m("text-sm text-muted-foreground",t),...a})}ke.displayName=De.displayName;const X=["opacity-70","opacity-80","opacity-90","opacity-100"],ee=["shadow-[0_0_2px_0_rgba(0,0,0,0.3)]","shadow-[0_0_4px_0_rgba(0,0,0,0.3)]","shadow-[0_0_7px_0_rgba(0,0,0,0.3)]","shadow-[0_0_10px_0_rgba(0,0,0,0.3)]"];function te(t){const n=Math.round(t*X.length-1),a=Math.round(t*ee.length-1);return m("shadow-purple-700 hover:opacity-100 focus:opacity-100 dark:shadow-purple-200",X[n]??"opacity-60",ee[a]??"shadow-none",t===1?"animate-pulse hover:animate-none focus:animate-none":null)}function Ie({isMenuOpened:t}){const n=A(),{users:a}=Y(),s=t?17:0,o=a.length-s;if(!a.length)return null;const r=t&&a.length===1?e.jsx(f,{target:"_blank",rel:"noopener noreferrer",to:"https://www.youtube.com/watch?v=w6Q3mHyzn78",children:e.jsx("img",{alt:"Tiffany Tunes",className:m("h-8 w-8 rounded-full border object-cover",te(1)),src:"/img/tiffany.png"})}):null,c=`${o}${t?" more ":" "}Epic Web Dev${o===1?"":"s"} working now`;return e.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.jsxs(Ye,{children:[a.slice(0,s).map(({user:i,score:l})=>{var g,w;const p=te(l),h=wt(i.location);return e.jsxs(K,{children:[e.jsx(q,{asChild:!0,children:i.avatarUrl?e.jsx("img",{tabIndex:0,alt:i.name||"Epic Web Dev",className:m("h-8 w-8 rounded-full border object-cover",p),src:i.avatarUrl}):e.jsx("div",{tabIndex:0,"aria-label":i.name||"Epic Web Dev",className:m("flex h-8 w-8 items-center justify-center rounded-full border",p),children:e.jsx(v,{name:"User"})})}),e.jsx(Z,{children:e.jsxs("span",{className:"flex flex-col items-center justify-center gap-1",children:[e.jsxs("span",{children:[i.name||"An EPIC Web Dev"," ",h?` is ${(w=(g=i.location)==null?void 0:g.origin)!=null&&w.includes("epicweb.dev")?"learning":"working"} ${l===1&&(n==null?void 0:n.id)!==i.id?"with you":""} on`:null]}),h!=null&&h.line1?e.jsx("span",{children:h.line1}):null,h!=null&&h.line2?e.jsx("span",{children:h.line2}):null]})})]},i.id)}),r,o>0?e.jsxs(K,{children:[e.jsx(q,{asChild:!0,children:e.jsx("div",{tabIndex:0,"aria-label":c,className:m("flex items-center justify-center rounded-full border bg-accent text-xs text-accent-foreground",t?"h-8 w-8":"h-6 w-6"),children:e.jsx("span",{className:m("pointer-events-none overflow-hidden text-ellipsis whitespace-nowrap text-center",t?"w-8":"w-6"),children:t?`+${o}`:o})})}),e.jsx(Z,{children:c})]}):null]})})}const Re=st("(min-width: 640px)",!0);function Vt(){const t=A(),n=Re(),a=Fe(),[s,o]=d.useState(!1);return e.jsxs("div",{className:"flex flex-col",children:[t?null:e.jsx(Nt,{}),a&&n?null:e.jsx(yt,{isMenuOpened:s,onMenuOpenChange:o}),e.jsxs("div",{className:m("flex flex-grow flex-col sm:flex-row",{"h-[calc(100vh-128px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))]":!t,"h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))]":t,"h-[unset]":!n&&s}),children:[n?e.jsx(Et,{isMenuOpened:s,onMenuOpenChange:o}):null,e.jsx("div",{className:m("h-full w-full max-w-full sm:max-w-[calc(100%-56px)]",s?"hidden md:block":""),children:e.jsx(We,{})})]})]})}function wt(t){if(!t)return null;const{exercise:n}=t,a=[n?[n.exerciseNumber,n.stepNumber].filter(Boolean).map(s=>s.toString().padStart(2,"0")).join("/"):null,n==null?void 0:n.type].filter(Boolean).join(" - ");return{line1:t.workshopTitle,line2:a}}function Nt(){const t=Re(),n=e.jsx("div",{children:ENV.EPICSHOP_DEPLOYED?e.jsxs("div",{children:["This is the deployed version. ",e.jsxs(e.Fragment,{children:[e.jsx(f,{className:"underline",target:"_blank",rel:"noopener noreferrer",to:ENV.EPICSHOP_GITHUB_REPO,children:"Run locally"})," for full experience."]})," "]}):e.jsxs("div",{children:[e.jsx(f,{to:"/login",className:"underline",children:"Login"})," ","or"," ",e.jsx("a",{href:"https://www.epicweb.dev/login",className:"underline",children:"join for free"})," ","for the full experience."]})});return e.jsx("div",{className:"z-10 flex h-16 items-center justify-between border-b bg-gradient-to-tr from-blue-500 to-indigo-500 pl-4 text-white",children:t?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"hidden flex-1 flex-wrap items-center gap-4 sm:flex",children:[e.jsx(v,{name:"EpicWeb",size:"lg"}),e.jsxs("div",{className:"flex flex-1 flex-wrap items-center",children:[e.jsxs("p",{className:"mr-2",children:["Welcome to the"," ",e.jsx(f,{to:"https://www.epicweb.dev",className:"underline",target:"_blank",children:"EpicWeb.dev"})," ","Workshop app!"]}),n]})]}),e.jsxs("div",{className:"hidden h-full flex-col items-center sm:flex md:flex-row",children:[e.jsxs(f,{to:"https://www.epicweb.dev",target:"_blank",className:"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold",children:[e.jsx("span",{className:"drop-shadow-sm",children:"Join Epic Web"}),e.jsx("span",{children:"↗︎"})]}),e.jsxs(f,{to:ENV.EPICSHOP_DEPLOYED?"https://www.epicweb.dev/login":"/login",className:"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30",children:[e.jsx(v,{name:"User",size:"lg"}),e.jsx("span",{className:"drop-shadow-sm",children:"Login"})]})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-1 flex-wrap items-center gap-4 sm:hidden",children:[e.jsx("a",{href:"https://www.epicweb.dev",children:e.jsx(v,{name:"EpicWeb",size:"lg"})}),e.jsxs(bt,{children:[e.jsx(vt,{children:e.jsx(v,{name:"Question",size:"lg",className:"animate-pulse"})}),e.jsxs(Pe,{children:[e.jsxs(_e,{children:[e.jsx(v,{name:"EpicWeb",size:"lg"}),e.jsx("span",{className:"text-lg font-semibold",children:"EpicWeb.dev"})]}),e.jsxs(ke,{children:["Welcome to the"," ",e.jsx(f,{to:"https://www.epicweb.dev",className:"underline",children:"EpicWeb.dev"})," ","Workshop app!"]}),n]})]})]}),e.jsxs("div",{className:"flex h-full items-center",children:[e.jsxs(f,{to:"https://www.epicweb.dev",target:"_blank",className:"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold",children:[e.jsx("span",{className:"drop-shadow-sm",children:"Join"}),e.jsx("span",{children:"↗︎"})]}),e.jsxs(f,{to:ENV.EPICSHOP_DEPLOYED?"https://www.epicweb.dev/login":"/login",className:"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30",children:[e.jsx(v,{name:"User",size:"lg"}),e.jsx("span",{className:"drop-shadow-sm",children:"Login"})]})]})]})})}const Se={hidden:{opacity:0,x:-20},visible:{opacity:1,x:0}};function Te({exerciseNumber:t,children:n}){const a=Xe(t);return e.jsx(x.li,{variants:Se,className:m("py-[6px] first:pt-3 last:pb-3",a?`${a} before:border-t`:null),children:e.jsx("span",{className:"ml-2",children:n})})}function C({children:t,...n}){const a=et(n);return e.jsx(x.li,{variants:Se,className:m("py-[6px] first:pt-3 last:pb-3",a?`${a} before:border-t`:null),children:e.jsx("span",{className:"ml-2",children:t})})}function yt({isMenuOpened:t,onMenuOpenChange:n}){const a=oe(),s=A(),o=se(),r=ne(),{users:c}=Y(),i={visible:{opacity:1,transition:{duration:.05,when:"beforeChildren",staggerChildren:.03}},hidden:{opacity:0}};return e.jsx("nav",{className:"flex w-full border-b sm:hidden",children:e.jsx("div",{className:"w-full",children:e.jsxs("div",{className:m("flex items-center",{"flex-col":t,"h-14":!t}),children:[e.jsx($e,{title:a.workshopTitle,isMenuOpened:t,setMenuOpened:n}),t&&e.jsxs(x.div,{className:"flex w-full flex-grow flex-col justify-between overflow-x-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar",initial:{opacity:0},animate:{opacity:1},children:[e.jsx(x.ul,{variants:i,initial:"hidden",animate:"visible",className:"flex flex-col",children:a.exercises.map(({exerciseNumber:l,title:p,steps:h})=>{const g=Number(r.exerciseNumber)===l,w=!g&&a.playground.exerciseNumber===l,u=l.toString().padStart(2,"0");return e.jsxs(Te,{exerciseNumber:l,children:[e.jsxs(f,{prefetch:"intent",to:`/${u}`,className:b("relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline",'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":g}),children:[p,w?" 🛝":null]}),g?e.jsxs(x.ul,{variants:i,initial:"hidden",animate:"visible",className:"ml-4 mt-4 flex flex-col",children:[e.jsx(C,{type:"instructions",exerciseNumber:l,children:e.jsx(f,{to:`/${u}`,prefetch:"intent",className:b('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":!r.stepNumber}),children:"Intro"})},l),h.filter(Boolean).map(({name:P,stepNumber:E,title:D})=>{const L=Number(r.stepNumber)===E,N=E.toString().padStart(2,"0"),_=P===a.playground.appName;return e.jsx(C,{type:"step",stepNumber:E,exerciseNumber:l,children:e.jsx(f,{to:`/${u}/${N}`,prefetch:"intent",className:b('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":L}),children:_?`${N}. ${D} 🛝`:`${N}. ${D}`})},E)}),e.jsx(C,{type:"finished",exerciseNumber:l,children:e.jsx(T,{to:`/${u}/finished`,prefetch:"intent",className:({isActive:P})=>b('relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":P}),children:"📝 Elaboration"})})]}):null]},l)})}),e.jsx("div",{className:"mt-6",children:e.jsx(T,{to:"/finished",className:({isActive:l})=>b("relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline",{'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""]':l}),children:"📝 Workshop Feedback"})})]}),e.jsx("div",{className:"flex-grow"}),e.jsx("div",{className:m("flex items-center justify-start p-4",t&&c.length>4?"min-h-14":"h-14",{"w-full border-t":t}),children:e.jsx(Ie,{isMenuOpened:t})}),ENV.EPICSHOP_DEPLOYED?null:s?e.jsx(S,{content:t?null:"Your account",children:e.jsxs(f,{className:m("flex h-14 flex-shrink-0 items-center justify-start space-x-3 px-4 py-4 text-center no-underline hover:underline",{"border-l":!t,"w-full border-t":t}),to:"/account",children:[s.avatarUrl?e.jsx("img",{alt:s.name??s.email,src:s.avatarUrl,className:"h-full rounded-full"}):e.jsx(v,{name:"User",className:"flex-shrink-0",size:"lg"}),t?e.jsx(x.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Your Account"}):e.jsx("span",{className:"sr-only",children:"Your account"})]})}):null,ENV.EPICSHOP_DEPLOYED?null:s&&o?e.jsx(S,{content:t?null:"Continue to next lesson",children:e.jsxs(f,{to:o,prefetch:"intent",className:b("flex h-14 w-full items-center space-x-3 border-l px-4 py-4 pl-[18px] no-underline hover:underline"),state:{from:"continue next lesson button"},children:[e.jsx(v,{name:"FastForward",className:"flex-shrink-0",size:"md"}),t?e.jsx(x.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Continue to next lesson"}):e.jsx("span",{className:"sr-only",children:"Continue to next lesson"})]})}):null,e.jsx("div",{className:m("flex h-14 w-14 items-center justify-center self-start p-4 sm:mb-4 sm:w-full",{"w-full border-t":t,"border-l":!t}),children:e.jsx(re,{})})]})})})}const O=400;function Et({isMenuOpened:t,onMenuOpenChange:n}){const a=oe(),s=A(),o=se(),r=ne(),{users:c}=Y(),i=a.exercises.find(u=>u.exerciseNumber===Number(r.exerciseNumber)),l=r.type==="solution"?i==null?void 0:i.solutions.find(u=>u.stepNumber===Number(r.stepNumber)):r.type==="problem"?i==null?void 0:i.problems.find(u=>u.stepNumber===Number(r.stepNumber)):null,p=H(),h={close:{width:56},open:{width:O}},g={visible:{opacity:1,transition:{duration:.05,when:"beforeChildren",staggerChildren:.03}},hidden:{opacity:0}},w=Number(r.exerciseNumber).toString().padStart(2,"0");return e.jsx("nav",{className:"hidden border-r sm:flex",children:e.jsx(x.div,{initial:t?"open":"close",variants:h,animate:p,children:e.jsxs("div",{className:"flex h-full flex-col items-center justify-between",children:[e.jsx($e,{title:a.workshopTitle,menuControls:p,isMenuOpened:t,setMenuOpened:n}),t&&e.jsxs(x.div,{style:{width:O},className:"flex flex-grow flex-col justify-between overflow-y-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar",initial:{opacity:0},animate:{opacity:1},children:[e.jsx(x.ul,{variants:g,initial:"hidden",animate:"visible",className:"flex flex-col",children:a.exercises.map(({exerciseNumber:u,title:P,steps:E})=>{const D=Number(r.exerciseNumber)===u,L=!D&&a.playground.exerciseNumber===u,N=u.toString().padStart(2,"0");return e.jsxs(Te,{exerciseNumber:u,children:[e.jsxs(f,{prefetch:"intent",to:`/${N}`,className:b("relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline",'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":D}),children:[P,L?" 🛝":null]}),D?e.jsxs(x.ul,{variants:g,initial:"hidden",animate:"visible",className:"ml-4 mt-4 flex flex-col",children:[e.jsx(C,{type:"instructions",exerciseNumber:u,children:e.jsx(f,{to:`/${N}`,prefetch:"intent",className:b('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":!r.stepNumber}),children:"Intro"})},u),E.filter(Boolean).map(({name:_,stepNumber:R,title:J})=>{const Ae=Number(r.stepNumber)===R,W=R.toString().padStart(2,"0"),Le=_===a.playground.appName;return e.jsx(C,{type:"step",stepNumber:R,exerciseNumber:u,children:e.jsx(f,{to:`/${N}/${W}`,prefetch:"intent",className:b('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":Ae}),children:Le?`${W}. ${J} 🛝`:`${W}. ${J}`})},R)}),e.jsx(C,{type:"finished",exerciseNumber:u,children:e.jsx(T,{to:`/${N}/finished`,prefetch:"intent",className:({isActive:_})=>b('relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":_}),children:"📝 Elaboration"})})]}):null]},u)})}),e.jsx("div",{className:"mt-6",children:e.jsx(T,{to:"/finished",className:({isActive:u})=>b("relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline",{'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""]':u}),children:"📝 Workshop Feedback"})})]}),!t&&e.jsx("div",{className:"flex flex-grow flex-col justify-center",children:e.jsxs("div",{className:"orientation-sideways w-full font-mono text-sm font-medium uppercase leading-none",children:[i!=null&&i.title?e.jsx(f,{to:`/${w}`,children:i.title}):null,i!=null&&i.title&&(l!=null&&l.title)?" — ":null,l!=null&&l.title?e.jsx(f,{to:`/${w}/${l.stepNumber.toString().padStart(2,"0")}`,children:l.title}):null]})}),e.jsx("div",{className:m("flex w-full items-center justify-start border-t p-4 transition-[height]",t&&c.length>4?"h-28":"h-14"),style:t?{width:O}:{},children:e.jsx(Ie,{isMenuOpened:t})}),ENV.EPICSHOP_DEPLOYED?null:s?e.jsx(S,{content:t?null:"Your account",children:e.jsxs(f,{className:"flex h-14 w-full flex-shrink-0 items-center justify-start space-x-3 border-t px-4 py-4 text-center no-underline hover:underline",to:"/account",children:[s.avatarUrl?e.jsx("img",{alt:s.name??s.email,src:s.avatarUrl,className:"h-full rounded-full"}):e.jsx(v,{name:"User",className:"flex-shrink-0",size:"lg"}),t?e.jsx(x.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Your Account"}):e.jsx("span",{className:"sr-only",children:"Your account"})]})}):null,ENV.EPICSHOP_DEPLOYED?null:s&&o?e.jsx(S,{content:t?null:"Continue to next lesson",children:e.jsxs(f,{to:o,prefetch:"intent",className:b("flex h-14 w-full items-center space-x-3 border-t px-4 py-4 pl-[18px] no-underline hover:underline"),state:{from:"continue next lesson button"},children:[e.jsx(v,{name:"FastForward",className:"flex-shrink-0",size:"md"}),t?e.jsx(x.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Continue to next lesson"}):e.jsx("span",{className:"sr-only",children:"Continue to next lesson"})]})}):null,e.jsx("div",{className:"mb-4 w-full self-start border-t pl-3 pt-[15px]",children:e.jsx(re,{})})]})})})}function $e({title:t,isMenuOpened:n,setMenuOpened:a,menuControls:s}){const o=d.useRef(null),r={open:{d:"M3.06061 2.99999L21.0606 21"},closed:{d:"M0 9.5L24 9.5"}},c={open:{d:"M3.00006 21.0607L21 3.06064"},moving:{d:"M0 14.5L24 14.5"},closed:{d:"M0 14.5L15 14.5"}},i=H(),l=H();async function p(){s==null||s.start(n?"close":"open"),a(!n),n?(i.start(r.closed),await l.start(c.moving),l.start(c.closed)):(await l.start(c.moving),i.start(r.open),l.start(c.open))}return d.useEffect(()=>{if(!n)return;function h(g){var w;g.key==="Escape"&&((w=o.current)==null||w.click())}return document.addEventListener("keyup",h),()=>document.removeEventListener("keyup",h)},[n]),e.jsxs("div",{className:m("relative inline-flex h-14 flex-shrink-0 items-center justify-between overflow-hidden border-r sm:w-full sm:border-b sm:border-r-0",{"w-full":n}),children:[e.jsx("button",{ref:o,className:"flex h-14 w-14 items-center justify-center","aria-label":"Open Navigation menu",onClick:p,children:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",children:[e.jsx(x.path,{...r.closed,animate:i,transition:{duration:.2},stroke:"currentColor",strokeWidth:1.5}),e.jsx(x.path,{...c.closed,animate:l,transition:{duration:.2},stroke:"currentColor",strokeWidth:1.5})]})}),n&&e.jsx(x.p,{transition:{delay:.2},initial:{opacity:0,y:5},animate:{opacity:1,y:0},className:"absolute right-5 whitespace-nowrap font-mono text-sm uppercase",children:e.jsx(f,{to:"/",children:t})})]})}export{Vt as default};
|
|
6
|
+
//# sourceMappingURL=_layout-IOROGN78.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_layout-IOROGN78.js","sources":["../../../../../node_modules/framer-motion/dist/es/animation/hooks/animation-controls.mjs","../../../../../node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs","../../../app/components/media-query.ts","../../../../../node_modules/@radix-ui/react-dialog/dist/index.mjs","../../../app/components/ui/dialog.tsx","../../../app/routes/_app+/_layout.tsx"],"sourcesContent":["import { invariant } from '../../utils/errors.mjs';\nimport { setTarget } from '../../render/utils/setters.mjs';\nimport { animateVisualElement } from '../interfaces/visual-element.mjs';\n\nfunction stopAnimation(visualElement) {\n visualElement.values.forEach((value) => value.stop());\n}\nfunction setVariants(visualElement, variantLabels) {\n const reversedLabels = [...variantLabels].reverse();\n reversedLabels.forEach((key) => {\n const variant = visualElement.getVariant(key);\n variant && setTarget(visualElement, variant);\n if (visualElement.variantChildren) {\n visualElement.variantChildren.forEach((child) => {\n setVariants(child, variantLabels);\n });\n }\n });\n}\nfunction setValues(visualElement, definition) {\n if (Array.isArray(definition)) {\n return setVariants(visualElement, definition);\n }\n else if (typeof definition === \"string\") {\n return setVariants(visualElement, [definition]);\n }\n else {\n setTarget(visualElement, definition);\n }\n}\n/**\n * @public\n */\nfunction animationControls() {\n /**\n * Track whether the host component has mounted.\n */\n let hasMounted = false;\n /**\n * A collection of linked component animation controls.\n */\n const subscribers = new Set();\n const controls = {\n subscribe(visualElement) {\n subscribers.add(visualElement);\n return () => void subscribers.delete(visualElement);\n },\n start(definition, transitionOverride) {\n invariant(hasMounted, \"controls.start() should only be called after a component has mounted. Consider calling within a useEffect hook.\");\n const animations = [];\n subscribers.forEach((visualElement) => {\n animations.push(animateVisualElement(visualElement, definition, {\n transitionOverride,\n }));\n });\n return Promise.all(animations);\n },\n set(definition) {\n invariant(hasMounted, \"controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook.\");\n return subscribers.forEach((visualElement) => {\n setValues(visualElement, definition);\n });\n },\n stop() {\n subscribers.forEach((visualElement) => {\n stopAnimation(visualElement);\n });\n },\n mount() {\n hasMounted = true;\n return () => {\n hasMounted = false;\n controls.stop();\n };\n },\n };\n return controls;\n}\n\nexport { animationControls, setValues };\n","import { animationControls } from './animation-controls.mjs';\nimport { useConstant } from '../../utils/use-constant.mjs';\nimport { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';\n\n/**\n * Creates `AnimationControls`, which can be used to manually start, stop\n * and sequence animations on one or more components.\n *\n * The returned `AnimationControls` should be passed to the `animate` property\n * of the components you want to animate.\n *\n * These components can then be animated with the `start` method.\n *\n * ```jsx\n * import * as React from 'react'\n * import { motion, useAnimation } from 'framer-motion'\n *\n * export function MyComponent(props) {\n * const controls = useAnimation()\n *\n * controls.start({\n * x: 100,\n * transition: { duration: 0.5 },\n * })\n *\n * return <motion.div animate={controls} />\n * }\n * ```\n *\n * @returns Animation controller with `start` and `stop` methods\n *\n * @public\n */\nfunction useAnimationControls() {\n const controls = useConstant(animationControls);\n useIsomorphicLayoutEffect(controls.mount, []);\n return controls;\n}\nconst useAnimation = useAnimationControls;\n\nexport { useAnimation, useAnimationControls };\n","import { useSyncExternalStore } from 'react'\n\nexport function makeMediaQueryStore(\n\tmediaQuery: string,\n\tserverSnapshot: boolean,\n) {\n\tfunction getSnapshot() {\n\t\treturn window.matchMedia(mediaQuery).matches\n\t}\n\n\tfunction subscribe(callback: () => void) {\n\t\tconst mediaQueryList = window.matchMedia(mediaQuery)\n\t\tmediaQueryList.addEventListener('change', callback)\n\t\treturn () => {\n\t\t\tmediaQueryList.removeEventListener('change', callback)\n\t\t}\n\t}\n\n\treturn function useMediaQuery() {\n\t\treturn useSyncExternalStore(subscribe, getSnapshot, () => serverSnapshot)\n\t}\n}\n","\"use client\";\n\n// packages/react/dialog/src/Dialog.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContext, createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { DismissableLayer } from \"@radix-ui/react-dismissable-layer\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { hideOthers } from \"aria-hidden\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nvar DIALOG_NAME = \"Dialog\";\nvar [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);\nvar [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);\nvar Dialog = (props) => {\n const {\n __scopeDialog,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true\n } = props;\n const triggerRef = React.useRef(null);\n const contentRef = React.useRef(null);\n const [open = false, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen,\n onChange: onOpenChange\n });\n return /* @__PURE__ */ jsx(\n DialogProvider,\n {\n scope: __scopeDialog,\n triggerRef,\n contentRef,\n contentId: useId(),\n titleId: useId(),\n descriptionId: useId(),\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n modal,\n children\n }\n );\n};\nDialog.displayName = DIALOG_NAME;\nvar TRIGGER_NAME = \"DialogTrigger\";\nvar DialogTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...triggerProps } = props;\n const context = useDialogContext(TRIGGER_NAME, __scopeDialog);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.contentId,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }\n);\nDialogTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"DialogPortal\";\nvar [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar DialogPortal = (props) => {\n const { __scopeDialog, forceMount, children, container } = props;\n const context = useDialogContext(PORTAL_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) });\n};\nDialogPortal.displayName = PORTAL_NAME;\nvar OVERLAY_NAME = \"DialogOverlay\";\nvar DialogOverlay = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);\n return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;\n }\n);\nDialogOverlay.displayName = OVERLAY_NAME;\nvar DialogOverlayImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, __scopeDialog);\n return (\n // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`\n // ie. when `Overlay` and `Content` are siblings\n /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n ...overlayProps,\n ref: forwardedRef,\n style: { pointerEvents: \"auto\", ...overlayProps.style }\n }\n ) })\n );\n }\n);\nvar CONTENT_NAME = \"DialogContent\";\nvar DialogContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }\n);\nDialogContent.displayName = CONTENT_NAME;\nvar DialogContentModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: true,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n if (isRightClick) event.preventDefault();\n }),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault()\n )\n }\n );\n }\n);\nvar DialogContentNonModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }\n);\nvar DialogContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, __scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, contentRef);\n useFocusGuards();\n return /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n role: \"dialog\",\n id: context.contentId,\n \"aria-describedby\": context.descriptionId,\n \"aria-labelledby\": context.titleId,\n \"data-state\": getState(context.open),\n ...contentProps,\n ref: composedRefs,\n onDismiss: () => context.onOpenChange(false)\n }\n )\n }\n ),\n /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(TitleWarning, { titleId: context.titleId }),\n /* @__PURE__ */ jsx(DescriptionWarning, { contentRef, descriptionId: context.descriptionId })\n ] })\n ] });\n }\n);\nvar TITLE_NAME = \"DialogTitle\";\nvar DialogTitle = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...titleProps } = props;\n const context = useDialogContext(TITLE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });\n }\n);\nDialogTitle.displayName = TITLE_NAME;\nvar DESCRIPTION_NAME = \"DialogDescription\";\nvar DialogDescription = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...descriptionProps } = props;\n const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });\n }\n);\nDialogDescription.displayName = DESCRIPTION_NAME;\nvar CLOSE_NAME = \"DialogClose\";\nvar DialogClose = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...closeProps } = props;\n const context = useDialogContext(CLOSE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }\n);\nDialogClose.displayName = CLOSE_NAME;\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nvar TITLE_WARNING_NAME = \"DialogTitleWarning\";\nvar [WarningProvider, useWarningContext] = createContext(TITLE_WARNING_NAME, {\n contentName: CONTENT_NAME,\n titleName: TITLE_NAME,\n docsSlug: \"dialog\"\n});\nvar TitleWarning = ({ titleId }) => {\n const titleWarningContext = useWarningContext(TITLE_WARNING_NAME);\n const MESSAGE = `\\`${titleWarningContext.contentName}\\` requires a \\`${titleWarningContext.titleName}\\` for the component to be accessible for screen reader users.\n\nIf you want to hide the \\`${titleWarningContext.titleName}\\`, you can wrap it with our VisuallyHidden component.\n\nFor more information, see https://radix-ui.com/primitives/docs/components/${titleWarningContext.docsSlug}`;\n React.useEffect(() => {\n if (titleId) {\n const hasTitle = document.getElementById(titleId);\n if (!hasTitle) console.error(MESSAGE);\n }\n }, [MESSAGE, titleId]);\n return null;\n};\nvar DESCRIPTION_WARNING_NAME = \"DialogDescriptionWarning\";\nvar DescriptionWarning = ({ contentRef, descriptionId }) => {\n const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME);\n const MESSAGE = `Warning: Missing \\`Description\\` or \\`aria-describedby={undefined}\\` for {${descriptionWarningContext.contentName}}.`;\n React.useEffect(() => {\n const describedById = contentRef.current?.getAttribute(\"aria-describedby\");\n if (descriptionId && describedById) {\n const hasDescription = document.getElementById(descriptionId);\n if (!hasDescription) console.warn(MESSAGE);\n }\n }, [MESSAGE, contentRef, descriptionId]);\n return null;\n};\nvar Root = Dialog;\nvar Trigger = DialogTrigger;\nvar Portal = DialogPortal;\nvar Overlay = DialogOverlay;\nvar Content = DialogContent;\nvar Title = DialogTitle;\nvar Description = DialogDescription;\nvar Close = DialogClose;\nexport {\n Close,\n Content,\n Description,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n Overlay,\n Portal,\n Root,\n Title,\n Trigger,\n WarningProvider,\n createDialogScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as DialogPrimitive from '@radix-ui/react-dialog'\nimport * as React from 'react'\nimport { cn } from '#app/utils/misc.tsx'\nimport { Icon } from '../icons'\n\nconst Dialog = DialogPrimitive.Root\n\nconst DialogTrigger = DialogPrimitive.Trigger\n\nconst DialogPortal = DialogPrimitive.Portal\n\nconst DialogClose = DialogPrimitive.Close\n\nfunction DialogOverlay({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n\treturn (\n\t\t<DialogPrimitive.Overlay\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t'fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\nfunction DialogContent({\n\tclassName,\n\tchildren,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Content>) {\n\treturn (\n\t\t<DialogPortal>\n\t\t\t<DialogOverlay />\n\t\t\t<DialogPrimitive.Content\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t<DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\">\n\t\t\t\t\t<Icon name=\"Close\" />\n\t\t\t\t\t<span className=\"sr-only\">Close</span>\n\t\t\t\t</DialogPrimitive.Close>\n\t\t\t</DialogPrimitive.Content>\n\t\t</DialogPortal>\n\t)\n}\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\nfunction DialogHeader({\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex flex-col space-y-1.5 text-center sm:text-left',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogHeader.displayName = 'DialogHeader'\n\nfunction DialogFooter({\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogFooter.displayName = 'DialogFooter'\n\nfunction DialogTitle({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n\treturn (\n\t\t<DialogPrimitive.Title\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t'text-lg font-semibold leading-none tracking-tight',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nfunction DialogDescription({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n\treturn (\n\t\t<DialogPrimitive.Description\n\t\t\tref={ref}\n\t\t\tclassName={cn('text-sm text-muted-foreground', className)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport {\n\tDialog,\n\tDialogClose,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogOverlay,\n\tDialogPortal,\n\tDialogTitle,\n\tDialogTrigger,\n}\n","import {\n\textractNumbersAndTypeFromAppNameOrPath,\n\tgetExercises,\n\tgetPlaygroundAppName,\n\tgetWorkshopTitle,\n} from '@epic-web/workshop-utils/apps.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport {\n\tjson,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n} from '@remix-run/node'\nimport {\n\tLink,\n\tNavLink,\n\tOutlet,\n\tuseLoaderData,\n\tuseParams,\n} from '@remix-run/react'\nimport { clsx } from 'clsx'\nimport {\n\tmotion,\n\tuseAnimationControls,\n\ttype AnimationControls,\n} from 'framer-motion'\nimport * as React from 'react'\nimport { useHydrated } from 'remix-utils/use-hydrated'\nimport { Icon } from '#app/components/icons.tsx'\nimport { makeMediaQueryStore } from '#app/components/media-query.js'\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogHeader,\n\tDialogTrigger,\n} from '#app/components/ui/dialog.js'\nimport {\n\tSimpleTooltip,\n\tTooltip,\n\tTooltipContent,\n\tTooltipProvider,\n\tTooltipTrigger,\n} from '#app/components/ui/tooltip.tsx'\nimport { useOptionalUser } from '#app/components/user.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { usePresence, type User } from '#app/utils/presence.tsx'\nimport {\n\tuseExerciseProgressClassName,\n\tuseNextExerciseRoute,\n\tuseProgressItemClassName,\n\ttype ProgressItemSearch,\n} from '../progress.tsx'\nimport { ThemeSwitch } from '../theme/index.tsx'\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('stepLoader')\n\tconst [exercises, workshopTitle, playgroundAppName] = await Promise.all([\n\t\tgetExercises({ request, timings }),\n\t\tgetWorkshopTitle(),\n\t\tgetPlaygroundAppName(),\n\t])\n\n\tconst playground = {\n\t\tappName: playgroundAppName,\n\t\texerciseNumber: Number(\n\t\t\textractNumbersAndTypeFromAppNameOrPath(playgroundAppName ?? '')\n\t\t\t\t?.exerciseNumber,\n\t\t),\n\t}\n\n\tconst result = json(\n\t\t{\n\t\t\tworkshopTitle,\n\t\t\texercises: exercises.map((e) => ({\n\t\t\t\texerciseNumber: e.exerciseNumber,\n\t\t\t\ttitle: e.title,\n\t\t\t\tsolutions: e.solutions.map(({ stepNumber, title, name }) => ({\n\t\t\t\t\tstepNumber,\n\t\t\t\t\ttitle,\n\t\t\t\t\tname,\n\t\t\t\t})),\n\t\t\t\tproblems: e.problems.map(({ stepNumber, title, name }) => ({\n\t\t\t\t\tstepNumber,\n\t\t\t\t\ttitle,\n\t\t\t\t\tname,\n\t\t\t\t})),\n\t\t\t\tsteps: e.steps.map(({ stepNumber, problem, solution }) => ({\n\t\t\t\t\tstepNumber,\n\t\t\t\t\ttitle: problem?.title ?? solution?.title ?? 'Unknown',\n\t\t\t\t\tname: problem?.name ?? solution?.name ?? 'Unknown',\n\t\t\t\t})),\n\t\t\t})),\n\t\t\tplayground,\n\t\t},\n\t\t{\n\t\t\theaders: {\n\t\t\t\tVary: 'Cookie',\n\t\t\t\t'Server-Timing': getServerTimeHeader(timings),\n\t\t\t},\n\t\t},\n\t)\n\treturn result\n}\n\nexport const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\tVary: 'Cookie',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nconst opacities = ['opacity-70', 'opacity-80', 'opacity-90', 'opacity-100']\nconst shadows = [\n\t'shadow-[0_0_2px_0_rgba(0,0,0,0.3)]',\n\t'shadow-[0_0_4px_0_rgba(0,0,0,0.3)]',\n\t'shadow-[0_0_7px_0_rgba(0,0,0,0.3)]',\n\t'shadow-[0_0_10px_0_rgba(0,0,0,0.3)]',\n]\nfunction getScoreClassNames(score: number) {\n\tconst opacityNumber = Math.round(score * opacities.length - 1)\n\tconst shadowNumber = Math.round(score * shadows.length - 1)\n\treturn cn(\n\t\t'shadow-purple-700 hover:opacity-100 focus:opacity-100 dark:shadow-purple-200',\n\t\topacities[opacityNumber] ?? 'opacity-60',\n\t\tshadows[shadowNumber] ?? 'shadow-none',\n\t\tscore === 1 ? 'animate-pulse hover:animate-none focus:animate-none' : null,\n\t)\n}\n\nfunction FacePile({ isMenuOpened }: { isMenuOpened: boolean }) {\n\tconst loggedInUser = useOptionalUser()\n\tconst { users } = usePresence()\n\tconst limit = isMenuOpened ? 17 : 0\n\tconst numberOverLimit = users.length - limit\n\tif (!users.length) return null\n\tconst tiffany =\n\t\tisMenuOpened && users.length === 1 ? (\n\t\t\t<Link\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tto=\"https://www.youtube.com/watch?v=w6Q3mHyzn78\"\n\t\t\t>\n\t\t\t\t<img\n\t\t\t\t\talt=\"Tiffany Tunes\"\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'h-8 w-8 rounded-full border object-cover',\n\t\t\t\t\t\tgetScoreClassNames(1),\n\t\t\t\t\t)}\n\t\t\t\t\tsrc=\"/img/tiffany.png\"\n\t\t\t\t/>\n\t\t\t</Link>\n\t\t) : null\n\tconst overLimitLabel = `${numberOverLimit}${\n\t\tisMenuOpened ? ' more ' : ' '\n\t}Epic Web Dev${numberOverLimit === 1 ? '' : 's'} working now`\n\treturn (\n\t\t<div className=\"flex flex-wrap items-center gap-2\">\n\t\t\t<TooltipProvider>\n\t\t\t\t{users.slice(0, limit).map(({ user, score }) => {\n\t\t\t\t\tconst scoreClassNames = getScoreClassNames(score)\n\t\t\t\t\tconst locationLabel = getLocationLabel(user.location)\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Tooltip key={user.id}>\n\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t{user.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t\t\t\t\talt={user.name || 'Epic Web Dev'}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t'h-8 w-8 rounded-full border object-cover',\n\t\t\t\t\t\t\t\t\t\t\tscoreClassNames,\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\tsrc={user.avatarUrl}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t\t\t\t\taria-label={user.name || 'Epic Web Dev'}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t'flex h-8 w-8 items-center justify-center rounded-full border',\n\t\t\t\t\t\t\t\t\t\t\tscoreClassNames,\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Icon name=\"User\" />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t<TooltipContent>\n\t\t\t\t\t\t\t\t<span className=\"flex flex-col items-center justify-center gap-1\">\n\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t{user.name || 'An EPIC Web Dev'}{' '}\n\t\t\t\t\t\t\t\t\t\t{locationLabel\n\t\t\t\t\t\t\t\t\t\t\t? ` is ${user.location?.origin?.includes('epicweb.dev') ? 'learning' : 'working'} ${\n\t\t\t\t\t\t\t\t\t\t\t\t\tscore === 1 && loggedInUser?.id !== user.id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? 'with you'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t\t\t\t\t\t\t} on`\n\t\t\t\t\t\t\t\t\t\t\t: null}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{locationLabel?.line1 ? (\n\t\t\t\t\t\t\t\t\t\t<span>{locationLabel.line1}</span>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t{locationLabel?.line2 ? (\n\t\t\t\t\t\t\t\t\t\t<span>{locationLabel.line2}</span>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t\t{tiffany}\n\t\t\t\t{numberOverLimit > 0 ? (\n\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t\t\taria-label={overLimitLabel}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'flex items-center justify-center rounded-full border bg-accent text-xs text-accent-foreground',\n\t\t\t\t\t\t\t\t\tisMenuOpened ? 'h-8 w-8' : 'h-6 w-6',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'pointer-events-none overflow-hidden text-ellipsis whitespace-nowrap text-center',\n\t\t\t\t\t\t\t\t\t\tisMenuOpened ? 'w-8' : 'w-6',\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isMenuOpened ? `+${numberOverLimit}` : numberOverLimit}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>{overLimitLabel}</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t) : null}\n\t\t\t</TooltipProvider>\n\t\t</div>\n\t)\n}\n\nconst useIsWide = makeMediaQueryStore('(min-width: 640px)', true)\n\nexport default function App() {\n\tconst user = useOptionalUser()\n\tconst isWide = useIsWide()\n\tconst isHydrated = useHydrated()\n\n\tconst [isMenuOpened, setMenuOpened] = React.useState(false)\n\n\treturn (\n\t\t<div className=\"flex flex-col\">\n\t\t\t{user ? null : <EpicWebBanner />}\n\t\t\t{/*\n\t\t\t\tthis isn't placed in a conditional with isWide because the server render\n\t\t\t\tdoesn't know whether it should be around or not so we just use CSS to hide it\n\t\t\t\tif it's not supposed to show up.\n\n\t\t\t\tWe don't just use media queries for the wider screen nav because we want\n\t\t\t\tto avoid running all the logic in there unnecessarily.\n\t\t\t*/}\n\t\t\t{isHydrated && isWide ? null : (\n\t\t\t\t<MobileNavigation\n\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\tonMenuOpenChange={setMenuOpened}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\t// this nonsense is here because we want the panels to be scrollable rather\n\t\t\t\t// than having the entire page be scrollable (at least on wider screens)\n\t\t\t\tclassName={cn('flex flex-grow flex-col sm:flex-row', {\n\t\t\t\t\t'h-[calc(100vh-128px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))]':\n\t\t\t\t\t\t!user,\n\t\t\t\t\t'h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))]':\n\t\t\t\t\t\tuser,\n\t\t\t\t\t'h-[unset]': !isWide && isMenuOpened,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{isWide ? (\n\t\t\t\t\t<Navigation\n\t\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\t\tonMenuOpenChange={setMenuOpened}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'h-full w-full max-w-full sm:max-w-[calc(100%-56px)]',\n\t\t\t\t\t\tisMenuOpened ? 'hidden md:block' : '',\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<Outlet />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction getLocationLabel(location: User['location']) {\n\tif (!location) return null\n\n\tconst { exercise } = location\n\n\tconst exercisePortion = [\n\t\texercise\n\t\t\t? [exercise.exerciseNumber, exercise.stepNumber]\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t.map((s) => s.toString().padStart(2, '0'))\n\t\t\t\t\t.join('/')\n\t\t\t: null,\n\t\texercise?.type,\n\t]\n\t\t.filter(Boolean)\n\t\t.join(' - ')\n\treturn { line1: location.workshopTitle, line2: exercisePortion }\n}\n\nfunction EpicWebBanner() {\n\tconst isWide = useIsWide()\n\tconst details = (\n\t\t<div>\n\t\t\t{ENV.EPICSHOP_DEPLOYED ? (\n\t\t\t\t<div>\n\t\t\t\t\t{`This is the deployed version. `}\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\tto={ENV.EPICSHOP_GITHUB_REPO}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tRun locally\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t{` for full experience.`}\n\t\t\t\t\t</>{' '}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div>\n\t\t\t\t\t<Link to=\"/login\" className=\"underline\">\n\t\t\t\t\t\tLogin\n\t\t\t\t\t</Link>{' '}\n\t\t\t\t\tor{' '}\n\t\t\t\t\t<a href=\"https://www.epicweb.dev/login\" className=\"underline\">\n\t\t\t\t\t\tjoin for free\n\t\t\t\t\t</a>{' '}\n\t\t\t\t\tfor the full experience.\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n\treturn (\n\t\t<div className=\"z-10 flex h-16 items-center justify-between border-b bg-gradient-to-tr from-blue-500 to-indigo-500 pl-4 text-white\">\n\t\t\t{isWide ? (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"hidden flex-1 flex-wrap items-center gap-4 sm:flex\">\n\t\t\t\t\t\t<Icon name=\"EpicWeb\" size=\"lg\" />\n\t\t\t\t\t\t<div className=\"flex flex-1 flex-wrap items-center\">\n\t\t\t\t\t\t\t<p className=\"mr-2\">\n\t\t\t\t\t\t\t\tWelcome to the{' '}\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto=\"https://www.epicweb.dev\"\n\t\t\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tEpicWeb.dev\n\t\t\t\t\t\t\t\t</Link>{' '}\n\t\t\t\t\t\t\t\tWorkshop app!\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{details}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"hidden h-full flex-col items-center sm:flex md:flex-row\">\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto=\"https://www.epicweb.dev\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Join Epic Web</span>\n\t\t\t\t\t\t\t<span>↗︎</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto={\n\t\t\t\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t\t\t\t? 'https://www.epicweb.dev/login'\n\t\t\t\t\t\t\t\t\t: '/login'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon name=\"User\" size=\"lg\" />\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Login</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"flex flex-1 flex-wrap items-center gap-4 sm:hidden\">\n\t\t\t\t\t\t<a href=\"https://www.epicweb.dev\">\n\t\t\t\t\t\t\t<Icon name=\"EpicWeb\" size=\"lg\" />\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<Dialog>\n\t\t\t\t\t\t\t<DialogTrigger>\n\t\t\t\t\t\t\t\t<Icon name=\"Question\" size=\"lg\" className=\"animate-pulse\" />\n\t\t\t\t\t\t\t</DialogTrigger>\n\t\t\t\t\t\t\t<DialogContent>\n\t\t\t\t\t\t\t\t<DialogHeader>\n\t\t\t\t\t\t\t\t\t<Icon name=\"EpicWeb\" size=\"lg\" />\n\t\t\t\t\t\t\t\t\t<span className=\"text-lg font-semibold\">EpicWeb.dev</span>\n\t\t\t\t\t\t\t\t</DialogHeader>\n\t\t\t\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\t\t\t\tWelcome to the{' '}\n\t\t\t\t\t\t\t\t\t<Link to=\"https://www.epicweb.dev\" className=\"underline\">\n\t\t\t\t\t\t\t\t\t\tEpicWeb.dev\n\t\t\t\t\t\t\t\t\t</Link>{' '}\n\t\t\t\t\t\t\t\t\tWorkshop app!\n\t\t\t\t\t\t\t\t</DialogDescription>\n\t\t\t\t\t\t\t\t{details}\n\t\t\t\t\t\t\t</DialogContent>\n\t\t\t\t\t\t</Dialog>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex h-full items-center\">\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto=\"https://www.epicweb.dev\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Join</span>\n\t\t\t\t\t\t\t<span>↗︎</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto={\n\t\t\t\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t\t\t\t? 'https://www.epicweb.dev/login'\n\t\t\t\t\t\t\t\t\t: '/login'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon name=\"User\" size=\"lg\" />\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Login</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\nconst itemVariants = {\n\thidden: { opacity: 0, x: -20 },\n\tvisible: { opacity: 1, x: 0 },\n}\nfunction NavigationExerciseListItem({\n\texerciseNumber,\n\tchildren,\n}: {\n\texerciseNumber: number\n\tchildren: React.ReactNode\n}) {\n\tconst progressClassName = useExerciseProgressClassName(exerciseNumber)\n\treturn (\n\t\t<motion.li\n\t\t\tvariants={itemVariants}\n\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\tclassName={cn(\n\t\t\t\t// add gap of 3 to children, but using padding so the progress extends through the whole height\n\t\t\t\t'py-[6px] first:pt-3 last:pb-3',\n\t\t\t\tprogressClassName ? `${progressClassName} before:border-t` : null,\n\t\t\t)}\n\t\t>\n\t\t\t<span className=\"ml-2\">{children}</span>\n\t\t</motion.li>\n\t)\n}\n\nfunction NavigationExerciseStepListItem({\n\tchildren,\n\t...progressItemSearch\n}: {\n\tchildren: React.ReactNode\n} & ProgressItemSearch) {\n\tconst progressClassName = useProgressItemClassName(progressItemSearch)\n\treturn (\n\t\t<motion.li\n\t\t\tvariants={itemVariants}\n\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\tclassName={cn(\n\t\t\t\t// add gap of 3 to children, but using padding so the progress extends through the whole height\n\t\t\t\t'py-[6px] first:pt-3 last:pb-3',\n\t\t\t\tprogressClassName ? `${progressClassName} before:border-t` : null,\n\t\t\t)}\n\t\t>\n\t\t\t<span className=\"ml-2\">{children}</span>\n\t\t</motion.li>\n\t)\n}\n\nfunction MobileNavigation({\n\tisMenuOpened,\n\tonMenuOpenChange: setMenuOpened,\n}: {\n\tisMenuOpened: boolean\n\tonMenuOpenChange: (change: boolean) => void\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tconst user = useOptionalUser()\n\tconst nextExerciseRoute = useNextExerciseRoute()\n\tconst params = useParams()\n\tconst { users } = usePresence()\n\n\t// items\n\tconst listVariants = {\n\t\tvisible: {\n\t\t\topacity: 1,\n\t\t\ttransition: {\n\t\t\t\tduration: 0.05,\n\t\t\t\twhen: 'beforeChildren',\n\t\t\t\tstaggerChildren: 0.03,\n\t\t\t},\n\t\t},\n\t\thidden: {\n\t\t\topacity: 0,\n\t\t},\n\t}\n\n\treturn (\n\t\t<nav className=\"flex w-full border-b sm:hidden\">\n\t\t\t<div className=\"w-full\">\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn('flex items-center', {\n\t\t\t\t\t\t'flex-col': isMenuOpened,\n\t\t\t\t\t\t'h-14': !isMenuOpened,\n\t\t\t\t\t})}\n\t\t\t\t>\n\t\t\t\t\t<NavToggle\n\t\t\t\t\t\ttitle={data.workshopTitle}\n\t\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\t\tsetMenuOpened={setMenuOpened}\n\t\t\t\t\t/>\n\t\t\t\t\t{isMenuOpened && (\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\tclassName=\"flex w-full flex-grow flex-col justify-between overflow-x-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar\"\n\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\tclassName=\"flex flex-col\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{data.exercises.map(({ exerciseNumber, title, steps }) => {\n\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\tNumber(params.exerciseNumber) === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst showPlayground =\n\t\t\t\t\t\t\t\t\t\t!isActive &&\n\t\t\t\t\t\t\t\t\t\tdata.playground.exerciseNumber === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst exerciseNum = exerciseNumber.toString().padStart(2, '0')\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<NavigationExerciseListItem\n\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ 'bg-foreground text-background': isActive },\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t\t\t\t\t\t{showPlayground ? ' 🛝' : null}\n\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t{isActive ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"ml-4 mt-4 flex flex-col\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"instructions\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t!params.stepNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIntro\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{steps\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.map(({ name, stepNumber, title }) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tNumber(params.stepNumber) === stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst step = stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.padStart(2, '0')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isPlayground =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname === data.playground.appName\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstepNumber={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/${step}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{isPlayground\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? `${step}. ${title} 🛝`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: `${step}. ${title}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"finished\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/finished`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background': isActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t📝 Elaboration\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t</NavigationExerciseListItem>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t<div className=\"mt-6\">\n\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\tto=\"/finished\"\n\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"]':\n\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t📝 Workshop Feedback\n\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t)}\n\t\t\t\t\t<div className=\"flex-grow\" />\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex items-center justify-start p-4',\n\t\t\t\t\t\t\tisMenuOpened && users.length > 4 ? 'min-h-14' : 'h-14',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'w-full border-t': isMenuOpened,\n\t\t\t\t\t\t\t\t// left border is covered by the menu\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<FacePile isMenuOpened={isMenuOpened} />\n\t\t\t\t\t</div>\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user ? (\n\t\t\t\t\t\t<SimpleTooltip content={isMenuOpened ? null : 'Your account'}>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'flex h-14 flex-shrink-0 items-center justify-start space-x-3 px-4 py-4 text-center no-underline hover:underline',\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t'border-l': !isMenuOpened,\n\t\t\t\t\t\t\t\t\t\t'w-full border-t': isMenuOpened,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tto=\"/account\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{user.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\talt={user.name ?? user.email}\n\t\t\t\t\t\t\t\t\t\tsrc={user.avatarUrl}\n\t\t\t\t\t\t\t\t\t\tclassName=\"h-full rounded-full\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Icon name=\"User\" className=\"flex-shrink-0\" size=\"lg\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tYour Account\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Your account</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user && nextExerciseRoute ? (\n\t\t\t\t\t\t<SimpleTooltip\n\t\t\t\t\t\t\tcontent={isMenuOpened ? null : 'Continue to next lesson'}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={nextExerciseRoute}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t'flex h-14 w-full items-center space-x-3 border-l px-4 py-4 pl-[18px] no-underline hover:underline',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstate={{ from: 'continue next lesson button' }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon name=\"FastForward\" className=\"flex-shrink-0\" size=\"md\" />\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tContinue to next lesson\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Continue to next lesson</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex h-14 w-14 items-center justify-center self-start p-4 sm:mb-4 sm:w-full',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'w-full border-t': isMenuOpened,\n\t\t\t\t\t\t\t\t'border-l': !isMenuOpened,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ThemeSwitch />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</nav>\n\t)\n}\n\nconst OPENED_MENU_WIDTH = 400\n\nfunction Navigation({\n\tisMenuOpened,\n\tonMenuOpenChange: setMenuOpened,\n}: {\n\tisMenuOpened: boolean\n\tonMenuOpenChange: (change: boolean) => void\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tconst user = useOptionalUser()\n\tconst nextExerciseRoute = useNextExerciseRoute()\n\tconst params = useParams()\n\tconst { users } = usePresence()\n\n\tconst exercise = data.exercises.find(\n\t\t(e) => e.exerciseNumber === Number(params.exerciseNumber),\n\t)\n\tconst app =\n\t\tparams.type === 'solution'\n\t\t\t? exercise?.solutions.find(\n\t\t\t\t\t(s) => s.stepNumber === Number(params.stepNumber),\n\t\t\t\t)\n\t\t\t: params.type === 'problem'\n\t\t\t\t? exercise?.problems.find(\n\t\t\t\t\t\t(p) => p.stepNumber === Number(params.stepNumber),\n\t\t\t\t\t)\n\t\t\t\t: null\n\n\t// container\n\tconst menuControls = useAnimationControls()\n\tconst menuVariants = {\n\t\tclose: { width: 56 },\n\t\topen: { width: OPENED_MENU_WIDTH },\n\t}\n\n\t// items\n\tconst listVariants = {\n\t\tvisible: {\n\t\t\topacity: 1,\n\t\t\ttransition: {\n\t\t\t\tduration: 0.05,\n\t\t\t\twhen: 'beforeChildren',\n\t\t\t\tstaggerChildren: 0.03,\n\t\t\t},\n\t\t},\n\t\thidden: {\n\t\t\topacity: 0,\n\t\t},\n\t}\n\tconst exNum = Number(params.exerciseNumber).toString().padStart(2, '0')\n\n\treturn (\n\t\t<nav className=\"hidden border-r sm:flex\">\n\t\t\t<motion.div\n\t\t\t\tinitial={isMenuOpened ? 'open' : 'close'}\n\t\t\t\tvariants={menuVariants}\n\t\t\t\tanimate={menuControls}\n\t\t\t>\n\t\t\t\t<div className=\"flex h-full flex-col items-center justify-between\">\n\t\t\t\t\t<NavToggle\n\t\t\t\t\t\ttitle={data.workshopTitle}\n\t\t\t\t\t\tmenuControls={menuControls}\n\t\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\t\tsetMenuOpened={setMenuOpened}\n\t\t\t\t\t/>\n\t\t\t\t\t{isMenuOpened && (\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tstyle={{ width: OPENED_MENU_WIDTH }}\n\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\tclassName=\"flex flex-grow flex-col justify-between overflow-y-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar\"\n\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\tclassName=\"flex flex-col\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{data.exercises.map(({ exerciseNumber, title, steps }) => {\n\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\tNumber(params.exerciseNumber) === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst showPlayground =\n\t\t\t\t\t\t\t\t\t\t!isActive &&\n\t\t\t\t\t\t\t\t\t\tdata.playground.exerciseNumber === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst exerciseNum = exerciseNumber.toString().padStart(2, '0')\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<NavigationExerciseListItem\n\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ 'bg-foreground text-background': isActive },\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t\t\t\t\t\t{showPlayground ? ' 🛝' : null}\n\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t{isActive ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"ml-4 mt-4 flex flex-col\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"instructions\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t!params.stepNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIntro\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{steps\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.map(({ name, stepNumber, title }) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tNumber(params.stepNumber) === stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst step = stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.padStart(2, '0')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isPlayground =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname === data.playground.appName\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstepNumber={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/${step}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{isPlayground\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? `${step}. ${title} 🛝`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: `${step}. ${title}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"finished\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/finished`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background': isActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t📝 Elaboration\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t</NavigationExerciseListItem>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t<div className=\"mt-6\">\n\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\tto=\"/finished\"\n\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"]':\n\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t📝 Workshop Feedback\n\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t)}\n\t\t\t\t\t{!isMenuOpened && (\n\t\t\t\t\t\t<div className=\"flex flex-grow flex-col justify-center\">\n\t\t\t\t\t\t\t<div className=\"orientation-sideways w-full font-mono text-sm font-medium uppercase leading-none\">\n\t\t\t\t\t\t\t\t{exercise?.title ? (\n\t\t\t\t\t\t\t\t\t<Link to={`/${exNum}`}>{exercise.title}</Link>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t{exercise?.title && app?.title ? ' — ' : null}\n\t\t\t\t\t\t\t\t{app?.title ? (\n\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\tto={`/${exNum}/${app.stepNumber\n\t\t\t\t\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t\t\t\t\t.padStart(2, '0')}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{app.title}\n\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex w-full items-center justify-start border-t p-4 transition-[height]',\n\t\t\t\t\t\t\tisMenuOpened && users.length > 4 ? 'h-28' : 'h-14',\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={isMenuOpened ? { width: OPENED_MENU_WIDTH } : {}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<FacePile isMenuOpened={isMenuOpened} />\n\t\t\t\t\t</div>\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user ? (\n\t\t\t\t\t\t<SimpleTooltip content={isMenuOpened ? null : 'Your account'}>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tclassName=\"flex h-14 w-full flex-shrink-0 items-center justify-start space-x-3 border-t px-4 py-4 text-center no-underline hover:underline\"\n\t\t\t\t\t\t\t\tto=\"/account\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{user.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\talt={user.name ?? user.email}\n\t\t\t\t\t\t\t\t\t\tsrc={user.avatarUrl}\n\t\t\t\t\t\t\t\t\t\tclassName=\"h-full rounded-full\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Icon name=\"User\" className=\"flex-shrink-0\" size=\"lg\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tYour Account\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Your account</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user && nextExerciseRoute ? (\n\t\t\t\t\t\t<SimpleTooltip\n\t\t\t\t\t\t\tcontent={isMenuOpened ? null : 'Continue to next lesson'}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={nextExerciseRoute}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t'flex h-14 w-full items-center space-x-3 border-t px-4 py-4 pl-[18px] no-underline hover:underline',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstate={{ from: 'continue next lesson button' }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon name=\"FastForward\" className=\"flex-shrink-0\" size=\"md\" />\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tContinue to next lesson\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Continue to next lesson</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"mb-4 w-full self-start border-t pl-3 pt-[15px]\">\n\t\t\t\t\t\t<ThemeSwitch />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</motion.div>\n\t\t</nav>\n\t)\n}\n\nfunction NavToggle({\n\ttitle,\n\tisMenuOpened,\n\tsetMenuOpened,\n\tmenuControls,\n}: {\n\ttitle: string\n\tisMenuOpened: boolean\n\tsetMenuOpened: (value: boolean) => void\n\tmenuControls?: AnimationControls\n}) {\n\tconst menuButtonRef = React.useRef<HTMLButtonElement>(null)\n\tconst path01Variants = {\n\t\topen: { d: 'M3.06061 2.99999L21.0606 21' },\n\t\tclosed: { d: 'M0 9.5L24 9.5' },\n\t}\n\tconst path02Variants = {\n\t\topen: { d: 'M3.00006 21.0607L21 3.06064' },\n\t\tmoving: { d: 'M0 14.5L24 14.5' },\n\t\tclosed: { d: 'M0 14.5L15 14.5' },\n\t}\n\tconst path01Controls = useAnimationControls()\n\tconst path02Controls = useAnimationControls()\n\n\tasync function toggleMenu() {\n\t\tvoid menuControls?.start(isMenuOpened ? 'close' : 'open')\n\t\tsetMenuOpened(!isMenuOpened)\n\t\tif (isMenuOpened) {\n\t\t\tvoid path01Controls.start(path01Variants.closed)\n\t\t\tawait path02Controls.start(path02Variants.moving)\n\t\t\tvoid path02Controls.start(path02Variants.closed)\n\t\t} else {\n\t\t\tawait path02Controls.start(path02Variants.moving)\n\t\t\tvoid path01Controls.start(path01Variants.open)\n\t\t\tvoid path02Controls.start(path02Variants.open)\n\t\t}\n\t}\n\n\tReact.useEffect(() => {\n\t\tif (!isMenuOpened) return\n\n\t\tfunction handleKeyUp(event: KeyboardEvent) {\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tmenuButtonRef.current?.click()\n\t\t\t}\n\t\t}\n\t\tdocument.addEventListener('keyup', handleKeyUp)\n\t\treturn () => document.removeEventListener('keyup', handleKeyUp)\n\t}, [isMenuOpened])\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'relative inline-flex h-14 flex-shrink-0 items-center justify-between overflow-hidden border-r sm:w-full sm:border-b sm:border-r-0',\n\t\t\t\t{\n\t\t\t\t\t'w-full': isMenuOpened,\n\t\t\t\t},\n\t\t\t)}\n\t\t>\n\t\t\t<button\n\t\t\t\tref={menuButtonRef}\n\t\t\t\tclassName=\"flex h-14 w-14 items-center justify-center\"\n\t\t\t\taria-label=\"Open Navigation menu\"\n\t\t\t\tonClick={toggleMenu}\n\t\t\t>\n\t\t\t\t<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n\t\t\t\t\t<motion.path\n\t\t\t\t\t\t{...path01Variants.closed}\n\t\t\t\t\t\tanimate={path01Controls}\n\t\t\t\t\t\ttransition={{ duration: 0.2 }}\n\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t/>\n\t\t\t\t\t<motion.path\n\t\t\t\t\t\t{...path02Variants.closed}\n\t\t\t\t\t\tanimate={path02Controls}\n\t\t\t\t\t\ttransition={{ duration: 0.2 }}\n\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t{isMenuOpened && (\n\t\t\t\t<motion.p\n\t\t\t\t\ttransition={{ delay: 0.2 }}\n\t\t\t\t\tinitial={{ opacity: 0, y: 5 }}\n\t\t\t\t\tanimate={{ opacity: 1, y: 0 }}\n\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\tclassName=\"absolute right-5 whitespace-nowrap font-mono text-sm uppercase\"\n\t\t\t\t>\n\t\t\t\t\t<Link to=\"/\">{title}</Link>\n\t\t\t\t</motion.p>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n"],"names":["stopAnimation","visualElement","value","setVariants","variantLabels","key","variant","setTarget","child","setValues","definition","animationControls","subscribers","controls","transitionOverride","animations","animateVisualElement","useAnimationControls","useConstant","useIsomorphicLayoutEffect","makeMediaQueryStore","mediaQuery","serverSnapshot","getSnapshot","subscribe","callback","mediaQueryList","useSyncExternalStore","DIALOG_NAME","createDialogContext","createDialogScope","createContextScope","DialogProvider","useDialogContext","Dialog","props","__scopeDialog","children","openProp","defaultOpen","onOpenChange","modal","triggerRef","React.useRef","contentRef","open","setOpen","useControllableState","jsx","useId","React.useCallback","prevOpen","TRIGGER_NAME","DialogTrigger","React.forwardRef","forwardedRef","triggerProps","context","composedTriggerRef","useComposedRefs","Primitive","getState","composeEventHandlers","PORTAL_NAME","PortalProvider","usePortalContext","DialogPortal","forceMount","container","React.Children","Presence","PortalPrimitive","OVERLAY_NAME","DialogOverlay","portalContext","overlayProps","DialogOverlayImpl","RemoveScroll","Slot","CONTENT_NAME","DialogContent","contentProps","DialogContentModal","DialogContentNonModal","composedRefs","React.useEffect","content","hideOthers","DialogContentImpl","event","_a","originalEvent","ctrlLeftClick","hasInteractedOutsideRef","hasPointerDownOutsideRef","_b","target","trapFocus","onOpenAutoFocus","onCloseAutoFocus","useFocusGuards","jsxs","Fragment","FocusScope","DismissableLayer","TitleWarning","DescriptionWarning","TITLE_NAME","DialogTitle","titleProps","DESCRIPTION_NAME","DialogDescription","descriptionProps","CLOSE_NAME","DialogClose","closeProps","TITLE_WARNING_NAME","WarningProvider","useWarningContext","createContext","titleId","titleWarningContext","MESSAGE","DESCRIPTION_WARNING_NAME","descriptionId","describedById","Root","Trigger","Portal","Overlay","Content","Title","Description","Close","DialogPrimitive.Root","DialogPrimitive.Trigger","DialogPrimitive.Portal","className","ref","DialogPrimitive.Overlay","cn","DialogPrimitive.Content","DialogPrimitive.Close","Icon","DialogHeader","DialogPrimitive.Title","DialogPrimitive.Description","opacities","shadows","getScoreClassNames","score","opacityNumber","Math","round","length","shadowNumber","FacePile","isMenuOpened","loggedInUser","useOptionalUser","users","usePresence","limit","numberOverLimit","tiffany","Link","rel","to","alt","src","overLimitLabel","TooltipProvider","slice","map","user","scoreClassNames","locationLabel","getLocationLabel","location","Tooltip","TooltipTrigger","asChild","avatarUrl","tabIndex","name","TooltipContent","origin","includes","id","line1","line2","useIsWide","App","isWide","isHydrated","useHydrated","setMenuOpened","React","EpicWebBanner","MobileNavigation","onMenuOpenChange","Navigation","Outlet","exercise","exercisePortion","exerciseNumber","stepNumber","filter","Boolean","s","toString","padStart","join","type","workshopTitle","details","ENV","EPICSHOP_DEPLOYED","EPICSHOP_GITHUB_REPO","href","size","itemVariants","hidden","opacity","x","visible","NavigationExerciseListItem","progressClassName","useExerciseProgressClassName","motion","li","variants","NavigationExerciseStepListItem","progressItemSearch","useProgressItemClassName","data","useLoaderData","nextExerciseRoute","useNextExerciseRoute","params","useParams","listVariants","transition","duration","when","staggerChildren","NavToggle","title","div","initial","animate","ul","exercises","steps","isActive","Number","showPlayground","playground","exerciseNum","prefetch","clsx","step","isPlayground","appName","NavLink","SimpleTooltip","email","state","from","ThemeSwitch","OPENED_MENU_WIDTH","find","e","app","solutions","problems","p","menuControls","menuVariants","close","width","exNum","style","menuButtonRef","path01Variants","d","closed","path02Variants","moving","path01Controls","path02Controls","toggleMenu","start","handleKeyUp","current","click","document","addEventListener","removeEventListener","onClick","height","viewBox","path","stroke","strokeWidth","delay","y"],"mappings":"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","x_google_ignoreList":[0,1,3]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e}from"./index-
|
|
2
|
-
//# sourceMappingURL=account-
|
|
1
|
+
import{j as e}from"./index-1cKOJFpX.js";import{B as a}from"./button-DcWUKEqR.js";import{I as i}from"./misc-Bt-_bj1O.js";import{S as o}from"./tooltip-Cqh5cQvd.js";import{u as m,a as u}from"./user-MNzkRgJ3.js";import{u as x}from"./presence-DgSzsRAv.js";import{u as h,a as p,L as r,F as c}from"./components-C17zb3Us.js";import"./clsx-B-dksMZM.js";import"./request-info-DU15ezmn.js";const O={getSitemapEntries:()=>null};function k(){const l=h(),d=p(),t=m(),s=u(),n=x();return e.jsxs("main",{className:"container flex h-full w-full max-w-3xl flex-grow flex-col items-center justify-center gap-4",children:[e.jsx("img",{className:"h-36 w-36 rounded-full",alt:(s==null?void 0:s.displayName)??t.name??t.email,src:t.avatarUrl}),e.jsx("h1",{className:"mb-1 text-2xl",children:"Your Account"}),e.jsx("p",{className:"text-center text-gray-700 dark:text-gray-300",children:t.name?`Hi ${(s==null?void 0:s.displayName)??t.name}, your device is logged in with ${t.email}.`:`Your device is logged in with ${t.email}.`}),s?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-center text-gray-700 dark:text-gray-300",children:["And you are connected to discord as ",s.displayName," (",s.id,")."]}),e.jsxs("div",{className:"flex justify-center gap-2",children:[e.jsx(d.Form,{method:"post",children:e.jsx(a,{varient:"mono",name:"intent",value:"disconnect-discord",children:"Disconnect Discord"})}),e.jsx(o,{content:"Your discord connection gives you access to the exclusive Discord channels for Epic Web",children:e.jsx(i,{name:"Question",tabIndex:0})})]})]}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(r,{to:l.discordAuthUrl,className:"inline-flex items-center gap-2 underline",children:[e.jsx(i,{name:"Discord",size:"lg"}),"Connect Discord"]}),e.jsx(o,{content:"This will give you access to the exclusive Discord channels for Epic Web",children:e.jsx(i,{name:"Question",tabIndex:0})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(c,{method:"POST",children:[e.jsx("input",{name:"optOut",type:"hidden",value:n!=null&&n.optOut?"false":"true"}),e.jsxs(a,{varient:"mono",name:"intent",value:"presence-opt-out",children:[n!=null&&n.optOut?"Opt in to":"Opt out of"," presence"]})]}),e.jsx(o,{content:"This controls whether your name and avatar are displayed in the pile of faces in navigation",children:e.jsx(i,{name:"Question",tabIndex:0})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(c,{method:"post",children:e.jsx(a,{varient:"mono",name:"intent",value:"logout",children:"Log device out"})}),e.jsx(o,{content:e.jsxs("div",{children:["Note: it is your ",e.jsx("i",{className:"italic",children:"device"})," that's logged in, not your browser.",e.jsx("br",{}),"So all browsers on this device will be logged in with the same account on this device."]}),children:e.jsx(i,{name:"Question",tabIndex:0})})]}),e.jsxs("p",{children:["Check"," ",e.jsx(r,{to:"/onboarding",className:"underline",children:"/onboarding"})," ","if you'd like to review onboarding again."]}),e.jsxs("p",{children:["Check"," ",e.jsx(r,{to:"/support",className:"underline",children:"/support"})," ","if you need support."]})]})}export{k as default,O as handle};
|
|
2
|
+
//# sourceMappingURL=account-CQNVYlpT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-
|
|
1
|
+
{"version":3,"file":"account-CQNVYlpT.js","sources":["../../../app/routes/_app+/account.tsx"],"sourcesContent":["import { deleteCache } from '@epic-web/workshop-utils/cache.server'\nimport {\n\tdeleteDb,\n\tdeleteDiscordInfo,\n\trequireAuthInfo,\n\tsetPresencePreferences,\n} from '@epic-web/workshop-utils/db.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport { json, redirect, type LoaderFunctionArgs } from '@remix-run/node'\nimport { Form, Link, useFetcher, useLoaderData } from '@remix-run/react'\nimport { Button } from '#app/components/button.tsx'\nimport { Icon } from '#app/components/icons.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.js'\nimport { useOptionalDiscordMember, useUser } from '#app/components/user.tsx'\nimport { ensureUndeployed } from '#app/utils/misc.tsx'\nimport { usePresencePreferences } from '#app/utils/presence.tsx'\nimport { redirectWithToast } from '#app/utils/toast.server.ts'\nimport { getDiscordAuthURL } from '../discord.callback.ts'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => null,\n}\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tensureUndeployed()\n\tawait requireAuthInfo({ request })\n\treturn json({ discordAuthUrl: getDiscordAuthURL() })\n}\n\nexport async function action({ request }: { request: Request }) {\n\tensureUndeployed()\n\tconst formData = await request.formData()\n\tconst intent = formData.get('intent')\n\tif (intent === 'disconnect-discord') {\n\t\tawait deleteDiscordInfo()\n\t\treturn redirectWithToast('/account', {\n\t\t\ttype: 'success',\n\t\t\ttitle: 'Disconnected',\n\t\t\tdescription: 'Local discord data has been deleted.',\n\t\t})\n\t} else if (intent === 'logout') {\n\t\tawait deleteDb()\n\t\tawait deleteCache()\n\t\treturn redirectWithToast('/login', {\n\t\t\ttype: 'success',\n\t\t\ttitle: 'Logged out',\n\t\t\tdescription: 'Goodbye! Come back soon!',\n\t\t})\n\t} else if (intent === 'presence-opt-out') {\n\t\tconst optOut = formData.get('optOut') === 'true'\n\t\tawait setPresencePreferences({ optOut })\n\t\treturn redirectWithToast('/account', {\n\t\t\ttitle: optOut ? 'Opted out' : 'Opted in',\n\t\t\tdescription: `You are now ${optOut ? 'invisible' : 'visible'}.`,\n\t\t\ttype: 'success',\n\t\t})\n\t}\n\n\treturn redirect('/account')\n}\n\nexport default function Account() {\n\tconst data = useLoaderData<typeof loader>()\n\tconst disconnectFetcher = useFetcher()\n\tconst user = useUser()\n\tconst discordMember = useOptionalDiscordMember()\n\tconst presencePreferences = usePresencePreferences()\n\treturn (\n\t\t<main className=\"container flex h-full w-full max-w-3xl flex-grow flex-col items-center justify-center gap-4\">\n\t\t\t<img\n\t\t\t\tclassName=\"h-36 w-36 rounded-full\"\n\t\t\t\talt={discordMember?.displayName ?? user.name ?? user.email}\n\t\t\t\tsrc={user.avatarUrl}\n\t\t\t/>\n\t\t\t<h1 className=\"mb-1 text-2xl\">Your Account</h1>\n\t\t\t<p className=\"text-center text-gray-700 dark:text-gray-300\">\n\t\t\t\t{user.name\n\t\t\t\t\t? `Hi ${\n\t\t\t\t\t\t\tdiscordMember?.displayName ?? user.name\n\t\t\t\t\t\t}, your device is logged in with ${user.email}.`\n\t\t\t\t\t: `Your device is logged in with ${user.email}.`}\n\t\t\t</p>\n\t\t\t{discordMember ? (\n\t\t\t\t<>\n\t\t\t\t\t<p className=\"text-center text-gray-700 dark:text-gray-300\">\n\t\t\t\t\t\tAnd you are connected to discord as {discordMember.displayName} (\n\t\t\t\t\t\t{discordMember.id}).\n\t\t\t\t\t</p>\n\t\t\t\t\t<div className=\"flex justify-center gap-2\">\n\t\t\t\t\t\t<disconnectFetcher.Form method=\"post\">\n\t\t\t\t\t\t\t<Button varient=\"mono\" name=\"intent\" value=\"disconnect-discord\">\n\t\t\t\t\t\t\t\tDisconnect Discord\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</disconnectFetcher.Form>\n\t\t\t\t\t\t<SimpleTooltip content=\"Your discord connection gives you access to the exclusive Discord channels for Epic Web\">\n\t\t\t\t\t\t\t<Icon name=\"Question\" tabIndex={0} />\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto={data.discordAuthUrl}\n\t\t\t\t\t\tclassName=\"inline-flex items-center gap-2 underline\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon name=\"Discord\" size=\"lg\" />\n\t\t\t\t\t\tConnect Discord\n\t\t\t\t\t</Link>\n\t\t\t\t\t<SimpleTooltip content=\"This will give you access to the exclusive Discord channels for Epic Web\">\n\t\t\t\t\t\t<Icon name=\"Question\" tabIndex={0} />\n\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tname=\"optOut\"\n\t\t\t\t\t\ttype=\"hidden\"\n\t\t\t\t\t\tvalue={presencePreferences?.optOut ? 'false' : 'true'}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button varient=\"mono\" name=\"intent\" value=\"presence-opt-out\">\n\t\t\t\t\t\t{presencePreferences?.optOut ? 'Opt in to' : 'Opt out of'} presence\n\t\t\t\t\t</Button>\n\t\t\t\t</Form>\n\t\t\t\t<SimpleTooltip content=\"This controls whether your name and avatar are displayed in the pile of faces in navigation\">\n\t\t\t\t\t<Icon name=\"Question\" tabIndex={0} />\n\t\t\t\t</SimpleTooltip>\n\t\t\t</div>\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Form method=\"post\">\n\t\t\t\t\t<Button varient=\"mono\" name=\"intent\" value=\"logout\">\n\t\t\t\t\t\tLog device out\n\t\t\t\t\t</Button>\n\t\t\t\t</Form>\n\t\t\t\t<SimpleTooltip\n\t\t\t\t\tcontent={\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\tNote: it is your <i className=\"italic\">device</i> that's logged\n\t\t\t\t\t\t\tin, not your browser.\n\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\tSo all browsers on this device will be logged in with the same\n\t\t\t\t\t\t\taccount on this device.\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t>\n\t\t\t\t\t<Icon name=\"Question\" tabIndex={0} />\n\t\t\t\t</SimpleTooltip>\n\t\t\t</div>\n\t\t\t<p>\n\t\t\t\tCheck{' '}\n\t\t\t\t<Link to=\"/onboarding\" className=\"underline\">\n\t\t\t\t\t/onboarding\n\t\t\t\t</Link>{' '}\n\t\t\t\tif you'd like to review onboarding again.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tCheck{' '}\n\t\t\t\t<Link to=\"/support\" className=\"underline\">\n\t\t\t\t\t/support\n\t\t\t\t</Link>{' '}\n\t\t\t\tif you need support.\n\t\t\t</p>\n\t\t</main>\n\t)\n}\n"],"names":["handle","getSitemapEntries","Account","data","useLoaderData","disconnectFetcher","useFetcher","user","useUser","discordMember","useOptionalDiscordMember","presencePreferences","usePresencePreferences","jsxs","className","children","jsx","alt","displayName","name","email","src","avatarUrl","Fragment","id","Form","method","Button","varient","value","SimpleTooltip","content","Icon","tabIndex","Link","to","discordAuthUrl","size","type","optOut"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as n}from"./index-
|
|
2
|
-
//# sourceMappingURL=button-
|
|
1
|
+
import{j as n}from"./index-1cKOJFpX.js";import{c as r}from"./clsx-B-dksMZM.js";import{L as u}from"./components-C17zb3Us.js";function l(){return n.jsx("span",{className:"inline-block animate-spin",children:"🌀"})}function d(){return n.jsx("span",{children:"✅"})}function m(){return n.jsx("span",{children:"❌"})}function a({varient:e,clip:o=!0}){const t="inline-flex bg-foreground text-background outline-none hover:bg-background hover:text-foreground focus:bg-background focus:text-foreground",s="px-8 py-4 font-bold",c="px-8 py-4 text-xl font-bold",i="px-8 py-4 font-mono text-sm uppercase";return r(t,{"clip-path-button":o,[s]:e==="primary",[c]:e==="big",[i]:e==="mono"})}function g({varient:e,status:o="idle",...t}){const s={pending:n.jsx(l,{}),success:n.jsx(d,{}),error:n.jsx(m,{}),idle:null}[o];return n.jsx("div",{className:"clip-path-button-outer w-fit border-2 border-foreground bg-foreground",children:n.jsxs("button",{...t,className:r(t.className,a({varient:e}),"flex justify-center gap-4"),children:[n.jsx("div",{children:t.children}),s]})})}function j({varient:e,...o}){return n.jsx("div",{className:"clip-path-button-outer w-fit border-2 border-foreground bg-foreground",children:n.jsx(u,{...o,className:r(o.className,a({varient:e}))})})}export{g as B,j as a};
|
|
2
|
+
//# sourceMappingURL=button-DcWUKEqR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button-
|
|
1
|
+
{"version":3,"file":"button-DcWUKEqR.js","sources":["../../../app/components/button.tsx"],"sourcesContent":["import { Link } from '@remix-run/react'\nimport { clsx } from 'clsx'\n\nfunction PendingState() {\n\treturn <span className=\"inline-block animate-spin\">🌀</span>\n}\n\nfunction SuccessState() {\n\treturn <span>✅</span>\n}\n\nfunction ErrorState() {\n\treturn <span>❌</span>\n}\n\nexport function getButtonClassName({\n\tvarient,\n\tclip = true,\n}: {\n\tvarient: 'primary' | 'big' | 'mono'\n\tclip?: boolean\n}) {\n\tconst baseClassName =\n\t\t'inline-flex bg-foreground text-background outline-none hover:bg-background hover:text-foreground focus:bg-background focus:text-foreground'\n\tconst primaryClassName = 'px-8 py-4 font-bold'\n\tconst bigClassName = 'px-8 py-4 text-xl font-bold'\n\tconst monoClassName = 'px-8 py-4 font-mono text-sm uppercase'\n\tconst className = clsx(baseClassName, {\n\t\t'clip-path-button': clip,\n\t\t[primaryClassName]: varient === 'primary',\n\t\t[bigClassName]: varient === 'big',\n\t\t[monoClassName]: varient === 'mono',\n\t})\n\treturn className\n}\n\nexport function Button({\n\tvarient,\n\tstatus = 'idle',\n\t...props\n}: React.ComponentPropsWithoutRef<'button'> &\n\tParameters<typeof getButtonClassName>[0] & {\n\t\tstatus?: 'pending' | 'success' | 'error' | 'idle'\n\t}) {\n\tconst companion = {\n\t\tpending: <PendingState />,\n\t\tsuccess: <SuccessState />,\n\t\terror: <ErrorState />,\n\t\tidle: null,\n\t}[status]\n\treturn (\n\t\t<div className=\"clip-path-button-outer w-fit border-2 border-foreground bg-foreground\">\n\t\t\t<button\n\t\t\t\t{...props}\n\t\t\t\tclassName={clsx(\n\t\t\t\t\tprops.className,\n\t\t\t\t\tgetButtonClassName({ varient }),\n\t\t\t\t\t'flex justify-center gap-4',\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<div>{props.children}</div>\n\t\t\t\t{companion}\n\t\t\t</button>\n\t\t</div>\n\t)\n}\n\nexport function ButtonLink({\n\tvarient,\n\t...props\n}: React.ComponentPropsWithoutRef<typeof Link> &\n\tParameters<typeof getButtonClassName>[0]) {\n\treturn (\n\t\t<div className=\"clip-path-button-outer w-fit border-2 border-foreground bg-foreground\">\n\t\t\t<Link\n\t\t\t\t{...props}\n\t\t\t\tclassName={clsx(props.className, getButtonClassName({ varient }))}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],"names":["PendingState","jsx","SuccessState","ErrorState","getButtonClassName","varient","clip","baseClassName","primaryClassName","bigClassName","monoClassName","clsx","Button","status","props","companion","jsxs","ButtonLink","Link"],"mappings":"4HAGA,SAASA,GAAe,CACvB,OAAQC,EAAAA,IAAA,OAAA,CAAK,UAAU,4BAA4B,SAAE,IAAA,CAAA,CACtD,CAEA,SAASC,GAAe,CAChB,OAAAD,EAAA,IAAC,QAAK,SAAC,GAAA,CAAA,CACf,CAEA,SAASE,GAAa,CACd,OAAAF,EAAA,IAAC,QAAK,SAAC,GAAA,CAAA,CACf,CAEO,SAASG,EAAmB,CAClC,QAAAC,EACA,KAAAC,EAAO,EACR,EAGG,CACF,MAAMC,EACL,6IACKC,EAAmB,sBACnBC,EAAe,8BACfC,EAAgB,wCAOf,OANWC,EAAKJ,EAAe,CACrC,mBAAoBD,EACpB,CAACE,CAAgB,EAAGH,IAAY,UAChC,CAACI,CAAY,EAAGJ,IAAY,MAC5B,CAACK,CAAa,EAAGL,IAAY,MAAA,CAC7B,CAEF,CAEO,SAASO,EAAO,CACtB,QAAAP,EACA,OAAAQ,EAAS,OACT,GAAGC,CACJ,EAGI,CACH,MAAMC,EAAY,CACjB,cAAUf,EAAa,EAAA,EACvB,cAAUE,EAAa,EAAA,EACvB,YAAQC,EAAW,EAAA,EACnB,KAAM,MACLU,CAAM,EAEP,OAAAZ,EAAAA,IAAC,MAAI,CAAA,UAAU,wEACd,SAAAe,EAAA,KAAC,SAAA,CACC,GAAGF,EACJ,UAAWH,EACVG,EAAM,UACNV,EAAmB,CAAE,QAAAC,EAAS,EAC9B,2BACD,EAEA,SAAA,CAACJ,EAAAA,IAAA,MAAA,CAAK,WAAM,QAAS,CAAA,EACpBc,CAAA,CAAA,CAEH,CAAA,CAAA,CAEF,CAEO,SAASE,EAAW,CAC1B,QAAAZ,EACA,GAAGS,CACJ,EAC2C,CAEzC,OAAAb,EAAAA,IAAC,MAAI,CAAA,UAAU,wEACd,SAAAA,EAAA,IAACiB,EAAA,CACC,GAAGJ,EACJ,UAAWH,EAAKG,EAAM,UAAWV,EAAmB,CAAE,QAAAC,CAAA,CAAS,CAAC,CAAA,CAElE,CAAA,CAAA,CAEF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{e as k,r as d,j as p}from"./index-
|
|
1
|
+
import{e as k,r as d,j as p}from"./index-1cKOJFpX.js";import{u as C}from"./request-info-DU15ezmn.js";function g(e){function r(o,t){var a;const s=e[t];if(!s)throw new Error(`Unknown client hint: ${typeof t=="string"?t:"Unknown"}`);const u=(a=o.split(";").map(c=>c.trim()).find(c=>c.startsWith(s.cookieName+"=")))==null?void 0:a.split("=")[1];return u?decodeURIComponent(u):null}function n(o){const t=typeof document<"u"?document.cookie:typeof o<"u"?o.headers.get("Cookie")??"":"";return Object.entries(e).reduce((s,[u,a])=>{const c=u;return"transform"in a?s[c]=a.transform(r(t,c)??a.fallback):s[c]=r(t,c)??a.fallback,s},{})}function i(){return`
|
|
2
2
|
// This block of code allows us to check if the client hints have changed and
|
|
3
3
|
// force a reload of the page with updated hints if they have so you don't get
|
|
4
4
|
// a flash of incorrect content.
|
|
@@ -33,4 +33,4 @@ function checkClientHints() {
|
|
|
33
33
|
|
|
34
34
|
checkClientHints();
|
|
35
35
|
`}return{getHints:n,getClientHintCheckScript:i}}const l={cookieName:"CH-prefers-color-scheme",getValueCode:"window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'",fallback:"light",transform(e){return e==="dark"?"dark":"light"}};function v(e,r=l.cookieName){const n=window.matchMedia("(prefers-color-scheme: dark)");function i(){const o=n.matches?"dark":"light";document.cookie=`${r}=${o}; Max-Age=31536000; Path=/`,e(o)}return n.addEventListener("change",i),function(){n.removeEventListener("change",i)}}const m={cookieName:"CH-reduced-motion",getValueCode:"window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'reduce' : 'no-preference'",fallback:"no-preference",transform(e){return e==="reduce"?"reduce":"no-preference"}};function H(e,r=m.cookieName){const n=window.matchMedia("(prefers-reduced-motion: reduce)");function i(){const o=n.matches?"reduce":"no-preference";document.cookie=`${r}=${o}; Max-Age=31536000; Path=/`,e(o)}return n.addEventListener("change",i),function(){n.removeEventListener("change",i)}}const S={cookieName:"CH-time-zone",getValueCode:"Intl.DateTimeFormat().resolvedOptions().timeZone",fallback:"UTC"},h="EpicShop_CH-prefers-color-scheme",f="EpicShop_CH-reduced-motion",w=g({theme:{...l,cookieName:h},timeZone:{...S,cookieName:"EpicShop_CH-time-zone"},reducedMotion:{...m,cookieName:f}});function b(){return C().hints}function E(){const{revalidate:e}=k();return d.useEffect(()=>v(()=>e(),h),[e]),d.useEffect(()=>H(()=>e(),f),[e]),p.jsx("script",{dangerouslySetInnerHTML:{__html:w.getClientHintCheckScript()}})}export{E as C,b as u};
|
|
36
|
-
//# sourceMappingURL=client-hints-
|
|
36
|
+
//# sourceMappingURL=client-hints-DWL_Mq1C.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-hints-DLYDs4RF.js","sources":["../../../../../node_modules/@epic-web/client-hints/dist/index.js","../../../../../node_modules/@epic-web/client-hints/dist/color-scheme.js","../../../../../node_modules/@epic-web/client-hints/dist/reduced-motion.js","../../../../../node_modules/@epic-web/client-hints/dist/time-zone.js","../../../app/utils/client-hints.tsx"],"sourcesContent":["export function getHintUtils(hints) {\n function getCookieValue(cookieString, name) {\n const hint = hints[name];\n if (!hint) {\n throw new Error(`Unknown client hint: ${typeof name === 'string' ? name : 'Unknown'}`);\n }\n const value = cookieString\n .split(';')\n .map((c) => c.trim())\n .find((c) => c.startsWith(hint.cookieName + '='))\n ?.split('=')[1];\n return value ? decodeURIComponent(value) : null;\n }\n function getHints(request) {\n const cookieString = typeof document !== 'undefined'\n ? document.cookie\n : typeof request !== 'undefined'\n ? request.headers.get('Cookie') ?? ''\n : '';\n return Object.entries(hints).reduce((acc, [name, hint]) => {\n const hintName = name;\n if ('transform' in hint) {\n // @ts-expect-error - this is fine (PRs welcome though)\n acc[hintName] = hint.transform(getCookieValue(cookieString, hintName) ?? hint.fallback);\n }\n else {\n // @ts-expect-error - this is fine (PRs welcome though)\n acc[hintName] = getCookieValue(cookieString, hintName) ?? hint.fallback;\n }\n return acc;\n }, {});\n }\n /**\n * This returns a string of JavaScript that can be used to check if the client\n * hints have changed and will reload the page if they have.\n */\n function getClientHintCheckScript() {\n return `\n// This block of code allows us to check if the client hints have changed and\n// force a reload of the page with updated hints if they have so you don't get\n// a flash of incorrect content.\nfunction checkClientHints() {\n\tif (!navigator.cookieEnabled) return;\n\n\t// set a short-lived cookie to make sure we can set cookies\n\tdocument.cookie = \"canSetCookies=1; Max-Age=60; SameSite=Lax\";\n\tconst canSetCookies = document.cookie.includes(\"canSetCookies=1\");\n\tdocument.cookie = \"canSetCookies=; Max-Age=-1; path=/\";\n\tif (!canSetCookies) return;\n\n\tconst cookies = document.cookie.split(';').map(c => c.trim()).reduce((acc, cur) => {\n\t\tconst [key, value] = cur.split('=');\n\t\tacc[key] = value;\n\t\treturn acc;\n\t}, {});\n\n\tlet cookieChanged = false;\n\tconst hints = [\n\t${Object.values(hints)\n .map((hint) => {\n const cookieName = JSON.stringify(hint.cookieName);\n return `{ name: ${cookieName}, actual: String(${hint.getValueCode}), value: cookies[${cookieName}] != null ? cookies[${cookieName}] : encodeURIComponent(\"${hint.fallback}\") }`;\n })\n .join(',\\n')}\n\t];\n\tfor (const hint of hints) {\n\t\tdocument.cookie = encodeURIComponent(hint.name) + '=' + encodeURIComponent(hint.actual) + '; Max-Age=31536000; path=/';\n\t\tif (decodeURIComponent(hint.value) !== hint.actual) {\n\t\t\tcookieChanged = true;\n\t\t}\n\t}\n\tif (cookieChanged) window.location.reload();\n}\n\ncheckClientHints();\n`;\n }\n return { getHints, getClientHintCheckScript };\n}\n","export const clientHint = {\n cookieName: 'CH-prefers-color-scheme',\n getValueCode: `window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'`,\n fallback: 'light',\n transform(value) {\n return value === 'dark' ? 'dark' : 'light';\n },\n};\n/**\n * Subscribe to changes in the user's color scheme preference. Optionally pass\n * in a cookie name to use for the cookie that will be set if different from the\n * default.\n */\nexport function subscribeToSchemeChange(subscriber, cookieName = clientHint.cookieName) {\n const schemaMatch = window.matchMedia('(prefers-color-scheme: dark)');\n function handleThemeChange() {\n const value = schemaMatch.matches ? 'dark' : 'light';\n document.cookie = `${cookieName}=${value}; Max-Age=31536000; Path=/`;\n subscriber(value);\n }\n schemaMatch.addEventListener('change', handleThemeChange);\n return function cleanupSchemaChange() {\n schemaMatch.removeEventListener('change', handleThemeChange);\n };\n}\n","export const clientHint = {\n cookieName: 'CH-reduced-motion',\n getValueCode: `window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'reduce' : 'no-preference'`,\n fallback: 'no-preference',\n transform(value) {\n return value === 'reduce' ? 'reduce' : 'no-preference';\n },\n};\n/**\n * Subscribe to changes in the user's motion preference. Optionally pass\n * in a cookie name to use for the cookie that will be set if different from the\n * default.\n */\nexport function subscribeToMotionChange(subscriber, cookieName = clientHint.cookieName) {\n const motionMatch = window.matchMedia('(prefers-reduced-motion: reduce)');\n function handleMotionChange() {\n const value = motionMatch.matches ? 'reduce' : 'no-preference';\n document.cookie = `${cookieName}=${value}; Max-Age=31536000; Path=/`;\n subscriber(value);\n }\n motionMatch.addEventListener('change', handleMotionChange);\n return function cleanupMotionChange() {\n motionMatch.removeEventListener('change', handleMotionChange);\n };\n}\n","export const clientHint = {\n cookieName: 'CH-time-zone',\n getValueCode: 'Intl.DateTimeFormat().resolvedOptions().timeZone',\n fallback: 'UTC',\n};\n","/**\n * This file contains utilities for using client hints for user preference which\n * are needed by the server, but are only known by the browser.\n */\nimport { getHintUtils } from '@epic-web/client-hints'\nimport {\n\tclientHint as colorSchemeHint,\n\tsubscribeToSchemeChange,\n} from '@epic-web/client-hints/color-scheme'\nimport {\n\tclientHint as reducedMotionHint,\n\tsubscribeToMotionChange,\n} from '@epic-web/client-hints/reduced-motion'\nimport { clientHint as timeZoneHint } from '@epic-web/client-hints/time-zone'\nimport { useRevalidator } from '@remix-run/react'\nimport * as React from 'react'\nimport { useRequestInfo } from './request-info.ts'\n\nconst themeCookieName = 'EpicShop_CH-prefers-color-scheme'\nconst motionCookieName = 'EpicShop_CH-reduced-motion'\nconst hintsUtils = getHintUtils({\n\ttheme: {\n\t\t...colorSchemeHint,\n\t\tcookieName: themeCookieName,\n\t},\n\ttimeZone: {\n\t\t...timeZoneHint,\n\t\tcookieName: 'EpicShop_CH-time-zone',\n\t},\n\treducedMotion: {\n\t\t...reducedMotionHint,\n\t\tcookieName: motionCookieName,\n\t},\n\t// add other hints here\n})\n\nexport const { getHints } = hintsUtils\n\n/**\n * @returns an object with the client hints and their values\n */\nexport function useHints() {\n\tconst requestInfo = useRequestInfo()\n\treturn requestInfo.hints\n}\n\n/**\n * @returns inline script element that checks for client hints and sets cookies\n * if they are not set then reloads the page if any cookie was set to an\n * inaccurate value.\n */\nexport function ClientHintCheck() {\n\tconst { revalidate } = useRevalidator()\n\tReact.useEffect(\n\t\t() => subscribeToSchemeChange(() => revalidate(), themeCookieName),\n\t\t[revalidate],\n\t)\n\tReact.useEffect(\n\t\t() => subscribeToMotionChange(() => revalidate(), motionCookieName),\n\t\t[revalidate],\n\t)\n\n\treturn (\n\t\t<script\n\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t__html: hintsUtils.getClientHintCheckScript(),\n\t\t\t}}\n\t\t/>\n\t)\n}\n"],"names":["getHintUtils","hints","getCookieValue","cookieString","name","hint","value","_a","getHints","request","acc","hintName","getClientHintCheckScript","cookieName","clientHint","subscribeToSchemeChange","subscriber","schemaMatch","handleThemeChange","subscribeToMotionChange","motionMatch","handleMotionChange","themeCookieName","motionCookieName","hintsUtils","colorSchemeHint","timeZoneHint","reducedMotionHint","useHints","useRequestInfo","ClientHintCheck","revalidate","useRevalidator","React.useEffect","jsx"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
1
|
+
{"version":3,"file":"client-hints-DWL_Mq1C.js","sources":["../../../../../node_modules/@epic-web/client-hints/dist/index.js","../../../../../node_modules/@epic-web/client-hints/dist/color-scheme.js","../../../../../node_modules/@epic-web/client-hints/dist/reduced-motion.js","../../../../../node_modules/@epic-web/client-hints/dist/time-zone.js","../../../app/utils/client-hints.tsx"],"sourcesContent":["export function getHintUtils(hints) {\n function getCookieValue(cookieString, name) {\n const hint = hints[name];\n if (!hint) {\n throw new Error(`Unknown client hint: ${typeof name === 'string' ? name : 'Unknown'}`);\n }\n const value = cookieString\n .split(';')\n .map((c) => c.trim())\n .find((c) => c.startsWith(hint.cookieName + '='))\n ?.split('=')[1];\n return value ? decodeURIComponent(value) : null;\n }\n function getHints(request) {\n const cookieString = typeof document !== 'undefined'\n ? document.cookie\n : typeof request !== 'undefined'\n ? request.headers.get('Cookie') ?? ''\n : '';\n return Object.entries(hints).reduce((acc, [name, hint]) => {\n const hintName = name;\n if ('transform' in hint) {\n // @ts-expect-error - this is fine (PRs welcome though)\n acc[hintName] = hint.transform(getCookieValue(cookieString, hintName) ?? hint.fallback);\n }\n else {\n // @ts-expect-error - this is fine (PRs welcome though)\n acc[hintName] = getCookieValue(cookieString, hintName) ?? hint.fallback;\n }\n return acc;\n }, {});\n }\n /**\n * This returns a string of JavaScript that can be used to check if the client\n * hints have changed and will reload the page if they have.\n */\n function getClientHintCheckScript() {\n return `\n// This block of code allows us to check if the client hints have changed and\n// force a reload of the page with updated hints if they have so you don't get\n// a flash of incorrect content.\nfunction checkClientHints() {\n\tif (!navigator.cookieEnabled) return;\n\n\t// set a short-lived cookie to make sure we can set cookies\n\tdocument.cookie = \"canSetCookies=1; Max-Age=60; SameSite=Lax\";\n\tconst canSetCookies = document.cookie.includes(\"canSetCookies=1\");\n\tdocument.cookie = \"canSetCookies=; Max-Age=-1; path=/\";\n\tif (!canSetCookies) return;\n\n\tconst cookies = document.cookie.split(';').map(c => c.trim()).reduce((acc, cur) => {\n\t\tconst [key, value] = cur.split('=');\n\t\tacc[key] = value;\n\t\treturn acc;\n\t}, {});\n\n\tlet cookieChanged = false;\n\tconst hints = [\n\t${Object.values(hints)\n .map((hint) => {\n const cookieName = JSON.stringify(hint.cookieName);\n return `{ name: ${cookieName}, actual: String(${hint.getValueCode}), value: cookies[${cookieName}] != null ? cookies[${cookieName}] : encodeURIComponent(\"${hint.fallback}\") }`;\n })\n .join(',\\n')}\n\t];\n\tfor (const hint of hints) {\n\t\tdocument.cookie = encodeURIComponent(hint.name) + '=' + encodeURIComponent(hint.actual) + '; Max-Age=31536000; path=/';\n\t\tif (decodeURIComponent(hint.value) !== hint.actual) {\n\t\t\tcookieChanged = true;\n\t\t}\n\t}\n\tif (cookieChanged) window.location.reload();\n}\n\ncheckClientHints();\n`;\n }\n return { getHints, getClientHintCheckScript };\n}\n","export const clientHint = {\n cookieName: 'CH-prefers-color-scheme',\n getValueCode: `window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'`,\n fallback: 'light',\n transform(value) {\n return value === 'dark' ? 'dark' : 'light';\n },\n};\n/**\n * Subscribe to changes in the user's color scheme preference. Optionally pass\n * in a cookie name to use for the cookie that will be set if different from the\n * default.\n */\nexport function subscribeToSchemeChange(subscriber, cookieName = clientHint.cookieName) {\n const schemaMatch = window.matchMedia('(prefers-color-scheme: dark)');\n function handleThemeChange() {\n const value = schemaMatch.matches ? 'dark' : 'light';\n document.cookie = `${cookieName}=${value}; Max-Age=31536000; Path=/`;\n subscriber(value);\n }\n schemaMatch.addEventListener('change', handleThemeChange);\n return function cleanupSchemaChange() {\n schemaMatch.removeEventListener('change', handleThemeChange);\n };\n}\n","export const clientHint = {\n cookieName: 'CH-reduced-motion',\n getValueCode: `window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'reduce' : 'no-preference'`,\n fallback: 'no-preference',\n transform(value) {\n return value === 'reduce' ? 'reduce' : 'no-preference';\n },\n};\n/**\n * Subscribe to changes in the user's motion preference. Optionally pass\n * in a cookie name to use for the cookie that will be set if different from the\n * default.\n */\nexport function subscribeToMotionChange(subscriber, cookieName = clientHint.cookieName) {\n const motionMatch = window.matchMedia('(prefers-reduced-motion: reduce)');\n function handleMotionChange() {\n const value = motionMatch.matches ? 'reduce' : 'no-preference';\n document.cookie = `${cookieName}=${value}; Max-Age=31536000; Path=/`;\n subscriber(value);\n }\n motionMatch.addEventListener('change', handleMotionChange);\n return function cleanupMotionChange() {\n motionMatch.removeEventListener('change', handleMotionChange);\n };\n}\n","export const clientHint = {\n cookieName: 'CH-time-zone',\n getValueCode: 'Intl.DateTimeFormat().resolvedOptions().timeZone',\n fallback: 'UTC',\n};\n","/**\n * This file contains utilities for using client hints for user preference which\n * are needed by the server, but are only known by the browser.\n */\nimport { getHintUtils } from '@epic-web/client-hints'\nimport {\n\tclientHint as colorSchemeHint,\n\tsubscribeToSchemeChange,\n} from '@epic-web/client-hints/color-scheme'\nimport {\n\tclientHint as reducedMotionHint,\n\tsubscribeToMotionChange,\n} from '@epic-web/client-hints/reduced-motion'\nimport { clientHint as timeZoneHint } from '@epic-web/client-hints/time-zone'\nimport { useRevalidator } from '@remix-run/react'\nimport * as React from 'react'\nimport { useRequestInfo } from './request-info.ts'\n\nconst themeCookieName = 'EpicShop_CH-prefers-color-scheme'\nconst motionCookieName = 'EpicShop_CH-reduced-motion'\nconst hintsUtils = getHintUtils({\n\ttheme: {\n\t\t...colorSchemeHint,\n\t\tcookieName: themeCookieName,\n\t},\n\ttimeZone: {\n\t\t...timeZoneHint,\n\t\tcookieName: 'EpicShop_CH-time-zone',\n\t},\n\treducedMotion: {\n\t\t...reducedMotionHint,\n\t\tcookieName: motionCookieName,\n\t},\n\t// add other hints here\n})\n\nexport const { getHints } = hintsUtils\n\n/**\n * @returns an object with the client hints and their values\n */\nexport function useHints() {\n\tconst requestInfo = useRequestInfo()\n\treturn requestInfo.hints\n}\n\n/**\n * @returns inline script element that checks for client hints and sets cookies\n * if they are not set then reloads the page if any cookie was set to an\n * inaccurate value.\n */\nexport function ClientHintCheck() {\n\tconst { revalidate } = useRevalidator()\n\tReact.useEffect(\n\t\t() => subscribeToSchemeChange(() => revalidate(), themeCookieName),\n\t\t[revalidate],\n\t)\n\tReact.useEffect(\n\t\t() => subscribeToMotionChange(() => revalidate(), motionCookieName),\n\t\t[revalidate],\n\t)\n\n\treturn (\n\t\t<script\n\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t__html: hintsUtils.getClientHintCheckScript(),\n\t\t\t}}\n\t\t/>\n\t)\n}\n"],"names":["getHintUtils","hints","getCookieValue","cookieString","name","hint","value","_a","getHints","request","acc","hintName","getClientHintCheckScript","cookieName","clientHint","subscribeToSchemeChange","subscriber","schemaMatch","handleThemeChange","subscribeToMotionChange","motionMatch","handleMotionChange","themeCookieName","motionCookieName","hintsUtils","colorSchemeHint","timeZoneHint","reducedMotionHint","useHints","useRequestInfo","ClientHintCheck","revalidate","useRevalidator","React.useEffect","jsx"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var Lt=Object.defineProperty;var Tt=(e,t,r)=>t in e?Lt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var G=(e,t,r)=>Tt(e,typeof t!="symbol"?t+"":t,r);import{r as l,
|
|
1
|
+
var Lt=Object.defineProperty;var Tt=(e,t,r)=>t in e?Lt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var G=(e,t,r)=>Tt(e,typeof t!="symbol"?t+"":t,r);import{r as l,l as Pt,u as B,d as Ye,N as X,o as Ot,p as We,q as j,s as ie,t as Ct,v as ge,w as M,D as be,x as oe,y as kt,z as At,A as _e,I as Dt,B as Ve,C as Ne,k as Nt,c as Ft,F as It,G as $t,H as jt,J as Ke,E as ae,i as Ut,a as Mt,m as Xe,K as Ht,L as Bt,M as Jt,P as zt}from"./index-1cKOJFpX.js";function Yt(e,t){for(var r=0;r<t.length;r++){const n=t[r];if(typeof n!="string"&&!Array.isArray(n)){for(const a in n)if(a!=="default"&&!(a in e)){const i=Object.getOwnPropertyDescriptor(n,a);i&&Object.defineProperty(e,a,i.get?i:{enumerable:!0,get:()=>n[a]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}var Ge={exports:{}},C={};/**
|
|
2
2
|
* @license React
|
|
3
3
|
* react-dom.production.js
|
|
4
4
|
*
|
|
@@ -163,4 +163,4 @@ ${h?`window.__remixManifest = ${JSON.stringify(xn(t,u),null,2)};`:""}
|
|
|
163
163
|
window.__remixRouteModules = {${y.map((T,N)=>`${JSON.stringify(T.route.id)}:route${N}`).join(",")}};
|
|
164
164
|
|
|
165
165
|
import(${JSON.stringify(t.entry.module)});`:" ";return l.createElement(l.Fragment,null,l.createElement("script",P({},e,{suppressHydrationWarning:!0,dangerouslySetInnerHTML:Me(_),type:void 0})),l.createElement("script",P({},e,{suppressHydrationWarning:!0,dangerouslySetInnerHTML:Me(k),type:"module",async:!0})))},[]);if(!c&&typeof __remixContext=="object"&&__remixContext.a)for(let S=0;S<__remixContext.a;S++)p.push(l.createElement(ze,{key:S,scriptProps:e,serializeData:b,serializeError:R}));let g=y.map(S=>{let E=t.routes[S.route.id];return(E.imports||[]).concat([E.module])}).flat(1),x=ne?[]:t.entry.imports.concat(g);return ne?null:l.createElement(l.Fragment,null,h?null:l.createElement("link",{rel:"modulepreload",href:t.url,crossOrigin:e.crossOrigin}),l.createElement("link",{rel:"modulepreload",href:t.entry.module,crossOrigin:e.crossOrigin}),In(x).map(S=>l.createElement("link",{key:S,rel:"modulepreload",href:S,crossOrigin:e.crossOrigin})),w,p)}function ze({dataKey:e,deferredData:t,routeId:r,scriptProps:n,serializeData:a,serializeError:i}){return typeof document>"u"&&t&&e&&r&&H(t.pendingKeys.includes(e),`Deferred data for route ${r} with key ${e} was not pending but tried to render a script for it.`),l.createElement(l.Suspense,{fallback:typeof document>"u"&&t&&e&&r?null:l.createElement("script",P({},n,{async:!0,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:" "}}))},typeof document>"u"&&t&&e&&r?l.createElement(Dn,{resolve:t.data[e],errorElement:l.createElement(Fn,{dataKey:e,routeId:r,scriptProps:n,serializeError:i}),children:s=>l.createElement("script",P({},n,{async:!0,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:a(r,e,s)}}))}):l.createElement("script",P({},n,{async:!0,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:" "}})))}function Fn({dataKey:e,routeId:t,scriptProps:r,serializeError:n}){let a=Jt();return l.createElement("script",P({},r,{suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:n(t,e,a)}}))}function In(e){return[...new Set(e)]}function Zn(){return Ht()}function Qn(e){return zt(e)}function qn(e={}){return br(e)}function xt(...e){return t=>{e.forEach(r=>{typeof r=="function"?r(t):r!=null&&(r.current=t)})}}export{Dn as A,vr as F,On as L,Gn as M,Pn as N,Kt as R,Nn as S,P as _,qn as a,Hn as b,Bn as c,Qn as d,at as e,Wn as f,pn as g,Ce as h,H as i,Vn as j,zn as k,Kn as l,Rt as m,Yn as n,Mn as o,z as p,Jn as q,qe as r,bn as s,Xn as t,Zn as u};
|
|
166
|
-
//# sourceMappingURL=components-
|
|
166
|
+
//# sourceMappingURL=components-C17zb3Us.js.map
|