@epic-web/workshop-app 4.14.1 → 4.16.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/{_exerciseNumber-Ccwr4LZw.js → _exerciseNumber-BLQUCLPr.js} +2 -2
- package/build/client/assets/{_exerciseNumber-Ccwr4LZw.js.map → _exerciseNumber-BLQUCLPr.js.map} +1 -1
- package/build/client/assets/{_exerciseNumber_.finished-gEWcHsfL.js → _exerciseNumber_.finished-C9TSc48F.js} +2 -2
- package/build/client/assets/{_exerciseNumber_.finished-gEWcHsfL.js.map → _exerciseNumber_.finished-C9TSc48F.js.map} +1 -1
- package/build/client/assets/_layout-B789acDk.js +6 -0
- package/build/client/assets/_layout-B789acDk.js.map +1 -0
- package/build/client/assets/_layout-CZ3fjUvs.js +2 -0
- package/build/client/assets/_layout-CZ3fjUvs.js.map +1 -0
- package/build/client/assets/_layout-DLIzcS5v.js +2 -0
- package/build/client/assets/_layout-DLIzcS5v.js.map +1 -0
- package/build/client/assets/{_layout-Bn9QhWq9.js → _layout-DMuKczTu.js} +2 -2
- package/build/client/assets/{_layout-Bn9QhWq9.js.map → _layout-DMuKczTu.js.map} +1 -1
- package/build/client/assets/account-LnI_Eq0t.js +2 -0
- package/build/client/assets/account-LnI_Eq0t.js.map +1 -0
- package/build/client/assets/{diff-CpG96hGZ.js → diff-4FQLirNf.js} +2 -2
- package/build/client/assets/{diff-CpG96hGZ.js.map → diff-4FQLirNf.js.map} +1 -1
- package/build/client/assets/{diff-Bd9WnUnR.js → diff-CPrD1rHd.js} +2 -2
- package/build/client/assets/{diff-Bd9WnUnR.js.map → diff-CPrD1rHd.js.map} +1 -1
- package/build/client/assets/discord-BgaWmFRC.js +2 -0
- package/build/client/assets/discord-BgaWmFRC.js.map +1 -0
- package/build/client/assets/discord-Dk1wbXOn.js +2 -0
- package/build/client/assets/discord-Dk1wbXOn.js.map +1 -0
- package/build/client/assets/{epic-video-DJN9_SUj.js → epic-video-CfelX9-n.js} +2 -2
- package/build/client/assets/{epic-video-DJN9_SUj.js.map → epic-video-CfelX9-n.js.map} +1 -1
- package/build/client/assets/finished-C0mN8TiU.js +2 -0
- package/build/client/assets/finished-C0mN8TiU.js.map +1 -0
- package/build/client/assets/{index-3HxjMIAS.js → index-De7yI02n.js} +2 -2
- package/build/client/assets/{index-3HxjMIAS.js.map → index-De7yI02n.js.map} +1 -1
- package/build/client/assets/login-SJlLMYmL.js +2 -0
- package/build/client/assets/login-SJlLMYmL.js.map +1 -0
- package/build/client/assets/{manifest-1375f1dd.js → manifest-38193299.js} +1 -1
- package/build/client/assets/mdx-CQW0I4So.js +2 -0
- package/build/client/assets/mdx-CQW0I4So.js.map +1 -0
- package/build/client/assets/onboarding-BXGyEPXy.js +2 -0
- package/build/client/assets/onboarding-BXGyEPXy.js.map +1 -0
- package/build/client/assets/robots_._txt-l0sNRNKZ.js +2 -0
- package/build/client/assets/robots_._txt-l0sNRNKZ.js.map +1 -0
- package/build/client/assets/root-BUqeXmeK.js.map +1 -1
- package/build/client/assets/sitemap_._xml-l0sNRNKZ.js +2 -0
- package/build/client/assets/sitemap_._xml-l0sNRNKZ.js.map +1 -0
- package/build/client/assets/support-DilzTPHE.js +2 -0
- package/build/client/assets/support-DilzTPHE.js.map +1 -0
- package/build/server/index.js +982 -925
- package/build/server/index.js.map +1 -1
- package/dist/server/index.js +18 -5
- package/package.json +5 -3
- package/start.js +1 -23
- package/build/client/assets/_layout-B9Y-8OU6.js +0 -2
- package/build/client/assets/_layout-B9Y-8OU6.js.map +0 -1
- package/build/client/assets/_layout-DaZNLfOL.js +0 -2
- package/build/client/assets/_layout-DaZNLfOL.js.map +0 -1
- package/build/client/assets/_layout-dHX2Hcew.js +0 -6
- package/build/client/assets/_layout-dHX2Hcew.js.map +0 -1
- package/build/client/assets/account-uvU1jIL2.js +0 -2
- package/build/client/assets/account-uvU1jIL2.js.map +0 -1
- package/build/client/assets/discord-CgwNGD2p.js +0 -2
- package/build/client/assets/discord-CgwNGD2p.js.map +0 -1
- package/build/client/assets/discord-yZor-3t1.js +0 -2
- package/build/client/assets/discord-yZor-3t1.js.map +0 -1
- package/build/client/assets/finished-B9qjUR4B.js +0 -2
- package/build/client/assets/finished-B9qjUR4B.js.map +0 -1
- package/build/client/assets/login-CHE9W6po.js +0 -2
- package/build/client/assets/login-CHE9W6po.js.map +0 -1
- package/build/client/assets/mdx-BENF-kTQ.js +0 -2
- package/build/client/assets/mdx-BENF-kTQ.js.map +0 -1
- package/build/client/assets/onboarding-FD1FkQuu.js +0 -2
- package/build/client/assets/onboarding-FD1FkQuu.js.map +0 -1
- package/build/client/assets/support-D1ydJNdm.js +0 -2
- package/build/client/assets/support-D1ydJNdm.js.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -2,7 +2,11 @@ import fs from "fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
import { getPresentUsers } from "@epic-web/workshop-presence/presence.server";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getApps,
|
|
7
|
+
getWorkshopRoot,
|
|
8
|
+
init as initApps
|
|
9
|
+
} from "@epic-web/workshop-utils/apps.server";
|
|
6
10
|
import { getWatcher } from "@epic-web/workshop-utils/change-tracker.server";
|
|
7
11
|
import { checkForUpdates } from "@epic-web/workshop-utils/git.server";
|
|
8
12
|
import { createRequestHandler } from "@remix-run/express";
|
|
@@ -16,6 +20,8 @@ import getPort, { portNumbers } from "get-port";
|
|
|
16
20
|
import morgan from "morgan";
|
|
17
21
|
import sourceMapSupport from "source-map-support";
|
|
18
22
|
import { WebSocket, WebSocketServer } from "ws";
|
|
23
|
+
const MODE = process.env.NODE_ENV ?? "development";
|
|
24
|
+
initApps();
|
|
19
25
|
installGlobals();
|
|
20
26
|
sourceMapSupport.install();
|
|
21
27
|
const viteDevServer = process.env.NODE_ENV === "production" ? null : await import("vite").then(
|
|
@@ -82,13 +88,20 @@ app.use((req, res, next) => {
|
|
|
82
88
|
}
|
|
83
89
|
next();
|
|
84
90
|
});
|
|
91
|
+
async function getBuild() {
|
|
92
|
+
const build = viteDevServer ? viteDevServer.ssrLoadModule("virtual:remix/server-build") : (
|
|
93
|
+
// @ts-ignore this should exist before running the server
|
|
94
|
+
// but it may not exist just yet.
|
|
95
|
+
await import("#build/server/index.js")
|
|
96
|
+
);
|
|
97
|
+
return build;
|
|
98
|
+
}
|
|
85
99
|
app.all(
|
|
86
100
|
"*",
|
|
87
101
|
createRequestHandler({
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
)
|
|
102
|
+
getLoadContext: () => ({ serverBuild: getBuild() }),
|
|
103
|
+
mode: MODE,
|
|
104
|
+
build: getBuild
|
|
92
105
|
})
|
|
93
106
|
);
|
|
94
107
|
const desiredPort = Number(process.env.PORT || 5639);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epic-web/workshop-app",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.16.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -44,10 +44,11 @@
|
|
|
44
44
|
"@epic-web/invariant": "^1.0.0",
|
|
45
45
|
"@epic-web/remember": "^1.0.2",
|
|
46
46
|
"@epic-web/restore-scroll": "^1.1.1",
|
|
47
|
-
"@epic-web/workshop-presence": "4.
|
|
48
|
-
"@epic-web/workshop-utils": "4.
|
|
47
|
+
"@epic-web/workshop-presence": "4.16.0",
|
|
48
|
+
"@epic-web/workshop-utils": "4.16.0",
|
|
49
49
|
"@mdx-js/mdx": "^3.0.1",
|
|
50
50
|
"@mux/mux-player-react": "^2.6.0",
|
|
51
|
+
"@nasa-gcn/remix-seo": "^2.0.1",
|
|
51
52
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
52
53
|
"@radix-ui/react-accordion": "^1.1.2",
|
|
53
54
|
"@radix-ui/react-dialog": "^1.0.5",
|
|
@@ -120,6 +121,7 @@
|
|
|
120
121
|
"unified": "^11.0.4",
|
|
121
122
|
"unist-util-remove-position": "^5.0.0",
|
|
122
123
|
"unist-util-visit": "^5.0.0",
|
|
124
|
+
"vite-env-only": "^3.0.3",
|
|
123
125
|
"ws": "^8.17.0",
|
|
124
126
|
"zod": "^3.23.8"
|
|
125
127
|
},
|
package/start.js
CHANGED
|
@@ -1,34 +1,12 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
1
|
import path from 'path'
|
|
3
2
|
import dotenv from 'dotenv'
|
|
4
3
|
|
|
4
|
+
process.env.NODE_ENV ??= 'development'
|
|
5
5
|
const EPICSHOP_CONTEXT_CWD = process.env.EPICSHOP_CONTEXT_CWD ?? process.cwd()
|
|
6
6
|
dotenv.config({
|
|
7
7
|
path: path.join(EPICSHOP_CONTEXT_CWD, '.env'),
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
-
let packageJson
|
|
11
|
-
try {
|
|
12
|
-
packageJson = JSON.parse(
|
|
13
|
-
await fs.promises.readFile(
|
|
14
|
-
path.join(EPICSHOP_CONTEXT_CWD, 'package.json'),
|
|
15
|
-
'utf8',
|
|
16
|
-
),
|
|
17
|
-
)
|
|
18
|
-
} catch {
|
|
19
|
-
throw new Error(
|
|
20
|
-
`Could not find and parse package.json at ${EPICSHOP_CONTEXT_CWD}`,
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (packageJson.epicshop.githubRoot) {
|
|
25
|
-
process.env.EPICSHOP_GITHUB_ROOT = packageJson.epicshop.githubRoot
|
|
26
|
-
} else {
|
|
27
|
-
throw new Error(
|
|
28
|
-
`Could not set the EPICSHOP_GITHUB_ROOT environment variable. Please set it to the URL of your GitHub repo in the "epicshop.githubRoot" property of the package.json.`,
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
10
|
if (process.env.NODE_ENV === 'production') {
|
|
33
11
|
await import('./dist/server/index.js').catch((err) => {
|
|
34
12
|
console.error('Encountered error importing the server, exiting...')
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{c as b,j as e}from"./index-Czg1ruVn.js";import{I as m}from"./misc-S5ZD98sI.js";import{S as f}from"./tooltip-BtzSIxlB.js";import{a as g}from"./progress-BwanvUpB.js";import{u as N,L as i,F as c}from"./components-wgHiPsTg.js";import"./clsx-B-dksMZM.js";const L=({matches:n})=>{var r;const l=(r=n.find(o=>o.id==="root"))==null?void 0:r.data;return[{title:`👷 | ${l==null?void 0:l.workshopTitle}`}]};function S(n,l){return n.type==="unknown"&&l.type==="unknown"?0:n.type==="unknown"?-1:l.type==="unknown"?1:0}function w(n){switch(n.type){case"workshop-instructions":return"/";case"workshop-finished":return"/finished";case"instructions":return`/${n.exerciseNumber.toString().padStart(2,"0")}`;case"step":return`/${n.exerciseNumber.toString().padStart(2,"0")}/${n.stepNumber.toString().padStart(2,"0")}`;case"finished":return`/${n.exerciseNumber.toString().padStart(2,"0")}/finished`;default:return""}}function T(){var a,d;const n=N(),l=b(),r=g(),o=((a=l.formData)==null?void 0:a.get("intent"))==="inspect",u=((d=l.formData)==null?void 0:d.get("intent"))==="stop-inspect",j={completed:"bg-blue-500",incomplete:"bg-yellow-500"};return e.jsxs("main",{className:"container mx-auto mt-8",children:[e.jsx("h1",{className:"text-4xl font-bold",children:"Admin"}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("nav",{children:e.jsxs("ul",{className:"flex gap-3",children:[e.jsx("li",{children:e.jsx(i,{className:"underline",to:"/",children:"Home"})}),e.jsx("li",{children:e.jsx(i,{className:"underline",to:"/diff",children:"Diff Viewer"})})]})}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Progress"}),r?e.jsx("ul",{className:"flex max-h-72 flex-col gap-2 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:r.sort(S).map(s=>{const t=`https://www.epicweb.dev/workshops/${n.workshopSlug}/${s.epicSectionSlug}/${s.epicLessonSlug}`,p=s.epicCompletedAt?"completed":"incomplete",h=[`${s.epicSectionSlug}/${s.epicLessonSlug}`,s.epicCompletedAt?`(${s.epicCompletedAt})`:null].filter(Boolean).join(" ");return e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx("span",{className:`h-3 w-3 rounded-full ${j[p]}`,title:p}),s.type==="unknown"?e.jsxs("span",{className:"flex items-center gap-1",children:[h,e.jsx("span",{className:"text-red-500",children:e.jsx(f,{content:"This video is in the workshop on EpicWeb.dev, but not in the local workshop.",children:e.jsx(m,{name:"Close"})})})]}):e.jsx(i,{to:w(s),children:h}),e.jsx(i,{to:t,children:e.jsx(m,{name:"ExternalLink"})})]},s.epicLessonSlug)})}):e.jsx("p",{children:"No progress data"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Commands"}),e.jsxs("ul",{className:"max-h-48 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:[e.jsx("li",{children:e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"clear-caches",children:"Clear local caches"})})}),e.jsx("li",{children:e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"clear-data",children:"Clear all local data (including auth data)"})})}),e.jsx("li",{children:n.inspectorRunning?e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"stop-inspect",children:o?"Stopping inspector...":"Stop inspector"})}):e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"inspect",children:u?"Starting inspector...":"Start inspector"})})})]})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Apps"}),e.jsx("ul",{className:"max-h-48 list-none overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:n.apps.map(s=>e.jsxs("li",{className:"flex items-center gap-2 py-1",children:[n.processes[s.name]?e.jsx(x,{status:"running"}):e.jsx(x,{status:"stopped"}),s.name]},s.name))})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Processes"}),e.jsx("ul",{className:"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:Object.entries(n.processes).map(([s,t])=>e.jsx("li",{children:e.jsxs("span",{children:[s," - Port: ",t.port," - PID ",t.pid," -"," ",t.color]})},s))})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Test Processes"}),e.jsx("ul",{className:"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:Object.entries(n.testProcesses).map(([s,t])=>e.jsx("li",{children:e.jsxs("span",{children:[s," - PID ",t.pid," - Exit code: ",t.exitCode]})},s))})]})]})]})}function x({status:n}){const l={running:{pinger:"bg-green-400",circle:"bg-green-500"},starting:{pinger:"bg-sky-400",circle:"bg-sky-500"},stopped:{circle:"bg-gray-500"},taken:{pinger:"bg-red-400",circle:"bg-red-500"}}[n];return e.jsxs("span",{className:"relative flex h-3 w-3",children:[l.pinger?e.jsx("span",{className:`absolute inline-flex h-full w-full animate-ping rounded-full ${l.pinger} opacity-75`}):null,e.jsx("span",{className:`relative inline-flex h-3 w-3 rounded-full ${l.circle}`})]})}export{T as default,L as meta};
|
|
2
|
-
//# sourceMappingURL=_layout-B9Y-8OU6.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_layout-B9Y-8OU6.js","sources":["../../../app/routes/admin+/_layout.tsx"],"sourcesContent":["import {\n\tgetApps,\n\tgetEpicWorkshopSlug,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getProcesses } from '@epic-web/workshop-utils/process-manager.server'\nimport {\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport {\n\tjson,\n\ttype ActionFunctionArgs,\n\ttype LoaderFunctionArgs,\n\ttype MetaFunction,\n} from '@remix-run/node'\nimport { Form, Link, useLoaderData, useNavigation } from '@remix-run/react'\nimport { Icon } from '#app/components/icons.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.tsx'\nimport { type loader as rootLoader } from '#app/root.tsx'\nimport {\n\tuseEpicProgress,\n\ttype SerializedProgress,\n} from '#app/routes/progress.tsx'\nimport { ensureUndeployed } from '#app/utils/misc.tsx'\nimport {\n\tclearCaches,\n\tclearData,\n\tstartInspector,\n\tstopInspector,\n} from './admin-utils.server.tsx'\n\ndeclare global {\n\tvar __inspector_open__: boolean | undefined\n}\n\nexport const meta: MetaFunction<typeof loader, { root: typeof rootLoader }> = ({\n\tmatches,\n}) => {\n\tconst rootData = matches.find((m) => m.id === 'root')?.data\n\treturn [{ title: `👷 | ${rootData?.workshopTitle}` }]\n}\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tensureUndeployed()\n\tconst timings = makeTimings('adminLoader')\n\tconst workshopSlug = (await getEpicWorkshopSlug()) ?? 'Unkown'\n\tconst apps = (await getApps({ request, timings })).filter(\n\t\t(a, i, ar) => ar.findIndex((b) => a.name === b.name) === i,\n\t)\n\tconst processes: Record<\n\t\tstring,\n\t\t{ port: number; pid?: number; color: string }\n\t> = {}\n\tconst testProcesses: Record<\n\t\tstring,\n\t\t{ pid?: number; exitCode?: number | null }\n\t> = {}\n\tfor (const [\n\t\tname,\n\t\t{ port, process, color },\n\t] of getProcesses().devProcesses.entries()) {\n\t\tprocesses[name] = { port, pid: process.pid, color }\n\t}\n\n\tfor (const [\n\t\tname,\n\t\t{ process, exitCode },\n\t] of getProcesses().testProcesses.entries()) {\n\t\ttestProcesses[name] = { pid: process?.pid, exitCode }\n\t}\n\treturn json(\n\t\t{\n\t\t\tapps,\n\t\t\tprocesses,\n\t\t\tworkshopSlug,\n\t\t\ttestProcesses,\n\t\t\tinspectorRunning: global.__inspector_open__,\n\t\t},\n\t\t{\n\t\t\theaders: {\n\t\t\t\t'Server-Timing': getServerTimeHeader(timings),\n\t\t\t},\n\t\t},\n\t)\n}\n\nexport async function action({ request }: ActionFunctionArgs) {\n\tensureUndeployed()\n\tconst formData = await request.formData()\n\tconst intent = formData.get('intent')\n\tswitch (intent) {\n\t\tcase 'clear-data': {\n\t\t\tawait clearData()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tcase 'clear-caches': {\n\t\t\tawait clearCaches()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tcase 'inspect': {\n\t\t\tawait startInspector()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tcase 'stop-inspect': {\n\t\t\tawait stopInspector()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(`Unknown intent: ${intent}`)\n\t\t}\n\t}\n}\n\nfunction sortProgress(a: SerializedProgress, b: SerializedProgress) {\n\treturn a.type === 'unknown' && b.type === 'unknown'\n\t\t? 0\n\t\t: a.type === 'unknown'\n\t\t\t? -1\n\t\t\t: b.type === 'unknown'\n\t\t\t\t? 1\n\t\t\t\t: 0\n}\n\nfunction linkProgress(progress: SerializedProgress) {\n\tswitch (progress.type) {\n\t\tcase 'workshop-instructions':\n\t\t\treturn '/'\n\t\tcase 'workshop-finished':\n\t\t\treturn '/finished'\n\t\tcase 'instructions':\n\t\t\treturn `/${progress.exerciseNumber.toString().padStart(2, '0')}`\n\t\tcase 'step':\n\t\t\treturn `/${progress.exerciseNumber\n\t\t\t\t.toString()\n\t\t\t\t.padStart(2, '0')}/${progress.stepNumber.toString().padStart(2, '0')}`\n\t\tcase 'finished':\n\t\t\treturn `/${progress.exerciseNumber.toString().padStart(2, '0')}/finished`\n\t\tdefault:\n\t\t\treturn ''\n\t}\n}\n\nexport default function AdminLayout() {\n\tconst data = useLoaderData<typeof loader>()\n\tconst navigation = useNavigation()\n\tconst epicProgress = useEpicProgress()\n\n\tconst isStartingInspector = navigation.formData?.get('intent') === 'inspect'\n\tconst isStoppingInspector =\n\t\tnavigation.formData?.get('intent') === 'stop-inspect'\n\n\tconst progressStatus = {\n\t\tcompleted: 'bg-blue-500',\n\t\tincomplete: 'bg-yellow-500',\n\t}\n\n\treturn (\n\t\t<main className=\"container mx-auto mt-8\">\n\t\t\t<h1 className=\"text-4xl font-bold\">Admin</h1>\n\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t<nav>\n\t\t\t\t\t<ul className=\"flex gap-3\">\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Link className=\"underline\" to=\"/\">\n\t\t\t\t\t\t\t\tHome\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Link className=\"underline\" to=\"/diff\">\n\t\t\t\t\t\t\t\tDiff Viewer\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</nav>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Progress</h2>\n\t\t\t\t\t{epicProgress ? (\n\t\t\t\t\t\t<ul className=\"flex max-h-72 flex-col gap-2 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t\t{epicProgress.sort(sortProgress).map((progress) => {\n\t\t\t\t\t\t\t\tconst epicUrl = `https://www.epicweb.dev/workshops/${data.workshopSlug}/${progress.epicSectionSlug}/${progress.epicLessonSlug}`\n\t\t\t\t\t\t\t\tconst status = progress.epicCompletedAt\n\t\t\t\t\t\t\t\t\t? 'completed'\n\t\t\t\t\t\t\t\t\t: 'incomplete'\n\t\t\t\t\t\t\t\tconst label = [\n\t\t\t\t\t\t\t\t\t`${progress.epicSectionSlug}/${progress.epicLessonSlug}`,\n\t\t\t\t\t\t\t\t\tprogress.epicCompletedAt\n\t\t\t\t\t\t\t\t\t\t? `(${progress.epicCompletedAt})`\n\t\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t.join(' ')\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\tkey={progress.epicLessonSlug}\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center gap-2\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclassName={`h-3 w-3 rounded-full ${progressStatus[status]}`}\n\t\t\t\t\t\t\t\t\t\t\ttitle={status}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{progress.type === 'unknown' ? (\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"flex items-center gap-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-red-500\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SimpleTooltip content=\"This video is in the workshop on EpicWeb.dev, but not in the local workshop.\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"Close\" />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<Link to={linkProgress(progress)}>{label}</Link>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t<Link to={epicUrl}>\n\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"ExternalLink\"></Icon>\n\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<p>No progress data</p>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Commands</h2>\n\t\t\t\t\t<ul className=\"max-h-48 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"clear-caches\">\n\t\t\t\t\t\t\t\t\tClear local caches\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"clear-data\">\n\t\t\t\t\t\t\t\t\tClear all local data (including auth data)\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t{data.inspectorRunning ? (\n\t\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"stop-inspect\">\n\t\t\t\t\t\t\t\t\t\t{isStartingInspector\n\t\t\t\t\t\t\t\t\t\t\t? 'Stopping inspector...'\n\t\t\t\t\t\t\t\t\t\t\t: 'Stop inspector'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"inspect\">\n\t\t\t\t\t\t\t\t\t\t{isStoppingInspector\n\t\t\t\t\t\t\t\t\t\t\t? 'Starting inspector...'\n\t\t\t\t\t\t\t\t\t\t\t: 'Start inspector'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Apps</h2>\n\t\t\t\t\t<ul className=\"max-h-48 list-none overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t{data.apps.map((app) => (\n\t\t\t\t\t\t\t<li key={app.name} className=\"flex items-center gap-2 py-1\">\n\t\t\t\t\t\t\t\t{data.processes[app.name] ? (\n\t\t\t\t\t\t\t\t\t<Pinger status=\"running\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Pinger status=\"stopped\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{app.name}\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Processes</h2>\n\t\t\t\t\t<ul className=\"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t{Object.entries(data.processes).map(([key, process]) => (\n\t\t\t\t\t\t\t<li key={key}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t{key} - Port: {process.port} - PID {process.pid} -{' '}\n\t\t\t\t\t\t\t\t\t{process.color}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Test Processes</h2>\n\t\t\t\t\t<ul className=\"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t{Object.entries(data.testProcesses).map(([key, process]) => (\n\t\t\t\t\t\t\t<li key={key}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t{key} - PID {process.pid} - Exit code: {process.exitCode}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</main>\n\t)\n}\n\nfunction Pinger({\n\tstatus,\n}: {\n\tstatus: 'running' | 'starting' | 'stopped' | 'taken'\n}) {\n\tconst colors = {\n\t\trunning: {\n\t\t\tpinger: 'bg-green-400',\n\t\t\tcircle: 'bg-green-500',\n\t\t},\n\t\tstarting: {\n\t\t\tpinger: 'bg-sky-400',\n\t\t\tcircle: 'bg-sky-500',\n\t\t},\n\t\tstopped: {\n\t\t\tcircle: 'bg-gray-500',\n\t\t},\n\t\ttaken: {\n\t\t\tpinger: 'bg-red-400',\n\t\t\tcircle: 'bg-red-500',\n\t\t},\n\t}[status]\n\treturn (\n\t\t<span className=\"relative flex h-3 w-3\">\n\t\t\t{colors.pinger ? (\n\t\t\t\t<span\n\t\t\t\t\tclassName={`absolute inline-flex h-full w-full animate-ping rounded-full ${colors.pinger} opacity-75`}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tclassName={`relative inline-flex h-3 w-3 rounded-full ${colors.circle}`}\n\t\t\t/>\n\t\t</span>\n\t)\n}\n"],"names":["meta","matches","rootData","find","m","id","data","title","workshopTitle","sortProgress","a","b","type","linkProgress","progress","exerciseNumber","toString","padStart","stepNumber","AdminLayout","useLoaderData","navigation","useNavigation","epicProgress","useEpicProgress","isStartingInspector","formData","get","isStoppingInspector","progressStatus","completed","incomplete","jsxs","className","children","jsx","Link","to","sort","map","epicUrl","workshopSlug","epicSectionSlug","epicLessonSlug","status","epicCompletedAt","label","filter","Boolean","join","SimpleTooltip","content","Icon","name","Form","method","value","inspectorRunning","apps","app","processes","Pinger","Object","entries","key","process","port","pid","color","testProcesses","exitCode","colors","running","pinger","circle","starting","stopped","taken"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_layout-DaZNLfOL.js","sources":["../../../app/routes/_app+/_exercises+/_layout.tsx"],"sourcesContent":["import { Outlet } from '@remix-run/react'\n\nexport default function ExercisesLayout() {\n\treturn (\n\t\t<div className=\"flex h-full flex-grow\">\n\t\t\t<Outlet />\n\t\t</div>\n\t)\n}\n"],"names":["ExercisesLayout","className","children","jsx","Outlet"],"mappings":"+CAEA,SAAwBA,GAAkB,CACzC,aACE,MAAI,CAAAC,UAAU,wBACdC,SAAAC,EAAAA,IAACC,IAAO,CACT,CAAA,CAEF"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{r as d,j as e,O as We,b as ne}from"./index-Czg1ruVn.js";import{c as b}from"./clsx-B-dksMZM.js";import{c as p,I as v}from"./misc-S5ZD98sI.js";import{c as Fe,u as z,P as I,a as k,b as U,d as Oe,D as Ve,e as He,f as ze,g as F,S,T as Ue,h as K,i as q,j as Z}from"./tooltip-BtzSIxlB.js";import{R as Ye,h as Be,u as Ge,F as Me,P as Qe}from"./index-C6ToujzV.js";import{b as A}from"./user-CdUDQ7a8.js";import{a as Y}from"./presence-CW1_eiIo.js";import{b as Je,s as ae,c as Ke,d as qe,e as se,m as x,u as Ze,f as Xe}from"./progress-BwanvUpB.js";import{T as re}from"./index-yEAxvbDV.js";import{L as f,u as oe,N as T}from"./components-wgHiPsTg.js";import"./request-info-DHtGM4FI.js";import"./client-hints-DLYDs4RF.js";function et(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 tt(t,n){if(Array.isArray(n))return V(t,n);if(typeof n=="string")return V(t,[n]);ae(t,n)}function nt(){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(Je(r,a,{transitionOverride:s}))}),Promise.all(o)},set(a){return t.forEach(s=>{tt(s,a)})},stop(){t.forEach(a=>{et(a)})},mount(){return()=>{n.stop()}}};return n}function H(){const t=Ke(nt);return qe(t.mount,[]),t}function at(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,Lt]=Fe(B),[st,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),[m=!1,h]=ze({prop:s,defaultProp:o,onChange:r});return e.jsx(st,{scope:n,triggerRef:i,contentRef:l,contentId:F(),titleId:F(),descriptionId:F(),open:m,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",[rt,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(rt,{scope:n,forceMount:a,children:d.Children.map(s,c=>e.jsx(U,{present:a||r.open,children:e.jsx(Qe,{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(ot,{...o,ref:n})}):null});he.displayName=$;var ot=d.forwardRef((t,n)=>{const{__scopeDialog:a,...s}=t,o=j($,a);return e.jsx(Ye,{as:Oe,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",pe=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(it,{...o,ref:n}):e.jsx(lt,{...o,ref:n})})});pe.displayName=y;var it=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 Be(r)},[]),e.jsx(me,{...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())})}),lt=d.forwardRef((t,n)=>{const a=j(y,t.__scopeDialog),s=d.useRef(!1),o=d.useRef(!1);return e.jsx(me,{...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,m;(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;((m=a.triggerRef.current)==null?void 0:m.contains(c))&&r.preventDefault(),r.detail.originalEvent.type==="focusin"&&o.current&&r.preventDefault()}})}),me=d.forwardRef((t,n)=>{const{__scopeDialog:a,trapFocus:s,onOpenAutoFocus:o,onCloseAutoFocus:r,...c}=t,i=j(y,a),l=d.useRef(null),m=z(n,l);return Ge(),e.jsxs(e.Fragment,{children:[e.jsx(Me,{asChild:!0,loop:!0,trapped:s,onMountAutoFocus:o,onUnmountAutoFocus:r,children:e.jsx(Ve,{role:"dialog",id:i.contentId,"aria-describedby":i.descriptionId,"aria-labelledby":i.titleId,"data-state":Q(i.open),...c,ref:m,onDismiss:()=>i.onOpenChange(!1)})}),e.jsxs(e.Fragment,{children:[e.jsx(ct,{titleId:i.titleId}),e.jsx(ut,{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",[Wt,Ne]=He(we,{contentName:y,titleName:M,docsSlug:"dialog"}),ct=({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},dt="DialogDescriptionWarning",ut=({contentRef:t,descriptionId:n})=>{const s=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${Ne(dt).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},ft=le,ht=de,pt=fe,ye=he,Ee=pe,mt=xe,De=be,xt=je;const gt=ft,bt=ht,vt=pt;function Ce({className:t,ref:n,...a}){return e.jsx(ye,{ref:n,className:p("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(vt,{children:[e.jsx(Ce,{}),e.jsxs(Ee,{ref:a,className:p("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(xt,{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:p("flex flex-col space-y-1.5 text-center sm:text-left",t),...n})}_e.displayName="DialogHeader";mt.displayName;function ke({className:t,ref:n,...a}){return e.jsx(De,{ref:n,className:p("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 p("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:p("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(Ue,{children:[a.slice(0,s).map(({user:i,score:l})=>{var g,N;const m=te(l),h=jt(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:p("h-8 w-8 rounded-full border object-cover",m),src:i.avatarUrl}):e.jsx("div",{tabIndex:0,"aria-label":i.name||"Epic Web Dev",className:p("flex h-8 w-8 items-center justify-center rounded-full border",m),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 ${(N=(g=i.location)==null?void 0:g.origin)!=null&&N.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:p("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:p("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=at("(min-width: 640px)",!0);function Ft(){const t=A(),n=Re(),[a,s]=d.useState(!1);return e.jsxs("div",{className:"flex flex-col",children:[t?null:e.jsx(wt,{}),e.jsx(Nt,{isMenuOpened:a,onMenuOpenChange:s}),e.jsxs("div",{className:p("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&&a}),children:[n?e.jsx(yt,{isMenuOpened:a,onMenuOpenChange:s}):null,e.jsx("div",{className:p("h-full w-full max-w-full sm:max-w-[calc(100%-56px)]",a?"hidden md:block":""),children:e.jsx(We,{})})]})]})}function jt(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 wt(){const t=Re(),n=e.jsx("div",{children:ENV.EPICSHOP_DEPLOYED?e.jsxs("div",{children:["This is the deployed version. ",ENV.EPICSHOP_GITHUB_ROOT?e.jsxs(e.Fragment,{children:[e.jsx(f,{className:"underline",target:"_blank",rel:"noopener noreferrer",to:ENV.EPICSHOP_GITHUB_ROOT,children:"Run locally"})," for full experience."]}):null," "]}):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(gt,{children:[e.jsx(bt,{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=Ze(t);return e.jsx(x.li,{variants:Se,className:p("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=Xe(n);return e.jsx(x.li,{variants:Se,className:p("py-[6px] first:pt-3 last:pb-3",a?`${a} before:border-t`:null),children:e.jsx("span",{className:"ml-2",children:t})})}function Nt({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:p("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:m,steps:h})=>{const g=Number(r.exerciseNumber)===l,N=!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:[m,N?" 🛝":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,w=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}/${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":L}),children:_?`${w}. ${D} 🛝`:`${w}. ${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:p("flex items-center justify-start p-4",t&&c.length>4?"min-h-14":"h-14",{"w-full border-t":t,"border-l":!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:p("flex h-14 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-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:p("h-14 self-start p-4 pt-[15px] sm:mb-4 sm:w-full",{"w-full border-t":t,"border-l":!t}),children:e.jsx(re,{})})]})})})}const O=400;function yt({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,m=H(),h={close:{width:56},open:{width:O}},g={visible:{opacity:1,transition:{duration:.05,when:"beforeChildren",staggerChildren:.03}},hidden:{opacity:0}},N=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:m,children:e.jsxs("div",{className:"flex h-full flex-col items-center justify-between",children:[e.jsx($e,{title:a.workshopTitle,menuControls:m,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,w=u.toString().padStart(2,"0");return e.jsxs(Te,{exerciseNumber:u,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":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:`/${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"})},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:`/${w}/${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:`/${w}/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:`/${N}`,children:i.title}):null,i!=null&&i.title&&(l!=null&&l.title)?" — ":null,l!=null&&l.title?e.jsx(f,{to:`/${N}/${l.stepNumber.toString().padStart(2,"0")}`,children:l.title}):null]})}),e.jsx("div",{className:p("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 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={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"}},c=H(),i=H();async function l(){s==null||s.start(n?"close":"open"),a(!n),n?(c.start(o.closed),await i.start(r.moving),i.start(r.closed)):(await i.start(r.moving),c.start(o.open),i.start(r.open))}const m=d.useRef(l);return d.useEffect(()=>{m.current=l}),d.useEffect(()=>{if(!n)return;function h(g){g.key==="Escape"&&m.current()}return document.addEventListener("keyup",h),()=>document.removeEventListener("keyup",h)},[n]),e.jsxs("div",{className:p("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",{className:"flex h-14 w-14 items-center justify-center","aria-label":"Open Navigation menu",onClick:l,children:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",children:[e.jsx(x.path,{...o.closed,animate:c,transition:{duration:.2},stroke:"currentColor",strokeWidth:1.5}),e.jsx(x.path,{...r.closed,animate:i,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{Ft as default};
|
|
6
|
-
//# sourceMappingURL=_layout-dHX2Hcew.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_layout-dHX2Hcew.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 { 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\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<MobileNavigation\n\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\tonMenuOpenChange={setMenuOpened}\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{ENV.EPICSHOP_GITHUB_ROOT ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tto={ENV.EPICSHOP_GITHUB_ROOT}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tRun locally\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t{` for full experience.`}\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : null}{' '}\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'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<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 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-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\n\t\t\t\t\t\tclassName={cn('h-14 self-start p-4 pt-[15px] sm:mb-4 sm:w-full', {\n\t\t\t\t\t\t\t'w-full border-t': isMenuOpened,\n\t\t\t\t\t\t\t'border-l': !isMenuOpened,\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 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 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\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\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","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_ROOT","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","path01Variants","d","closed","path02Variants","moving","path01Controls","path02Controls","toggleMenu","start","latestToggleMenu","current","handleKeyUp","document","addEventListener","removeEventListener","onClick","height","viewBox","path","stroke","strokeWidth","delay","y"],"mappings":"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","x_google_ignoreList":[0,1,3]}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as e}from"./index-Czg1ruVn.js";import{B as a}from"./button-BA3iiLRs.js";import{I as i}from"./misc-S5ZD98sI.js";import{S as o}from"./tooltip-BtzSIxlB.js";import{u as m,a as u}from"./user-CdUDQ7a8.js";import{u as x}from"./presence-CW1_eiIo.js";import{u as h,a as p,L as r,F as c}from"./components-wgHiPsTg.js";import"./clsx-B-dksMZM.js";import"./request-info-DHtGM4FI.js";function O(){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{O as default};
|
|
2
|
-
//# sourceMappingURL=account-uvU1jIL2.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"account-uvU1jIL2.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 { 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 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":["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":"2XAwDA,SAAwBA,GAAU,CACjC,MAAMC,EAAOC,IACPC,EAAoBC,IACpBC,EAAOC,IACPC,EAAgBC,IAChBC,EAAsBC,IAE3B,OAAAC,EAAAA,KAAC,OAAK,CAAAC,UAAU,8FACfC,SAAA,CAAAC,EAAA,IAAC,MAAA,CACAF,UAAU,yBACVG,KAAKR,GAAAA,YAAAA,EAAeS,cAAeX,EAAKY,MAAQZ,EAAKa,MACrDC,IAAKd,EAAKe,SAAA,CACX,EACCN,EAAA,IAAA,KAAA,CAAGF,UAAU,gBAAgBC,SAAY,cAAA,CAAA,QACzC,IAAE,CAAAD,UAAU,+CACXC,SAAKR,EAAAY,KACH,OACAV,GAAAA,YAAAA,EAAeS,cAAeX,EAAKY,IACpC,mCAAmCZ,EAAKa,KAAK,IAC5C,iCAAiCb,EAAKa,KAAK,IAC/C,EACCX,EAECI,EAAA,KAAAU,WAAA,CAAAR,SAAA,CAACF,EAAA,KAAA,IAAA,CAAEC,UAAU,+CAA+CC,SAAA,CAAA,uCACtBN,EAAcS,YAAY,KAC9DT,EAAce,GAAG,IAAA,CACnB,CAAA,EACAX,EAAA,KAAC,MAAI,CAAAC,UAAU,4BACdC,SAAA,CAAAC,EAAAA,IAACX,EAAkBoB,KAAlB,CAAuBC,OAAO,OAC9BX,SAACC,EAAA,IAAAW,EAAA,CAAOC,QAAQ,OAAOT,KAAK,SAASU,MAAM,qBAAqBd,8BAEhE,CACD,CAAA,EACAC,EAAA,IAACc,EAAc,CAAAC,QAAQ,0FACtBhB,SAAAC,EAAA,IAACgB,GAAKb,KAAK,WAAWc,SAAU,EAAG,CACpC,CAAA,CAAA,CACD,CAAA,CAAA,CAAA,CACD,EAEApB,EAAA,KAAC,MAAI,CAAAC,UAAU,0BACdC,SAAA,CAAAF,EAAA,KAACqB,EAAA,CACAC,GAAIhC,EAAKiC,eACTtB,UAAU,2CAEVC,SAAA,CAAAC,EAAA,IAACgB,EAAK,CAAAb,KAAK,UAAUkB,KAAK,IAAK,CAAA,EAAE,iBAAA,CAAA,CAElC,EACArB,EAAA,IAACc,EAAc,CAAAC,QAAQ,2EACtBhB,SAAAC,EAAA,IAACgB,GAAKb,KAAK,WAAWc,SAAU,EAAG,CACpC,CAAA,CAAA,CACD,CAAA,EAEDpB,EAAA,KAAC,MAAI,CAAAC,UAAU,0BACdC,SAAA,CAACF,EAAA,KAAAY,EAAA,CAAKC,OAAO,OACZX,SAAA,CAAAC,EAAA,IAAC,QAAA,CACAG,KAAK,SACLmB,KAAK,SACLT,MAAOlB,GAAAA,MAAAA,EAAqB4B,OAAS,QAAU,MAAA,CAChD,SACCZ,EAAO,CAAAC,QAAQ,OAAOT,KAAK,SAASU,MAAM,mBACzCd,SAAA,CAAAJ,GAAAA,MAAAA,EAAqB4B,OAAS,YAAc,aAAa,WAAA,CAC3D,CAAA,CAAA,CACD,CAAA,EACAvB,EAAA,IAACc,EAAc,CAAAC,QAAQ,8FACtBhB,SAAAC,EAAA,IAACgB,GAAKb,KAAK,WAAWc,SAAU,EAAG,CACpC,CAAA,CAAA,CACD,CAAA,EACApB,EAAA,KAAC,MAAI,CAAAC,UAAU,0BACdC,SAAA,CAAAC,EAAA,IAACS,EAAK,CAAAC,OAAO,OACZX,SAAAC,EAAA,IAACW,EAAO,CAAAC,QAAQ,OAAOT,KAAK,SAASU,MAAM,SAASd,SAAA,iBAEpD,CACD,CAAA,EACAC,EAAA,IAACc,EAAA,CACAC,eACE,MAAI,CAAAhB,SAAA,CAAA,oBACcC,EAAA,IAAA,IAAA,CAAEF,UAAU,SAASC,SAAM,QAAA,CAAA,EAAI,6CAEhD,KAAG,CAAA,CAAA,EAAE,wFAAA,CAGP,CAAA,EAGDA,SAACC,EAAA,IAAAgB,EAAA,CAAKb,KAAK,WAAWc,SAAU,EAAG,CAAA,CACpC,CAAA,CACD,CAAA,SACC,IAAE,CAAAlB,SAAA,CAAA,QACI,UACLmB,EAAK,CAAAC,GAAG,cAAcrB,UAAU,YAAYC,SAE7C,aAAA,CAAA,EAAQ,IAAI,2CAAA,CAEb,CAAA,SACC,IAAE,CAAAA,SAAA,CAAA,QACI,UACLmB,EAAK,CAAAC,GAAG,WAAWrB,UAAU,YAAYC,SAE1C,UAAA,CAAA,EAAQ,IAAI,sBAAA,CAEb,CAAA,CAAA,CACD,CAAA,CAEF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discord-CgwNGD2p.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as e}from"./index-Czg1ruVn.js";import{I as i}from"./misc-S5ZD98sI.js";import{b as t,a as c}from"./user-CdUDQ7a8.js";import{u as l,L as s}from"./components-wgHiPsTg.js";function m({discordAuthUrl:r}){const n=t(),o=c();return n?o?"https://discord.com/channels/715220730605731931/1161045224907341972":r:"/login"}function a({discordAuthUrl:r}){const n=t(),o=c();return n?o?e.jsxs("div",{className:"flex items-center justify-center gap-2 text-xl underline",children:[e.jsx(s,{to:"discord://discord.com/channels/715220730605731931/1161045224907341972",children:e.jsx(i,{name:"Discord",size:"2xl"})}),e.jsx(s,{to:"https://discord.com/channels/715220730605731931/1161045224907341972",target:"_blank",rel:"noreferrer noopener",children:"Open Discord"})]}):e.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-2 text-xl",children:[e.jsxs(s,{to:r,className:"flex items-center gap-2 underline",children:[e.jsx(i,{name:"Discord",size:"2xl"}),"Connect Discord"]})," ",e.jsxs("span",{children:["to get access to the exclusive"," ",e.jsx(s,{to:"/discord",className:"underline",children:"discord channel"}),"."]})]}):e.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-2 text-xl",children:[e.jsxs(s,{to:"/login",className:"inline-flex items-center gap-2 underline",children:[e.jsx(i,{name:"Discord",size:"2xl"}),"Login"]})," ",e.jsxs("span",{children:["to get access to the exclusive"," ",e.jsx(s,{to:"/discord",className:"underline",children:"discord channel"}),"."]})]})}function p(){const r=l();return e.jsxs("div",{className:"container flex h-full max-w-3xl flex-col items-center justify-center gap-4 p-12",children:[e.jsx(a,{discordAuthUrl:r.discordAuthUrl}),e.jsxs("p",{children:["The"," ",e.jsx(s,{target:"_blank",rel:"noreferrer noopener",className:"underline",to:"https://kentcdodds.com/discord",children:"Epic Web Community on Discord"})," ","is a great place to hang out with other developers who are working through this workshop. You can ask questions, get help, and solidify what you're learning by helping others."]}),e.jsx("p",{children:e.jsxs("small",{className:"text-sm",children:["If you've not joined the Epic Web Community on Discord yet, you'll be required to go through a short onboarding process first. A friendly bot will explain the process when you"," ",e.jsx(s,{to:"https://kcd.im/discord",target:"_blank",rel:"noreferrer noopener",className:"underline",children:"join"}),"."]})})]})}export{a as D,p as a,m as u};
|
|
2
|
-
//# sourceMappingURL=discord-yZor-3t1.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discord-yZor-3t1.js","sources":["../../../app/routes/_app+/discord.tsx"],"sourcesContent":["import { json } from '@remix-run/node'\nimport { Link, useLoaderData } from '@remix-run/react'\nimport { Icon } from '#app/components/icons.tsx'\nimport {\n\tuseOptionalDiscordMember,\n\tuseOptionalUser,\n} from '#app/components/user.tsx'\nimport { getDiscordAuthURL } from '../discord.callback.ts'\n\nexport async function loader() {\n\treturn json({ discordAuthUrl: getDiscordAuthURL() })\n}\n\nexport function useDiscordCTALink({\n\tdiscordAuthUrl,\n}: {\n\tdiscordAuthUrl: string\n}) {\n\tconst user = useOptionalUser()\n\tconst discordMember = useOptionalDiscordMember()\n\n\tif (!user) {\n\t\treturn '/login'\n\t}\n\tif (!discordMember) {\n\t\treturn discordAuthUrl\n\t}\n\n\treturn 'https://discord.com/channels/715220730605731931/1161045224907341972'\n}\n\nexport function DiscordCTA({ discordAuthUrl }: { discordAuthUrl: string }) {\n\tconst user = useOptionalUser()\n\tconst discordMember = useOptionalDiscordMember()\n\n\tif (!user) {\n\t\treturn (\n\t\t\t<div className=\"flex flex-wrap items-center justify-center gap-2 text-xl\">\n\t\t\t\t<Link to=\"/login\" className=\"inline-flex items-center gap-2 underline\">\n\t\t\t\t\t<Icon name=\"Discord\" size=\"2xl\" />\n\t\t\t\t\tLogin\n\t\t\t\t</Link>{' '}\n\t\t\t\t<span>\n\t\t\t\t\tto get access to the exclusive{' '}\n\t\t\t\t\t<Link to=\"/discord\" className=\"underline\">\n\t\t\t\t\t\tdiscord channel\n\t\t\t\t\t</Link>\n\t\t\t\t\t.\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t)\n\t}\n\tif (!discordMember) {\n\t\treturn (\n\t\t\t<div className=\"flex flex-wrap items-center justify-center gap-2 text-xl\">\n\t\t\t\t<Link to={discordAuthUrl} className=\"flex items-center gap-2 underline\">\n\t\t\t\t\t<Icon name=\"Discord\" size=\"2xl\" />\n\t\t\t\t\tConnect Discord\n\t\t\t\t</Link>{' '}\n\t\t\t\t<span>\n\t\t\t\t\tto get access to the exclusive{' '}\n\t\t\t\t\t<Link to=\"/discord\" className=\"underline\">\n\t\t\t\t\t\tdiscord channel\n\t\t\t\t\t</Link>\n\t\t\t\t\t.\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t)\n\t}\n\n\treturn (\n\t\t<div className=\"flex items-center justify-center gap-2 text-xl underline\">\n\t\t\t<Link to=\"discord://discord.com/channels/715220730605731931/1161045224907341972\">\n\t\t\t\t<Icon name=\"Discord\" size=\"2xl\" />\n\t\t\t</Link>\n\t\t\t<Link\n\t\t\t\tto=\"https://discord.com/channels/715220730605731931/1161045224907341972\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noreferrer noopener\"\n\t\t\t>\n\t\t\t\tOpen Discord\n\t\t\t</Link>\n\t\t</div>\n\t)\n}\n\nexport default function DiscordRoute() {\n\tconst data = useLoaderData<typeof loader>()\n\n\treturn (\n\t\t<div className=\"container flex h-full max-w-3xl flex-col items-center justify-center gap-4 p-12\">\n\t\t\t<DiscordCTA discordAuthUrl={data.discordAuthUrl} />\n\t\t\t<p>\n\t\t\t\tThe{' '}\n\t\t\t\t<Link\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\trel=\"noreferrer noopener\"\n\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\tto=\"https://kentcdodds.com/discord\"\n\t\t\t\t>\n\t\t\t\t\tEpic Web Community on Discord\n\t\t\t\t</Link>{' '}\n\t\t\t\tis a great place to hang out with other developers who are working\n\t\t\t\tthrough this workshop. You can ask questions, get help, and solidify\n\t\t\t\twhat you're learning by helping others.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\t<small className=\"text-sm\">\n\t\t\t\t\tIf you've not joined the Epic Web Community on Discord yet, you'll be\n\t\t\t\t\trequired to go through a short onboarding process first. A friendly\n\t\t\t\t\tbot will explain the process when you{' '}\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto=\"https://kcd.im/discord\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noreferrer noopener\"\n\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t>\n\t\t\t\t\t\tjoin\n\t\t\t\t\t</Link>\n\t\t\t\t\t.\n\t\t\t\t</small>\n\t\t\t</p>\n\t\t</div>\n\t)\n}\n"],"names":["useDiscordCTALink","discordAuthUrl","user","useOptionalUser","discordMember","useOptionalDiscordMember","DiscordCTA","jsxs","className","children","jsx","Link","to","Icon","name","size","target","rel","DiscordRoute","data","useLoaderData"],"mappings":"iLAaO,SAASA,EAAkB,CACjCC,eAAAA,CACD,EAEG,CACF,MAAMC,EAAOC,IACPC,EAAgBC,IAEtB,OAAKH,EAGAE,EAIE,sEAHCH,EAHA,QAOT,CAEgB,SAAAK,EAAW,CAAEL,eAAAA,CAAe,EAA+B,CAC1E,MAAMC,EAAOC,IACPC,EAAgBC,IAEtB,OAAKH,EAiBAE,EAmBJG,EAAAA,KAAC,MAAI,CAAAC,UAAU,2DACdC,SAAA,CAACC,EAAA,IAAAC,EAAA,CAAKC,GAAG,wEACRH,SAAAC,EAAA,IAACG,GAAKC,KAAK,UAAUC,KAAK,MAAM,CACjC,CAAA,EACAL,EAAA,IAACC,EAAA,CACAC,GAAG,sEACHI,OAAO,SACPC,IAAI,sBACJR,SAAA,cAAA,CAED,CAAA,CACD,CAAA,EA5BCF,EAAAA,KAAC,MAAI,CAAAC,UAAU,2DACdC,SAAA,CAAAF,EAAA,KAACI,EAAK,CAAAC,GAAIX,EAAgBO,UAAU,oCACnCC,SAAA,CAAAC,EAAA,IAACG,EAAK,CAAAC,KAAK,UAAUC,KAAK,KAAM,CAAA,EAAE,iBAAA,EAEnC,EAAQ,WACP,OAAK,CAAAN,SAAA,CAAA,iCAC0B,UAC9BE,EAAK,CAAAC,GAAG,WAAWJ,UAAU,YAAYC,SAE1C,iBAAA,CAAA,EAAO,GAAA,CAER,CAAA,CAAA,CACD,CAAA,EA7BAF,EAAAA,KAAC,MAAI,CAAAC,UAAU,2DACdC,SAAA,CAAAF,EAAA,KAACI,EAAK,CAAAC,GAAG,SAASJ,UAAU,2CAC3BC,SAAA,CAAAC,EAAA,IAACG,EAAK,CAAAC,KAAK,UAAUC,KAAK,KAAM,CAAA,EAAE,OAAA,EAEnC,EAAQ,WACP,OAAK,CAAAN,SAAA,CAAA,iCAC0B,UAC9BE,EAAK,CAAAC,GAAG,WAAWJ,UAAU,YAAYC,SAE1C,iBAAA,CAAA,EAAO,GAAA,CAER,CAAA,CAAA,CACD,CAAA,CAmCH,CAEA,SAAwBS,GAAe,CACtC,MAAMC,EAAOC,IAGZ,OAAAb,EAAAA,KAAC,MAAI,CAAAC,UAAU,kFACdC,SAAA,CAACC,EAAA,IAAAJ,EAAA,CAAWL,eAAgBkB,EAAKlB,cAAgB,CAAA,SAChD,IAAE,CAAAQ,SAAA,CAAA,MACE,IACJC,EAAAA,IAACC,EAAA,CACAK,OAAO,SACPC,IAAI,sBACJT,UAAU,YACVI,GAAG,iCACHH,SAAA,+BAAA,CAED,EAAQ,IAAI,iLAAA,CAIb,CAAA,EACCC,EAAA,IAAA,IAAA,CACAD,SAACF,EAAA,KAAA,QAAA,CAAMC,UAAU,UAAUC,SAAA,CAAA,kLAGY,IACtCC,EAAAA,IAACC,EAAA,CACAC,GAAG,yBACHI,OAAO,SACPC,IAAI,sBACJT,UAAU,YACVC,SAAA,MAED,CAAA,EAAO,GAAA,EAER,CACD,CAAA,CAAA,CACD,CAAA,CAEF"}
|