@epic-web/workshop-app 4.3.0 → 4.4.0
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/_layout-BnXo_nCX.js +2 -0
- package/build/client/assets/_layout-BnXo_nCX.js.map +1 -0
- package/build/client/assets/{manifest-0d62be17.js → manifest-71ff3c7f.js} +1 -1
- package/build/server/index.js +2 -2
- package/build/server/index.js.map +1 -1
- package/package.json +3 -3
- package/build/client/assets/_layout-PTTX5RMb.js +0 -2
- package/build/client/assets/_layout-PTTX5RMb.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epic-web/workshop-app",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@epic-web/invariant": "^1.0.0",
|
|
43
43
|
"@epic-web/remember": "^1.0.2",
|
|
44
44
|
"@epic-web/restore-scroll": "^1.0.1",
|
|
45
|
-
"@epic-web/workshop-presence": "4.
|
|
46
|
-
"@epic-web/workshop-utils": "4.
|
|
45
|
+
"@epic-web/workshop-presence": "4.4.0",
|
|
46
|
+
"@epic-web/workshop-utils": "4.4.0",
|
|
47
47
|
"@mdx-js/mdx": "^3.0.1",
|
|
48
48
|
"@mux/mux-player-react": "^2.3.3",
|
|
49
49
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as N,j as e,O as K,b as Q}from"./index-D1WEsmVZ.js";import{c as b}from"./clsx-B-dksMZM.js";import{b as q,s as Y,c as X,d as Z,e as M,m as h,u as ee,f as te}from"./progress-CBZt2pmu.js";import{T as se}from"./index-HBgMKyVf.js";import{c as u,I as v}from"./misc-CXGQ7VS9.js";import{S as I,T as ne,a as $,b as D,c as V}from"./tooltip-CVFWPOu0.js";import{b as L}from"./user-DiGtbaa7.js";import{a as O}from"./presence-B2xpI37C.js";import{L as f,u as ae,N as W}from"./components-Dj3sm47B.js";import"./request-info-BHMoxBaT.js";import"./client-hints-BsCjbOX0.js";function re(t){t.values.forEach(s=>s.stop())}function _(t,s){[...s].reverse().forEach(o=>{const l=t.getVariant(o);l&&Y(t,l),t.variantChildren&&t.variantChildren.forEach(r=>{_(r,s)})})}function oe(t,s){if(Array.isArray(s))return _(t,s);if(typeof s=="string")return _(t,[s]);Y(t,s)}function le(){const t=new Set,s={subscribe(n){return t.add(n),()=>void t.delete(n)},start(n,o){const l=[];return t.forEach(r=>{l.push(q(r,n,{transitionOverride:o}))}),Promise.all(l)},set(n){return t.forEach(o=>{oe(o,n)})},stop(){t.forEach(n=>{re(n)})},mount(){return()=>{s.stop()}}};return s}function S(){const t=X(le);return Z(t.mount,[]),t}const H=["opacity-70","opacity-80","opacity-90","opacity-100"],U=["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 A(t){const s=Math.round(t*H.length-1),n=Math.round(t*U.length-1);return u("shadow-purple-700 hover:opacity-100 focus:opacity-100 dark:shadow-purple-200",H[s]??"opacity-60",U[n]??"shadow-none",t===1?"animate-pulse hover:animate-none focus:animate-none":null)}function ie({isMenuOpened:t}){const s=L(),{users:n}=O(),o=t?17:0,l=n.length-o;if(!n.length)return null;const r=t&&n.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:u("h-8 w-8 rounded-full border object-cover",A(1)),src:"/img/tiffany.png"})}):null,m=`${l}${t?" more ":" "}Epic Web Dev${l===1?"":"s"} working now`;return e.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.jsxs(ne,{children:[n.slice(0,o).map(({user:a,score:c})=>{var x,g;const p=A(c),d=ce(a.location);return e.jsxs($,{children:[e.jsx(D,{asChild:!0,children:a.avatarUrl?e.jsx("img",{tabIndex:0,alt:a.name||"Epic Web Dev",className:u("h-8 w-8 rounded-full border object-cover",p),src:a.avatarUrl}):e.jsx("div",{tabIndex:0,"aria-label":a.name||"Epic Web Dev",className:u("flex h-8 w-8 items-center justify-center rounded-full border",p),children:e.jsx(v,{name:"User"})})}),e.jsx(V,{children:e.jsxs("span",{className:"flex flex-col items-center justify-center gap-1",children:[e.jsxs("span",{children:[a.name||"An EPIC Web Dev"," ",d?` is ${(g=(x=a.location)==null?void 0:x.origin)!=null&&g.includes("epicweb.dev")?"learning":"working"} ${c===1&&(s==null?void 0:s.id)!==a.id?"with you":""} on`:null]}),d!=null&&d.line1?e.jsx("span",{children:d.line1}):null,d!=null&&d.line2?e.jsx("span",{children:d.line2}):null]})})]},a.id)}),r,l>0?e.jsxs($,{children:[e.jsx(D,{asChild:!0,children:e.jsx("div",{tabIndex:0,"aria-label":m,className:u("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:u("pointer-events-none overflow-hidden text-ellipsis whitespace-nowrap text-center",t?"w-8":"w-6"),children:t?`+${l}`:l})})}),e.jsx(V,{children:m})]}):null]})})}function Ce(){const t=L(),[s,n]=N.useState(!1);return e.jsxs("div",{className:"flex flex-col",children:[t?null:e.jsx(de,{}),e.jsxs("div",{className:u("flex flex-grow",{"h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))]":!t,"h-[calc(100vh-112px-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))]":ENV.EPICSHOP_DEPLOYED,"h-[calc(100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))]":t}),children:[e.jsx(ue,{isMenuOpened:s,onMenuOpenChange:n}),e.jsx("div",{className:u("h-full w-full max-w-[calc(100%-56px)]",s?"hidden md:block":""),children:e.jsx(K,{})})]})]})}function ce(t){if(!t)return null;const{exercise:s}=t,n=[s?[s.exerciseNumber,s.stepNumber].filter(Boolean).map(o=>o.toString().padStart(2,"0")).join("/"):null,s==null?void 0:s.type].filter(Boolean).join(" - ");return{line1:t.workshopTitle,line2:n}}function de(){return e.jsxs("div",{className:u("z-10 flex items-center justify-between border-b bg-gradient-to-tr from-blue-500 to-indigo-500 pl-4 text-white",ENV.EPICSHOP_DEPLOYED?"h-[112px] md:h-[64px]":"h-16"),children:[e.jsxs("div",{className:"flex flex-1 flex-wrap items-center gap-4",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!"]}),ENV.EPICSHOP_DEPLOYED?e.jsxs("small",{className:"text-sm",children:["This is the deployed version."," ",ENV.EPICSHOP_GITHUB_ROOT?e.jsx(f,{className:"underline",target:"_blank",rel:"noopener noreferrer",to:ENV.EPICSHOP_GITHUB_ROOT,children:"Run locally"}):null," ","for full experience."]}):null]})]}),e.jsxs("div",{className:"flex h-full flex-col items-center 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"})]})]})]})}const B={hidden:{opacity:0,x:-20},visible:{opacity:1,x:0}};function fe({exerciseNumber:t,children:s}){const n=ee(t);return e.jsx(h.li,{variants:B,className:u("py-[6px] first:pt-3 last:pb-3",n?`${n} before:border-t`:null),children:e.jsx("span",{className:"ml-2",children:s})})}function k({children:t,...s}){const n=te(s);return e.jsx(h.li,{variants:B,className:u("py-[6px] first:pt-3 last:pb-3",n?`${n} before:border-t`:null),children:e.jsx("span",{className:"ml-2",children:t})})}const P=400;function ue({isMenuOpened:t,onMenuOpenChange:s}){const n=ae(),o=L(),l=M(),r=Q(),{users:m}=O(),a=n.exercises.find(i=>i.exerciseNumber===Number(r.exerciseNumber)),c=r.type==="solution"?a==null?void 0:a.solutions.find(i=>i.stepNumber===Number(r.stepNumber)):r.type==="problem"?a==null?void 0:a.problems.find(i=>i.stepNumber===Number(r.stepNumber)):null,p=S(),d={close:{width:56},open:{width:P}},x={visible:{opacity:1,transition:{duration:.05,when:"beforeChildren",staggerChildren:.03}},hidden:{opacity:0}},g=Number(r.exerciseNumber).toString().padStart(2,"0");return e.jsx("nav",{className:"flex border-r",children:e.jsx(h.div,{initial:t?"open":"close",variants:d,animate:p,children:e.jsxs("div",{className:"flex h-full flex-col items-center justify-between",children:[e.jsx(he,{title:n.workshopTitle,menuControls:p,isMenuOpened:t,setMenuOpened:s}),t&&e.jsxs(h.div,{style:{width:P},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(h.ul,{variants:x,initial:"hidden",animate:"visible",className:"flex flex-col",children:n.exercises.map(({exerciseNumber:i,title:R,steps:z})=>{const y=Number(r.exerciseNumber)===i,F=!y&&n.playground.exerciseNumber===i,w=i.toString().padStart(2,"0");return e.jsxs(fe,{exerciseNumber:i,children:[e.jsxs(f,{prefetch:"intent",to:`/${w}`,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":y}),children:[R,F?" 🛝":null]}),y?e.jsxs(h.ul,{variants:x,initial:"hidden",animate:"visible",className:"ml-4 mt-4 flex flex-col",children:[e.jsx(k,{type:"instructions",exerciseNumber:i,children:e.jsx(f,{to:`/${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":!r.stepNumber}),children:"Intro"})},i),z.filter(Boolean).map(({name:E,stepNumber:j,title:T})=>{const G=Number(r.stepNumber)===j,C=j.toString().padStart(2,"0"),J=E===n.playground.appName;return e.jsx(k,{type:"step",stepNumber:j,exerciseNumber:i,children:e.jsx(f,{to:`/${w}/${C}`,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":G}),children:J?`${C}. ${T} 🛝`:`${C}. ${T}`})},j)}),e.jsx(k,{type:"finished",exerciseNumber:i,children:e.jsx(W,{to:`/${w}/finished`,prefetch:"intent",className:({isActive:E})=>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":E}),children:"📝 Elaboration"})})]}):null]},i)})}),e.jsx("div",{className:"mt-6",children:e.jsx(W,{to:"/finished",className:({isActive:i})=>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-[""]':i}),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:[a!=null&&a.title?e.jsx(f,{to:`/${g}`,children:a.title}):null,a!=null&&a.title&&(c!=null&&c.title)?" — ":null,c!=null&&c.title?e.jsx(f,{to:`/${g}/${c.stepNumber.toString().padStart(2,"0")}`,children:c.title}):null]})}),e.jsx("div",{className:u("flex w-full items-center justify-start border-t p-4 transition-[height]",t&&m.length>4?"h-28":"h-14"),style:t?{width:P}:{},children:e.jsx(ie,{isMenuOpened:t})}),ENV.EPICSHOP_DEPLOYED?null:o?e.jsx(I,{content:t?null:"Your account",children:e.jsxs(f,{className:"flex h-14 w-full items-center justify-start space-x-3 border-t px-4 py-4 text-center no-underline hover:underline",to:"/account",children:[o.avatarUrl?e.jsx("img",{alt:o.name??o.email,src:o.avatarUrl,className:"h-full rounded-full"}):e.jsx(v,{name:"User",className:"flex-shrink-0",size:"lg"}),t?e.jsx(h.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:o&&l?e.jsx(I,{content:t?null:"Continue to next lesson",children:e.jsxs(f,{to:l,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(h.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(se,{})})]})})})}function he({title:t,isMenuOpened:s,setMenuOpened:n,menuControls:o}){const l={open:{d:"M3.06061 2.99999L21.0606 21"},closed:{d:"M0 9.5L24 9.5"}},r={open:{d:"M3.00006 21.0607L21 3.06064"},moving:{d:"M0 14.5L24 14.5"},closed:{d:"M0 14.5L15 14.5"}},m=S(),a=S();async function c(){o.start(s?"close":"open"),n(!s),s?(m.start(l.closed),await a.start(r.moving),a.start(r.closed)):(await a.start(r.moving),m.start(l.open),a.start(r.open))}const p=N.useRef(c);return N.useEffect(()=>{p.current=c}),N.useEffect(()=>{if(!s)return;function d(x){x.key==="Escape"&&p.current()}return document.addEventListener("keyup",d),()=>document.removeEventListener("keyup",d)},[s]),e.jsxs("div",{className:"relative inline-flex h-14 w-full items-center justify-between overflow-hidden border-b",children:[e.jsx("button",{className:"flex h-14 w-14 items-center justify-center","aria-label":"Open Navigation menu",onClick:c,children:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",children:[e.jsx(h.path,{...l.closed,animate:m,transition:{duration:.2},stroke:"currentColor",strokeWidth:1.5}),e.jsx(h.path,{...r.closed,animate:a,transition:{duration:.2},stroke:"currentColor",strokeWidth:1.5})]})}),s&&e.jsx(h.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{Ce as default};
|
|
2
|
-
//# sourceMappingURL=_layout-PTTX5RMb.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_layout-PTTX5RMb.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/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 {\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\ttype LoaderFunctionArgs,\n\ttype HeadersFunction,\n\tjson,\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\ttype AnimationControls,\n\tmotion,\n\tuseAnimationControls,\n} from 'framer-motion'\nimport * as React from 'react'\nimport {\n\tuseNextExerciseRoute,\n\tuseExerciseProgressClassName,\n\ttype ProgressItemSearch,\n\tuseProgressItemClassName,\n} from '../progress.tsx'\nimport { ThemeSwitch } from '../theme/index.tsx'\nimport { Icon } from '#app/components/icons.tsx'\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 { type User, usePresence } from '#app/utils/presence.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\nexport default function App() {\n\tconst user = useOptionalUser()\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<div\n\t\t\t\tclassName={cn('flex flex-grow', {\n\t\t\t\t\t'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-112px-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\tENV.EPICSHOP_DEPLOYED,\n\t\t\t\t\t'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})}\n\t\t\t>\n\t\t\t\t<Navigation\n\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\tonMenuOpenChange={setMenuOpened}\n\t\t\t\t/>\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-[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\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'z-10 flex items-center justify-between border-b bg-gradient-to-tr from-blue-500 to-indigo-500 pl-4 text-white',\n\t\t\t\tENV.EPICSHOP_DEPLOYED ? 'h-[112px] md:h-[64px]' : 'h-16',\n\t\t\t)}\n\t\t>\n\t\t\t<div className=\"flex flex-1 flex-wrap items-center gap-4\">\n\t\t\t\t<Icon name=\"EpicWeb\" size=\"lg\" />\n\t\t\t\t<div className=\"flex flex-1 flex-wrap items-center\">\n\t\t\t\t\t<p className=\"mr-2\">\n\t\t\t\t\t\tWelcome to the{' '}\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\tclassName=\"underline\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tEpicWeb.dev\n\t\t\t\t\t\t</Link>{' '}\n\t\t\t\t\t\tWorkshop app!\n\t\t\t\t\t</p>\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? (\n\t\t\t\t\t\t<small className=\"text-sm\">\n\t\t\t\t\t\t\tThis is the deployed version.{' '}\n\t\t\t\t\t\t\t{ENV.EPICSHOP_GITHUB_ROOT ? (\n\t\t\t\t\t\t\t\t<Link\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\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\tto={ENV.EPICSHOP_GITHUB_ROOT}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRun locally\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t) : null}{' '}\n\t\t\t\t\t\t\tfor full experience.\n\t\t\t\t\t\t</small>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"flex h-full flex-col items-center md:flex-row\">\n\t\t\t\t<Link\n\t\t\t\t\tto=\"https://www.epicweb.dev\"\n\t\t\t\t\ttarget=\"_blank\"\n\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>\n\t\t\t\t\t<span className=\"drop-shadow-sm\">Join Epic Web</span>\n\t\t\t\t\t<span>↗︎</span>\n\t\t\t\t</Link>\n\t\t\t\t<Link\n\t\t\t\t\tto={\n\t\t\t\t\t\tENV.EPICSHOP_DEPLOYED ? 'https://www.epicweb.dev/login' : '/login'\n\t\t\t\t\t}\n\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>\n\t\t\t\t\t<Icon name=\"User\" size=\"lg\" />\n\t\t\t\t\t<span className=\"drop-shadow-sm\">Login</span>\n\t\t\t\t</Link>\n\t\t\t</div>\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\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\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\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\te => 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\ts => 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\tp => 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=\"flex border-r\">\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\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\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\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 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\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\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 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\tconst latestToggleMenu = React.useRef(toggleMenu)\n\tReact.useEffect(() => {\n\t\tlatestToggleMenu.current = toggleMenu\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\tvoid latestToggleMenu.current()\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 className=\"relative inline-flex h-14 w-full items-center justify-between overflow-hidden border-b\">\n\t\t\t<button\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\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","opacities","shadows","getScoreClassNames","score","opacityNumber","shadowNumber","cn","FacePile","isMenuOpened","loggedInUser","useOptionalUser","users","usePresence","limit","numberOverLimit","tiffany","jsx","Link","overLimitLabel","jsxs","TooltipProvider","user","scoreClassNames","locationLabel","getLocationLabel","Tooltip","TooltipTrigger","Icon","TooltipContent","_b","_a","headers","setMenuOpened","React.useState","EpicWebBanner","Navigation","Outlet","location","exercise","exercisePortion","s","itemVariants","NavigationExerciseListItem","exerciseNumber","children","progressClassName","motion","progressItemSearch","useProgressItemClassName","OPENED_MENU_WIDTH","data","useLoaderData","nextExerciseRoute","useNextExerciseRoute","params","useParams","e","app","p","menuControls","menuVariants","listVariants","exNum","NavToggle","title","steps","isActive","showPlayground","exerciseNum","clsx","NavigationExerciseStepListItem","name","stepNumber","title2","isPlayground","step","isActive2","NavLink","SimpleTooltip","ThemeSwitch","path01Variants","path02Variants","path01Controls","path02Controls","toggleMenu","latestToggleMenu","React.useRef","React.useEffect","handleKeyUp","event"],"mappings":"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","x_google_ignoreList":[0,1]}
|