@epic-web/workshop-app 6.23.1 → 6.23.2

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.
Files changed (24) hide show
  1. package/build/client/assets/{_exerciseNumber-DLQcM4v6.js → _exerciseNumber-Cnmd182F.js} +2 -2
  2. package/build/client/assets/{_exerciseNumber-DLQcM4v6.js.map → _exerciseNumber-Cnmd182F.js.map} +1 -1
  3. package/build/client/assets/{_exerciseNumber_.finished-DaOTQdWd.js → _exerciseNumber_.finished-D078JW2f.js} +2 -2
  4. package/build/client/assets/{_exerciseNumber_.finished-DaOTQdWd.js.map → _exerciseNumber_.finished-D078JW2f.js.map} +1 -1
  5. package/build/client/assets/{_layout-CJr4y8eX.js → _layout-CcWrk4kg.js} +2 -2
  6. package/build/client/assets/{_layout-CJr4y8eX.js.map → _layout-CcWrk4kg.js.map} +1 -1
  7. package/build/client/assets/{diff-Dwb3EWYp.js → diff-0XgucEQg.js} +2 -2
  8. package/build/client/assets/{diff-Dwb3EWYp.js.map → diff-0XgucEQg.js.map} +1 -1
  9. package/build/client/assets/{diff-Tx3FhzEy.js → diff-C84h1q-R.js} +2 -2
  10. package/build/client/assets/{diff-Tx3FhzEy.js.map → diff-C84h1q-R.js.map} +1 -1
  11. package/build/client/assets/{finished-33U_fnqH.js → finished-CzDipjN1.js} +2 -2
  12. package/build/client/assets/{finished-33U_fnqH.js.map → finished-CzDipjN1.js.map} +1 -1
  13. package/build/client/assets/{index-Dlyr-xKB.js → index-BQT6Cv4C.js} +2 -2
  14. package/build/client/assets/{index-Dlyr-xKB.js.map → index-BQT6Cv4C.js.map} +1 -1
  15. package/build/client/assets/{index-CNnVvQvr.js → index-D13MNswH.js} +2 -2
  16. package/build/client/assets/{index-CNnVvQvr.js.map → index-D13MNswH.js.map} +1 -1
  17. package/build/client/assets/{manifest-23b26aed.js → manifest-5865a9d7.js} +1 -1
  18. package/build/client/assets/mdx-BDFRig3X.js +3 -0
  19. package/build/client/assets/mdx-BDFRig3X.js.map +1 -0
  20. package/build/server/index.js +2 -2
  21. package/build/server/index.js.map +1 -1
  22. package/package.json +3 -3
  23. package/build/client/assets/mdx-Bbi38W8y.js +0 -3
  24. package/build/client/assets/mdx-Bbi38W8y.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{w as n,a as l,L as c,b as m,i as p}from"./chunk-EF7DTUVF-ByhKO_Pl.js";import{j as r}from"./jsx-runtime-EKYJJIwR.js";import{E as x}from"./index-CcWv7OrP.js";import{E as a}from"./epic-video-BODCgn-e.js";import{u as d}from"./revalidation-ws-BMyn5NqG.js";import{M as u,E as f}from"./mdx-Bbi38W8y.js";import{P as h}from"./progress-CkGdQlTp.js";import{g as b}from"./misc-DjWUkK1U.js";import{g as j}from"./seo-t5J-DRxw.js";import"./index-DatCARk7.js";import"./index-MRSoBlHC.js";import"./tooltip-JIUlMcsz.js";import"./index-DA15my8N.js";import"./pe-D3WpHDnY.js";import"./online-CxLmaFqb.js";import"./loading-DJq7N2Fo.js";import"./user-CJVisi_Z.js";import"./workshop-config-CcvXvaNp.js";import"./clsx-B-dksMZM.js";import"./index-Bn6wT_6F.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-C8ErpL4p.js";const O=({data:o,matches:e})=>{const t=o?.exercise.exerciseNumber.toString().padStart(2,"0"),s=e.find(i=>i?.id==="root")?.data;return!o||!s?[{title:"🦉 | Error"}]:j({title:`📝 | ${t}. ${o.exercise.title} | ${s?.workshopTitle}`,description:`Introduction for ${t}. ${o.exercise.title}`,ogTitle:o.exercise.title,ogDescription:`Introduction for exercise ${Number(t)}`,instructor:s.instructor,requestInfo:s.requestInfo})},g={h1:()=>null},Q=n(function({loaderData:e}){d({watchPaths:[e.exerciseReadme.file]});const t=String(e.firstStep?.stepNumber??"01").padStart(2,"0");return r.jsxs("main",{className:"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3",children:[r.jsxs("article",{id:e.articleId,className:"shadow-on-scrollbox flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 scrollbar-thin scrollbar-thumb-scrollbar md:px-10 md:py-12 md:pt-16",children:[r.jsx("div",{children:r.jsx("h1",{className:"text-[clamp(3rem,6vw,7.5rem)] font-extrabold leading-none",children:e.exercise.title})}),r.jsx("div",{children:e.exercise.instructionsCode?r.jsx(a,{epicVideoInfosPromise:e.epicVideoInfosPromise,children:r.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:r.jsx(u,{code:e.exercise.instructionsCode,components:g})})}):"No instructions yet..."})]},e.articleId),r.jsx(x,{elementQuery:`#${e.articleId}`},`scroll-${e.articleId}`),r.jsx(h,{type:"instructions",exerciseNumber:e.exerciseNumber,className:"h-14 border-t px-6"}),r.jsxs("div",{className:"flex h-16 justify-between border-b-4 border-t lg:border-b-0",children:[r.jsx("div",{}),r.jsx(f,{file:e.exerciseReadme.file,relativePath:e.exerciseReadme.relativePath}),r.jsx(c,{to:`${t}/${e.firstType}`,prefetch:"intent",className:"flex h-full items-center justify-center bg-foreground px-7 text-background",children:"Start Learning"})]})]})}),W=l(function(){const e=m();return typeof document<"u"&&console.error(e),p(e)?e.status===404?r.jsx("p",{children:"Sorry, we couldn't find that step."}):r.jsxs("p",{children:[e.status," ",e.data]}):r.jsx("p",{children:b(e)})});export{W as ErrorBoundary,Q as default,O as meta};
2
- //# sourceMappingURL=_exerciseNumber-DLQcM4v6.js.map
1
+ import{w as n,a as l,L as c,b as m,i as p}from"./chunk-EF7DTUVF-ByhKO_Pl.js";import{j as r}from"./jsx-runtime-EKYJJIwR.js";import{E as x}from"./index-CcWv7OrP.js";import{E as a}from"./epic-video-BODCgn-e.js";import{u as d}from"./revalidation-ws-BMyn5NqG.js";import{M as u,E as f}from"./mdx-BDFRig3X.js";import{P as h}from"./progress-CkGdQlTp.js";import{g as b}from"./misc-DjWUkK1U.js";import{g as j}from"./seo-t5J-DRxw.js";import"./index-DatCARk7.js";import"./index-MRSoBlHC.js";import"./tooltip-JIUlMcsz.js";import"./index-DA15my8N.js";import"./pe-D3WpHDnY.js";import"./online-CxLmaFqb.js";import"./loading-DJq7N2Fo.js";import"./user-CJVisi_Z.js";import"./workshop-config-CcvXvaNp.js";import"./clsx-B-dksMZM.js";import"./index-Bn6wT_6F.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-C8ErpL4p.js";const O=({data:o,matches:e})=>{const t=o?.exercise.exerciseNumber.toString().padStart(2,"0"),s=e.find(i=>i?.id==="root")?.data;return!o||!s?[{title:"🦉 | Error"}]:j({title:`📝 | ${t}. ${o.exercise.title} | ${s?.workshopTitle}`,description:`Introduction for ${t}. ${o.exercise.title}`,ogTitle:o.exercise.title,ogDescription:`Introduction for exercise ${Number(t)}`,instructor:s.instructor,requestInfo:s.requestInfo})},g={h1:()=>null},Q=n(function({loaderData:e}){d({watchPaths:[e.exerciseReadme.file]});const t=String(e.firstStep?.stepNumber??"01").padStart(2,"0");return r.jsxs("main",{className:"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3",children:[r.jsxs("article",{id:e.articleId,className:"shadow-on-scrollbox flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 scrollbar-thin scrollbar-thumb-scrollbar md:px-10 md:py-12 md:pt-16",children:[r.jsx("div",{children:r.jsx("h1",{className:"text-[clamp(3rem,6vw,7.5rem)] font-extrabold leading-none",children:e.exercise.title})}),r.jsx("div",{children:e.exercise.instructionsCode?r.jsx(a,{epicVideoInfosPromise:e.epicVideoInfosPromise,children:r.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:r.jsx(u,{code:e.exercise.instructionsCode,components:g})})}):"No instructions yet..."})]},e.articleId),r.jsx(x,{elementQuery:`#${e.articleId}`},`scroll-${e.articleId}`),r.jsx(h,{type:"instructions",exerciseNumber:e.exerciseNumber,className:"h-14 border-t px-6"}),r.jsxs("div",{className:"flex h-16 justify-between border-b-4 border-t lg:border-b-0",children:[r.jsx("div",{}),r.jsx(f,{file:e.exerciseReadme.file,relativePath:e.exerciseReadme.relativePath}),r.jsx(c,{to:`${t}/${e.firstType}`,prefetch:"intent",className:"flex h-full items-center justify-center bg-foreground px-7 text-background",children:"Start Learning"})]})]})}),W=l(function(){const e=m();return typeof document<"u"&&console.error(e),p(e)?e.status===404?r.jsx("p",{children:"Sorry, we couldn't find that step."}):r.jsxs("p",{children:[e.status," ",e.data]}):r.jsx("p",{children:b(e)})});export{W as ErrorBoundary,Q as default,O as meta};
2
+ //# sourceMappingURL=_exerciseNumber-Cnmd182F.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_exerciseNumber-DLQcM4v6.js","sources":["../../../app/routes/_app+/exercise+/$exerciseNumber.tsx"],"sourcesContent":["import path from 'path'\nimport { invariantResponse } from '@epic-web/invariant'\nimport { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopRoot,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport {\n\tdata,\n\ttype HeadersFunction,\n\tLink,\n\tisRouteErrorResponse,\n\tuseRouteError,\n} from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.js'\nimport { type RootLoaderData } from '#app/root.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { ProgressToggle } from '#app/routes/progress.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { getErrorMessage } from '#app/utils/misc.tsx'\nimport { getSeoMetaTags } from '#app/utils/seo.js'\nimport { type Route } from './+types/$exerciseNumber.tsx'\n\nexport const meta: Route.MetaFunction = ({ data, matches }) => {\n\tconst number = data?.exercise.exerciseNumber.toString().padStart(2, '0')\n\n\tconst rootData = matches.find((m) => m?.id === 'root')?.data as RootLoaderData\n\tif (!data || !rootData) return [{ title: '🦉 | Error' }]\n\n\treturn getSeoMetaTags({\n\t\ttitle: `📝 | ${number}. ${data.exercise.title} | ${rootData?.workshopTitle}`,\n\t\tdescription: `Introduction for ${number}. ${data.exercise.title}`,\n\t\togTitle: data.exercise.title,\n\t\togDescription: `Introduction for exercise ${Number(number)}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('exerciseNumberLoader')\n\tinvariantResponse(params.exerciseNumber, 'exerciseNumber is required')\n\tconst { title: workshopTitle } = getWorkshopConfig()\n\tconst exercises = await time(() => getExercises({ request, timings }), {\n\t\ttimings,\n\t\ttype: 'getExercises',\n\t\tdesc: 'getExercises in $exerciseNumber.tsx',\n\t})\n\tconst exercise = exercises.find(\n\t\t(e) => e.exerciseNumber === Number(params.exerciseNumber),\n\t)\n\tif (!exercise) {\n\t\tthrow new Response('Not found', { status: 404 })\n\t}\n\n\tconst readmeFilepath = path.join(\n\t\tgetWorkshopRoot(),\n\t\t'exercises',\n\t\texercise.dirName,\n\t\t'README.mdx',\n\t)\n\n\tconst firstStep = exercise.steps.find(Boolean)\n\n\tconst articleId = `workshop-${slugify(workshopTitle)}-${\n\t\texercise.exerciseNumber\n\t}-instructions`\n\n\treturn data(\n\t\t{\n\t\t\tarticleId,\n\t\t\texercise,\n\t\t\texerciseNumber: exercise.exerciseNumber,\n\t\t\texerciseReadme: {\n\t\t\t\tfile: readmeFilepath,\n\t\t\t\trelativePath: `exercises/${exercise.dirName}`,\n\t\t\t},\n\t\t\texerciseTitle: exercise.title,\n\t\t\tfirstStep,\n\t\t\tfirstType: firstStep?.problem ? 'problem' : 'solution',\n\t\t\ttitle: workshopTitle,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(\n\t\t\t\texercise.instructionsEpicVideoEmbeds,\n\t\t\t\t{ request },\n\t\t\t),\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 const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\n// we'll render the title ourselves thank you\nconst mdxComponents = { h1: () => null }\n\nexport default function ExerciseNumberRoute({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tuseRevalidationWS({\n\t\twatchPaths: [data.exerciseReadme.file],\n\t})\n\n\tconst firstStepNumber = String(data.firstStep?.stepNumber ?? '01').padStart(\n\t\t2,\n\t\t'0',\n\t)\n\treturn (\n\t\t<main className=\"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3\">\n\t\t\t<article\n\t\t\t\tid={data.articleId}\n\t\t\t\tkey={data.articleId}\n\t\t\t\tclassName=\"shadow-on-scrollbox flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 scrollbar-thin scrollbar-thumb-scrollbar md:px-10 md:py-12 md:pt-16\"\n\t\t\t>\n\t\t\t\t<div>\n\t\t\t\t\t<h1 className=\"text-[clamp(3rem,6vw,7.5rem)] font-extrabold leading-none\">\n\t\t\t\t\t\t{data.exercise.title}\n\t\t\t\t\t</h1>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t{data.exercise.instructionsCode ? (\n\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t<Mdx\n\t\t\t\t\t\t\t\t\tcode={data.exercise.instructionsCode}\n\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t'No instructions yet...'\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</article>\n\t\t\t<ElementScrollRestoration\n\t\t\t\telementQuery={`#${data.articleId}`}\n\t\t\t\tkey={`scroll-${data.articleId}`}\n\t\t\t/>\n\t\t\t<ProgressToggle\n\t\t\t\ttype=\"instructions\"\n\t\t\t\texerciseNumber={data.exerciseNumber}\n\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t/>\n\t\t\t<div className=\"flex h-16 justify-between border-b-4 border-t lg:border-b-0\">\n\t\t\t\t<div />\n\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\tfile={data.exerciseReadme.file}\n\t\t\t\t\trelativePath={data.exerciseReadme.relativePath}\n\t\t\t\t/>\n\t\t\t\t<Link\n\t\t\t\t\tto={`${firstStepNumber}/${data.firstType}`}\n\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\tclassName=\"flex h-full items-center justify-center bg-foreground px-7 text-background\"\n\t\t\t\t>\n\t\t\t\t\tStart Learning\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t</main>\n\t)\n}\n\nexport function ErrorBoundary() {\n\tconst error = useRouteError()\n\n\tif (typeof document !== 'undefined') {\n\t\tconsole.error(error)\n\t}\n\n\treturn isRouteErrorResponse(error) ? (\n\t\terror.status === 404 ? (\n\t\t\t<p>Sorry, we couldn't find that step.</p>\n\t\t) : (\n\t\t\t<p>\n\t\t\t\t{error.status} {error.data}\n\t\t\t</p>\n\t\t)\n\t) : (\n\t\t<p>{getErrorMessage(error)}</p>\n\t)\n}\n"],"names":["meta","data","matches","number","exercise","exerciseNumber","toString","padStart","rootData","find","m","id","title","getSeoMetaTags","workshopTitle","description","ogTitle","ogDescription","Number","instructor","requestInfo","mdxComponents","h1","$exerciseNumber","_UNSAFE_withComponentProps","loaderData","useRevalidationWS","watchPaths","exerciseReadme","file","firstStepNumber","String","firstStep","stepNumber","jsxs","className","children","articleId","jsx","instructionsCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","ElementScrollRestoration","elementQuery","ProgressToggle","type","EditFileOnGitHub","relativePath","Link","to","firstType","prefetch","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","error","useRouteError","document","console","isRouteErrorResponse","status","getErrorMessage"],"mappings":"6yBAiCO,MAAMA,EAA2BA,CAAC,CAAEC,KAAAA,EAAMC,QAAAA,CAAQ,IAAM,CAC9D,MAAMC,EAASF,GAAMG,SAASC,eAAeC,WAAWC,SAAS,EAAG,GAAG,EAEjEC,EAAWN,EAAQO,KAAMC,GAAMA,GAAGC,KAAO,MAAM,GAAGV,KACxD,MAAI,CAACA,GAAQ,CAACO,EAAiB,CAAC,CAAEI,MAAO,YAAa,CAAC,EAEhDC,EAAe,CACrBD,MAAO,QAAQT,CAAM,KAAKF,EAAKG,SAASQ,KAAK,MAAMJ,GAAUM,aAAa,GAC1EC,YAAa,oBAAoBZ,CAAM,KAAKF,EAAKG,SAASQ,KAAK,GAC/DI,QAASf,EAAKG,SAASQ,MACvBK,cAAe,6BAA6BC,OAAOf,CAAM,CAAC,GAC1DgB,WAAYX,EAASW,WACrBC,YAAaZ,EAASY,WACvB,CAAC,CACF,EAkEMC,EAAgB,CAAEC,GAAIA,IAAM,IAAK,EAEvCC,EAAAC,EAAA,SAA4C,CAC3CC,WAAYxB,CACb,EAAyB,CACxByB,EAAkB,CACjBC,WAAY,CAAC1B,EAAK2B,eAAeC,IAAI,CACtC,CAAC,EAED,MAAMC,EAAkBC,OAAO9B,EAAK+B,WAAWC,YAAc,IAAI,EAAE1B,SAClE,EACA,GACD,EACA,OACC2B,EAAAA,KAAC,OAAA,CAAKC,UAAU,4FACfC,SAAA,CAAAF,EAAAA,KAAC,UAAA,CACAvB,GAAIV,EAAKoC,UAETF,UAAU,8JAEVC,SAAA,CAAAE,EAAAA,IAAC,MAAA,CACAF,eAAC,KAAA,CAAGD,UAAU,4DACZC,SAAAnC,EAAKG,SAASQ,MAChB,CAAA,CACD,EACA0B,EAAAA,IAAC,MAAA,CACCF,SAAAnC,EAAKG,SAASmC,iBACdD,EAAAA,IAACE,EAAA,CACAC,sBAAuBxC,EAAKwC,sBAE5BL,SAAAE,EAAAA,IAAC,MAAA,CAAIH,UAAU,sCACdC,SAAAE,EAAAA,IAACI,EAAA,CACAC,KAAM1C,EAAKG,SAASmC,iBACpBK,WAAYvB,EACb,EACD,CAAA,CACD,EAEA,wBAAA,CAEF,CAAA,GAvBKpB,EAAKoC,SAwBX,EACAC,EAAAA,IAACO,EAAA,CACAC,aAAc,IAAI7C,EAAKoC,SAAS,EAAA,EAC3B,UAAUpC,EAAKoC,SAAS,EAC9B,EACAC,EAAAA,IAACS,EAAA,CACAC,KAAK,eACL3C,eAAgBJ,EAAKI,eACrB8B,UAAU,oBAAA,CACX,EACAD,EAAAA,KAAC,MAAA,CAAIC,UAAU,8DACdC,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAA,CAAI,EACLA,EAAAA,IAACW,EAAA,CACApB,KAAM5B,EAAK2B,eAAeC,KAC1BqB,aAAcjD,EAAK2B,eAAesB,YAAA,CACnC,EACAZ,EAAAA,IAACa,EAAA,CACAC,GAAI,GAAGtB,CAAe,IAAI7B,EAAKoD,SAAS,GACxCC,SAAS,SACTnB,UAAU,6EACVC,SAAA,gBAAA,CAED,CAAA,CAAA,CACD,CAAA,CAAA,CACD,CAEF,CAAA,EAEOmB,EAAAC,EAAA,UAAyB,CAC/B,MAAMC,EAAQC,EAAA,EAEd,OAAI,OAAOC,SAAa,KACvBC,QAAQH,MAAMA,CAAK,EAGbI,EAAqBJ,CAAK,EAChCA,EAAMK,SAAW,IAChBxB,EAAAA,IAAC,IAAA,CAAEF,SAAA,oCAAA,CAAkC,EAErCF,EAAAA,KAAC,IAAA,CACCE,SAAA,CAAAqB,EAAMK,OAAO,IAAEL,EAAMxD,IAAA,CAAA,CACvB,EAGDqC,EAAAA,IAAC,IAAA,CAAGF,SAAA2B,EAAgBN,CAAK,CAAA,CAAE,CAE7B,CAAA"}
1
+ {"version":3,"file":"_exerciseNumber-Cnmd182F.js","sources":["../../../app/routes/_app+/exercise+/$exerciseNumber.tsx"],"sourcesContent":["import path from 'path'\nimport { invariantResponse } from '@epic-web/invariant'\nimport { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopRoot,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport {\n\tdata,\n\ttype HeadersFunction,\n\tLink,\n\tisRouteErrorResponse,\n\tuseRouteError,\n} from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.js'\nimport { type RootLoaderData } from '#app/root.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { ProgressToggle } from '#app/routes/progress.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { getErrorMessage } from '#app/utils/misc.tsx'\nimport { getSeoMetaTags } from '#app/utils/seo.js'\nimport { type Route } from './+types/$exerciseNumber.tsx'\n\nexport const meta: Route.MetaFunction = ({ data, matches }) => {\n\tconst number = data?.exercise.exerciseNumber.toString().padStart(2, '0')\n\n\tconst rootData = matches.find((m) => m?.id === 'root')?.data as RootLoaderData\n\tif (!data || !rootData) return [{ title: '🦉 | Error' }]\n\n\treturn getSeoMetaTags({\n\t\ttitle: `📝 | ${number}. ${data.exercise.title} | ${rootData?.workshopTitle}`,\n\t\tdescription: `Introduction for ${number}. ${data.exercise.title}`,\n\t\togTitle: data.exercise.title,\n\t\togDescription: `Introduction for exercise ${Number(number)}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('exerciseNumberLoader')\n\tinvariantResponse(params.exerciseNumber, 'exerciseNumber is required')\n\tconst { title: workshopTitle } = getWorkshopConfig()\n\tconst exercises = await time(() => getExercises({ request, timings }), {\n\t\ttimings,\n\t\ttype: 'getExercises',\n\t\tdesc: 'getExercises in $exerciseNumber.tsx',\n\t})\n\tconst exercise = exercises.find(\n\t\t(e) => e.exerciseNumber === Number(params.exerciseNumber),\n\t)\n\tif (!exercise) {\n\t\tthrow new Response('Not found', { status: 404 })\n\t}\n\n\tconst readmeFilepath = path.join(\n\t\tgetWorkshopRoot(),\n\t\t'exercises',\n\t\texercise.dirName,\n\t\t'README.mdx',\n\t)\n\n\tconst firstStep = exercise.steps.find(Boolean)\n\n\tconst articleId = `workshop-${slugify(workshopTitle)}-${\n\t\texercise.exerciseNumber\n\t}-instructions`\n\n\treturn data(\n\t\t{\n\t\t\tarticleId,\n\t\t\texercise,\n\t\t\texerciseNumber: exercise.exerciseNumber,\n\t\t\texerciseReadme: {\n\t\t\t\tfile: readmeFilepath,\n\t\t\t\trelativePath: `exercises/${exercise.dirName}`,\n\t\t\t},\n\t\t\texerciseTitle: exercise.title,\n\t\t\tfirstStep,\n\t\t\tfirstType: firstStep?.problem ? 'problem' : 'solution',\n\t\t\ttitle: workshopTitle,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(\n\t\t\t\texercise.instructionsEpicVideoEmbeds,\n\t\t\t\t{ request },\n\t\t\t),\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 const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\n// we'll render the title ourselves thank you\nconst mdxComponents = { h1: () => null }\n\nexport default function ExerciseNumberRoute({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tuseRevalidationWS({\n\t\twatchPaths: [data.exerciseReadme.file],\n\t})\n\n\tconst firstStepNumber = String(data.firstStep?.stepNumber ?? '01').padStart(\n\t\t2,\n\t\t'0',\n\t)\n\treturn (\n\t\t<main className=\"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3\">\n\t\t\t<article\n\t\t\t\tid={data.articleId}\n\t\t\t\tkey={data.articleId}\n\t\t\t\tclassName=\"shadow-on-scrollbox flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 scrollbar-thin scrollbar-thumb-scrollbar md:px-10 md:py-12 md:pt-16\"\n\t\t\t>\n\t\t\t\t<div>\n\t\t\t\t\t<h1 className=\"text-[clamp(3rem,6vw,7.5rem)] font-extrabold leading-none\">\n\t\t\t\t\t\t{data.exercise.title}\n\t\t\t\t\t</h1>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t{data.exercise.instructionsCode ? (\n\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t<Mdx\n\t\t\t\t\t\t\t\t\tcode={data.exercise.instructionsCode}\n\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t'No instructions yet...'\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</article>\n\t\t\t<ElementScrollRestoration\n\t\t\t\telementQuery={`#${data.articleId}`}\n\t\t\t\tkey={`scroll-${data.articleId}`}\n\t\t\t/>\n\t\t\t<ProgressToggle\n\t\t\t\ttype=\"instructions\"\n\t\t\t\texerciseNumber={data.exerciseNumber}\n\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t/>\n\t\t\t<div className=\"flex h-16 justify-between border-b-4 border-t lg:border-b-0\">\n\t\t\t\t<div />\n\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\tfile={data.exerciseReadme.file}\n\t\t\t\t\trelativePath={data.exerciseReadme.relativePath}\n\t\t\t\t/>\n\t\t\t\t<Link\n\t\t\t\t\tto={`${firstStepNumber}/${data.firstType}`}\n\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\tclassName=\"flex h-full items-center justify-center bg-foreground px-7 text-background\"\n\t\t\t\t>\n\t\t\t\t\tStart Learning\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t</main>\n\t)\n}\n\nexport function ErrorBoundary() {\n\tconst error = useRouteError()\n\n\tif (typeof document !== 'undefined') {\n\t\tconsole.error(error)\n\t}\n\n\treturn isRouteErrorResponse(error) ? (\n\t\terror.status === 404 ? (\n\t\t\t<p>Sorry, we couldn't find that step.</p>\n\t\t) : (\n\t\t\t<p>\n\t\t\t\t{error.status} {error.data}\n\t\t\t</p>\n\t\t)\n\t) : (\n\t\t<p>{getErrorMessage(error)}</p>\n\t)\n}\n"],"names":["meta","data","matches","number","exercise","exerciseNumber","toString","padStart","rootData","find","m","id","title","getSeoMetaTags","workshopTitle","description","ogTitle","ogDescription","Number","instructor","requestInfo","mdxComponents","h1","$exerciseNumber","_UNSAFE_withComponentProps","loaderData","useRevalidationWS","watchPaths","exerciseReadme","file","firstStepNumber","String","firstStep","stepNumber","jsxs","className","children","articleId","jsx","instructionsCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","ElementScrollRestoration","elementQuery","ProgressToggle","type","EditFileOnGitHub","relativePath","Link","to","firstType","prefetch","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","error","useRouteError","document","console","isRouteErrorResponse","status","getErrorMessage"],"mappings":"6yBAiCO,MAAMA,EAA2BA,CAAC,CAAEC,KAAAA,EAAMC,QAAAA,CAAQ,IAAM,CAC9D,MAAMC,EAASF,GAAMG,SAASC,eAAeC,WAAWC,SAAS,EAAG,GAAG,EAEjEC,EAAWN,EAAQO,KAAMC,GAAMA,GAAGC,KAAO,MAAM,GAAGV,KACxD,MAAI,CAACA,GAAQ,CAACO,EAAiB,CAAC,CAAEI,MAAO,YAAa,CAAC,EAEhDC,EAAe,CACrBD,MAAO,QAAQT,CAAM,KAAKF,EAAKG,SAASQ,KAAK,MAAMJ,GAAUM,aAAa,GAC1EC,YAAa,oBAAoBZ,CAAM,KAAKF,EAAKG,SAASQ,KAAK,GAC/DI,QAASf,EAAKG,SAASQ,MACvBK,cAAe,6BAA6BC,OAAOf,CAAM,CAAC,GAC1DgB,WAAYX,EAASW,WACrBC,YAAaZ,EAASY,WACvB,CAAC,CACF,EAkEMC,EAAgB,CAAEC,GAAIA,IAAM,IAAK,EAEvCC,EAAAC,EAAA,SAA4C,CAC3CC,WAAYxB,CACb,EAAyB,CACxByB,EAAkB,CACjBC,WAAY,CAAC1B,EAAK2B,eAAeC,IAAI,CACtC,CAAC,EAED,MAAMC,EAAkBC,OAAO9B,EAAK+B,WAAWC,YAAc,IAAI,EAAE1B,SAClE,EACA,GACD,EACA,OACC2B,EAAAA,KAAC,OAAA,CAAKC,UAAU,4FACfC,SAAA,CAAAF,EAAAA,KAAC,UAAA,CACAvB,GAAIV,EAAKoC,UAETF,UAAU,8JAEVC,SAAA,CAAAE,EAAAA,IAAC,MAAA,CACAF,eAAC,KAAA,CAAGD,UAAU,4DACZC,SAAAnC,EAAKG,SAASQ,MAChB,CAAA,CACD,EACA0B,EAAAA,IAAC,MAAA,CACCF,SAAAnC,EAAKG,SAASmC,iBACdD,EAAAA,IAACE,EAAA,CACAC,sBAAuBxC,EAAKwC,sBAE5BL,SAAAE,EAAAA,IAAC,MAAA,CAAIH,UAAU,sCACdC,SAAAE,EAAAA,IAACI,EAAA,CACAC,KAAM1C,EAAKG,SAASmC,iBACpBK,WAAYvB,EACb,EACD,CAAA,CACD,EAEA,wBAAA,CAEF,CAAA,GAvBKpB,EAAKoC,SAwBX,EACAC,EAAAA,IAACO,EAAA,CACAC,aAAc,IAAI7C,EAAKoC,SAAS,EAAA,EAC3B,UAAUpC,EAAKoC,SAAS,EAC9B,EACAC,EAAAA,IAACS,EAAA,CACAC,KAAK,eACL3C,eAAgBJ,EAAKI,eACrB8B,UAAU,oBAAA,CACX,EACAD,EAAAA,KAAC,MAAA,CAAIC,UAAU,8DACdC,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAA,CAAI,EACLA,EAAAA,IAACW,EAAA,CACApB,KAAM5B,EAAK2B,eAAeC,KAC1BqB,aAAcjD,EAAK2B,eAAesB,YAAA,CACnC,EACAZ,EAAAA,IAACa,EAAA,CACAC,GAAI,GAAGtB,CAAe,IAAI7B,EAAKoD,SAAS,GACxCC,SAAS,SACTnB,UAAU,6EACVC,SAAA,gBAAA,CAED,CAAA,CAAA,CACD,CAAA,CAAA,CACD,CAEF,CAAA,EAEOmB,EAAAC,EAAA,UAAyB,CAC/B,MAAMC,EAAQC,EAAA,EAEd,OAAI,OAAOC,SAAa,KACvBC,QAAQH,MAAMA,CAAK,EAGbI,EAAqBJ,CAAK,EAChCA,EAAMK,SAAW,IAChBxB,EAAAA,IAAC,IAAA,CAAEF,SAAA,oCAAA,CAAkC,EAErCF,EAAAA,KAAC,IAAA,CACCE,SAAA,CAAAqB,EAAMK,OAAO,IAAEL,EAAMxD,IAAA,CAAA,CACvB,EAGDqC,EAAAA,IAAC,IAAA,CAAGF,SAAA2B,EAAgBN,CAAK,CAAA,CAAE,CAE7B,CAAA"}
@@ -1,2 +1,2 @@
1
- import{w as l,L as n}from"./chunk-EF7DTUVF-ByhKO_Pl.js";import{j as e}from"./jsx-runtime-EKYJJIwR.js";import{E as c}from"./index-CcWv7OrP.js";import{r as m}from"./index-DatCARk7.js";import{E as a}from"./epic-video-BODCgn-e.js";import{I as x,c as d}from"./misc-DjWUkK1U.js";import{L as f}from"./loading-DJq7N2Fo.js";import{N as p}from"./nav-chevrons-BOkHwadX.js";import{u as h}from"./revalidation-ws-BMyn5NqG.js";import{M as u,E as b}from"./mdx-Bbi38W8y.js";import{P as j}from"./progress-CkGdQlTp.js";import{u as g}from"./index-MRSoBlHC.js";import{u as N}from"./online-CxLmaFqb.js";import{g as v}from"./seo-t5J-DRxw.js";import"./user-CJVisi_Z.js";import"./workshop-config-CcvXvaNp.js";import"./clsx-B-dksMZM.js";import"./index-DA15my8N.js";import"./index-Bn6wT_6F.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-C8ErpL4p.js";import"./pe-D3WpHDnY.js";import"./tooltip-JIUlMcsz.js";const B=({data:s,matches:r})=>{const i=s?.exercise.exerciseNumber.toString().padStart(2,"0"),o=r.find(t=>t?.id==="root")?.data;return!s||!o?[{title:"🦉 | Error"}]:v({title:`🦉 | ${i}. ${s.exercise.title} | ${o?.workshopTitle}`,description:`Elaboration for ${i}. ${s.exercise.title}`,ogTitle:`Finished: ${s.exercise.title}`,ogDescription:`Elaboration for exercise ${Number(i)}`,instructor:o.instructor,requestInfo:o.requestInfo})},w={h1:()=>null},J=l(function({loaderData:r}){const i=r.exercise.exerciseNumber.toString().padStart(2,"0");return h({watchPaths:[`./exercises/${i}/FINISHED.mdx`]}),e.jsx("div",{className:"flex max-w-full flex-grow flex-col",children:e.jsxs("main",{className:"flex flex-grow flex-col sm:grid sm:h-full sm:min-h-[800px] sm:grid-cols-1 sm:grid-rows-2 md:min-h-[unset] lg:grid-cols-2 lg:grid-rows-1",children:[e.jsxs("div",{className:"relative flex flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:border-r",children:[e.jsx("h1",{className:"h-14 border-b pl-10 pr-5 text-sm font-medium leading-tight",children:e.jsx("div",{className:"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2",children:e.jsxs("div",{className:"flex items-center justify-start gap-x-2",children:[e.jsx(n,{to:`/${i}`,className:"hover:underline",children:`${i}. ${r.exercise.title}`}),e.jsx("span",{children:"/"}),e.jsx("span",{children:"Elaboration"})]})})}),e.jsx("article",{className:"shadow-on-scrollbox h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 scrollbar-thin scrollbar-thumb-scrollbar sm:p-10 sm:pt-8",id:r.articleId,children:r.exercise.finishedCode?e.jsx(a,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(u,{code:r.exercise.finishedCode,components:w})})}):"No finished instructions yet..."}),e.jsx(c,{elementQuery:`#${r.articleId}`}),e.jsx(j,{type:"finished",exerciseNumber:r.exercise.exerciseNumber,className:"h-14 border-t px-6"}),e.jsxs("div",{className:"flex h-16 justify-between border-b-4 border-t lg:border-b-0",children:[e.jsx("div",{}),e.jsx(b,{file:r.exerciseFinished.file,relativePath:r.exerciseFinished.relativePath}),e.jsx(p,{prev:r.prevStepLink,next:r.nextStepLink})]})]}),e.jsx(E,{exerciseFormEmbedUrl:r.exerciseFormEmbedUrl,exerciseTitle:r.exercise.title})]})})});function E({exerciseFormEmbedUrl:s,exerciseTitle:r}){const i=g(),[o,t]=m.useState(!1);return N()?e.jsxs("div",{className:"relative min-h-full sm:min-h-[unset] sm:flex-shrink-0",children:[o?null:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center",children:e.jsx(f,{children:e.jsxs("span",{children:["Loading ",r," Elaboration form"]})})}),e.jsx("iframe",{onLoad:()=>t(!0),onError:()=>t(!0),title:"Elaboration",src:s,className:d("absolute inset-0 flex h-full w-full transition-opacity duration-300",o?"opacity-100":"opacity-0"),style:{colorScheme:i}})]}):e.jsx("div",{className:"relative flex-shrink-0",children:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center text-body-md text-foreground-destructive",children:e.jsx(x,{name:"WifiNoConnection",size:"xl",children:e.jsxs("span",{children:["Unable to load the ",e.jsx("a",{href:s,className:"underline",children:`${r} feedback form`})," when offline"]})})})})}export{J as default,B as meta};
2
- //# sourceMappingURL=_exerciseNumber_.finished-DaOTQdWd.js.map
1
+ import{w as l,L as n}from"./chunk-EF7DTUVF-ByhKO_Pl.js";import{j as e}from"./jsx-runtime-EKYJJIwR.js";import{E as c}from"./index-CcWv7OrP.js";import{r as m}from"./index-DatCARk7.js";import{E as a}from"./epic-video-BODCgn-e.js";import{I as x,c as d}from"./misc-DjWUkK1U.js";import{L as f}from"./loading-DJq7N2Fo.js";import{N as p}from"./nav-chevrons-BOkHwadX.js";import{u as h}from"./revalidation-ws-BMyn5NqG.js";import{M as u,E as b}from"./mdx-BDFRig3X.js";import{P as j}from"./progress-CkGdQlTp.js";import{u as g}from"./index-MRSoBlHC.js";import{u as N}from"./online-CxLmaFqb.js";import{g as v}from"./seo-t5J-DRxw.js";import"./user-CJVisi_Z.js";import"./workshop-config-CcvXvaNp.js";import"./clsx-B-dksMZM.js";import"./index-DA15my8N.js";import"./index-Bn6wT_6F.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-C8ErpL4p.js";import"./pe-D3WpHDnY.js";import"./tooltip-JIUlMcsz.js";const B=({data:s,matches:r})=>{const i=s?.exercise.exerciseNumber.toString().padStart(2,"0"),o=r.find(t=>t?.id==="root")?.data;return!s||!o?[{title:"🦉 | Error"}]:v({title:`🦉 | ${i}. ${s.exercise.title} | ${o?.workshopTitle}`,description:`Elaboration for ${i}. ${s.exercise.title}`,ogTitle:`Finished: ${s.exercise.title}`,ogDescription:`Elaboration for exercise ${Number(i)}`,instructor:o.instructor,requestInfo:o.requestInfo})},w={h1:()=>null},J=l(function({loaderData:r}){const i=r.exercise.exerciseNumber.toString().padStart(2,"0");return h({watchPaths:[`./exercises/${i}/FINISHED.mdx`]}),e.jsx("div",{className:"flex max-w-full flex-grow flex-col",children:e.jsxs("main",{className:"flex flex-grow flex-col sm:grid sm:h-full sm:min-h-[800px] sm:grid-cols-1 sm:grid-rows-2 md:min-h-[unset] lg:grid-cols-2 lg:grid-rows-1",children:[e.jsxs("div",{className:"relative flex flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:border-r",children:[e.jsx("h1",{className:"h-14 border-b pl-10 pr-5 text-sm font-medium leading-tight",children:e.jsx("div",{className:"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2",children:e.jsxs("div",{className:"flex items-center justify-start gap-x-2",children:[e.jsx(n,{to:`/${i}`,className:"hover:underline",children:`${i}. ${r.exercise.title}`}),e.jsx("span",{children:"/"}),e.jsx("span",{children:"Elaboration"})]})})}),e.jsx("article",{className:"shadow-on-scrollbox h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 scrollbar-thin scrollbar-thumb-scrollbar sm:p-10 sm:pt-8",id:r.articleId,children:r.exercise.finishedCode?e.jsx(a,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(u,{code:r.exercise.finishedCode,components:w})})}):"No finished instructions yet..."}),e.jsx(c,{elementQuery:`#${r.articleId}`}),e.jsx(j,{type:"finished",exerciseNumber:r.exercise.exerciseNumber,className:"h-14 border-t px-6"}),e.jsxs("div",{className:"flex h-16 justify-between border-b-4 border-t lg:border-b-0",children:[e.jsx("div",{}),e.jsx(b,{file:r.exerciseFinished.file,relativePath:r.exerciseFinished.relativePath}),e.jsx(p,{prev:r.prevStepLink,next:r.nextStepLink})]})]}),e.jsx(E,{exerciseFormEmbedUrl:r.exerciseFormEmbedUrl,exerciseTitle:r.exercise.title})]})})});function E({exerciseFormEmbedUrl:s,exerciseTitle:r}){const i=g(),[o,t]=m.useState(!1);return N()?e.jsxs("div",{className:"relative min-h-full sm:min-h-[unset] sm:flex-shrink-0",children:[o?null:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center",children:e.jsx(f,{children:e.jsxs("span",{children:["Loading ",r," Elaboration form"]})})}),e.jsx("iframe",{onLoad:()=>t(!0),onError:()=>t(!0),title:"Elaboration",src:s,className:d("absolute inset-0 flex h-full w-full transition-opacity duration-300",o?"opacity-100":"opacity-0"),style:{colorScheme:i}})]}):e.jsx("div",{className:"relative flex-shrink-0",children:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center text-body-md text-foreground-destructive",children:e.jsx(x,{name:"WifiNoConnection",size:"xl",children:e.jsxs("span",{children:["Unable to load the ",e.jsx("a",{href:s,className:"underline",children:`${r} feedback form`})," when offline"]})})})})}export{J as default,B as meta};
2
+ //# sourceMappingURL=_exerciseNumber_.finished-D078JW2f.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_exerciseNumber_.finished-DaOTQdWd.js","sources":["../../../app/routes/_app+/exercise+/$exerciseNumber_.finished.tsx"],"sourcesContent":["import path from 'path'\nimport { invariantResponse } from '@epic-web/invariant'\nimport { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetAppPageRoute,\n\tgetApps,\n\tgetExercise,\n\tgetWorkshopRoot,\n\tisExerciseStepApp,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport * as React from 'react'\nimport { data, type HeadersFunction, Link } from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { Icon } from '#app/components/icons.tsx'\nimport { Loading } from '#app/components/loading.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.js'\nimport { type RootLoaderData } from '#app/root.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { ProgressToggle } from '#app/routes/progress.tsx'\nimport { useTheme } from '#app/routes/theme/index.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { useIsOnline } from '#app/utils/online.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.js'\nimport { type Route } from './+types/$exerciseNumber_.finished.tsx'\n\nexport const meta: Route.MetaFunction = ({ data, matches }) => {\n\tconst number = data?.exercise.exerciseNumber.toString().padStart(2, '0')\n\n\tconst rootData = matches.find((m) => m?.id === 'root')?.data as RootLoaderData\n\tif (!data || !rootData) return [{ title: '🦉 | Error' }]\n\n\treturn getSeoMetaTags({\n\t\ttitle: `🦉 | ${number}. ${data.exercise.title} | ${rootData?.workshopTitle}`,\n\t\tdescription: `Elaboration for ${number}. ${data.exercise.title}`,\n\t\togTitle: `Finished: ${data.exercise.title}`,\n\t\togDescription: `Elaboration for exercise ${Number(number)}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('exerciseFinishedLoader')\n\tinvariantResponse(params.exerciseNumber, 'exerciseNumber is required')\n\tconst exercise = await getExercise(params.exerciseNumber, {\n\t\ttimings,\n\t\trequest,\n\t})\n\tif (!exercise) {\n\t\tthrow new Response('Not found', { status: 404 })\n\t}\n\tconst workshopConfig = getWorkshopConfig()\n\tconst exerciseFormTemplate = workshopConfig.forms.exercise\n\tconst exerciseFormEmbedUrl = exerciseFormTemplate\n\t\t.replace('{workshopTitle}', encodeURIComponent(workshopConfig.title))\n\t\t.replace('{exerciseTitle}', encodeURIComponent(exercise.title))\n\tconst nextExercise = await getExercise(exercise.exerciseNumber + 1, {\n\t\ttimings,\n\t\trequest,\n\t})\n\n\tconst finishedFilepath = path.join(\n\t\tgetWorkshopRoot(),\n\t\t'exercises',\n\t\texercise.dirName,\n\t\t'FINISHED.mdx',\n\t)\n\n\tconst apps = await getApps({ request, timings })\n\tconst exerciseApps = apps\n\t\t.filter(isExerciseStepApp)\n\t\t.filter((app) => app.exerciseNumber === exercise.exerciseNumber)\n\tconst prevApp = exerciseApps[exerciseApps.length - 1]\n\n\tconst articleId = `workshop-${slugify(workshopConfig.title)}-${\n\t\texercise.exerciseNumber\n\t}-finished`\n\n\treturn data(\n\t\t{\n\t\t\tarticleId,\n\t\t\tworkshopTitle: workshopConfig.title,\n\t\t\texercise,\n\t\t\texerciseFormEmbedUrl,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(\n\t\t\t\texercise.finishedEpicVideoEmbeds,\n\t\t\t\t{ request },\n\t\t\t),\n\t\t\texerciseFinished: {\n\t\t\t\tfile: finishedFilepath,\n\t\t\t\trelativePath: `exercises/${exercise.dirName}/FINISHED.mdx`,\n\t\t\t},\n\t\t\tprevStepLink: prevApp\n\t\t\t\t? {\n\t\t\t\t\t\tto: getAppPageRoute(prevApp),\n\t\t\t\t\t\t'aria-label': `${prevApp.title} (${prevApp.type})`,\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t\tnextStepLink: nextExercise\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/exercise/${nextExercise.exerciseNumber.toString().padStart(2, '0')}`,\n\t\t\t\t\t\t'aria-label': `${nextExercise.title}`,\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tto: '/finished',\n\t\t\t\t\t\t'aria-label': 'Finished! 🎉',\n\t\t\t\t\t},\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 const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nconst mdxComponents = { h1: () => null }\nexport default function ExerciseFinished({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tconst exerciseNumber = data.exercise.exerciseNumber\n\t\t.toString()\n\t\t.padStart(2, '0')\n\n\tuseRevalidationWS({\n\t\twatchPaths: [`./exercises/${exerciseNumber}/FINISHED.mdx`],\n\t})\n\n\treturn (\n\t\t<div className=\"flex max-w-full flex-grow flex-col\">\n\t\t\t<main className=\"flex flex-grow flex-col sm:grid sm:h-full sm:min-h-[800px] sm:grid-cols-1 sm:grid-rows-2 md:min-h-[unset] lg:grid-cols-2 lg:grid-rows-1\">\n\t\t\t\t<div className=\"relative flex flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:border-r\">\n\t\t\t\t\t<h1 className=\"h-14 border-b pl-10 pr-5 text-sm font-medium leading-tight\">\n\t\t\t\t\t\t<div className=\"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2\">\n\t\t\t\t\t\t\t\t<Link to={`/${exerciseNumber}`} className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t{`${exerciseNumber}. ${data.exercise.title}`}\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t<span>/</span>\n\t\t\t\t\t\t\t\t<span>Elaboration</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</h1>\n\n\t\t\t\t\t<article\n\t\t\t\t\t\tclassName=\"shadow-on-scrollbox h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 scrollbar-thin scrollbar-thumb-scrollbar sm:p-10 sm:pt-8\"\n\t\t\t\t\t\tid={data.articleId}\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.exercise.finishedCode ? (\n\t\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t\t<Mdx\n\t\t\t\t\t\t\t\t\t\tcode={data.exercise.finishedCode}\n\t\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t// TODO: render a random dad joke...\n\t\t\t\t\t\t\t'No finished instructions yet...'\n\t\t\t\t\t\t)}\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration elementQuery={`#${data.articleId}`} />\n\t\t\t\t\t<ProgressToggle\n\t\t\t\t\t\ttype=\"finished\"\n\t\t\t\t\t\texerciseNumber={data.exercise.exerciseNumber}\n\t\t\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"flex h-16 justify-between border-b-4 border-t lg:border-b-0\">\n\t\t\t\t\t\t<div />\n\t\t\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\t\t\tfile={data.exerciseFinished.file}\n\t\t\t\t\t\t\trelativePath={data.exerciseFinished.relativePath}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<NavChevrons prev={data.prevStepLink} next={data.nextStepLink} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<Survey\n\t\t\t\t\texerciseFormEmbedUrl={data.exerciseFormEmbedUrl}\n\t\t\t\t\texerciseTitle={data.exercise.title}\n\t\t\t\t/>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nfunction Survey({\n\texerciseFormEmbedUrl,\n\texerciseTitle,\n}: {\n\texerciseFormEmbedUrl: string\n\texerciseTitle: string\n}) {\n\tconst theme = useTheme()\n\tconst [iframeLoaded, setIframeLoaded] = React.useState(false)\n\tconst isOnline = useIsOnline()\n\tif (!isOnline) {\n\t\treturn (\n\t\t\t<div className=\"relative flex-shrink-0\">\n\t\t\t\t<div className=\"absolute inset-0 z-10 flex items-center justify-center text-body-md text-foreground-destructive\">\n\t\t\t\t\t<Icon name=\"WifiNoConnection\" size=\"xl\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{'Unable to load the '}\n\t\t\t\t\t\t\t<a href={exerciseFormEmbedUrl} className=\"underline\">\n\t\t\t\t\t\t\t\t{`${exerciseTitle} feedback form`}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t{' when offline'}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Icon>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t)\n\t}\n\treturn (\n\t\t<div className=\"relative min-h-full sm:min-h-[unset] sm:flex-shrink-0\">\n\t\t\t{!iframeLoaded ? (\n\t\t\t\t<div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n\t\t\t\t\t<Loading>\n\t\t\t\t\t\t<span>Loading {exerciseTitle} Elaboration form</span>\n\t\t\t\t\t</Loading>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<iframe\n\t\t\t\tonLoad={() => setIframeLoaded(true)}\n\t\t\t\t// show what would have shown if there is an error\n\t\t\t\tonError={() => setIframeLoaded(true)}\n\t\t\t\ttitle=\"Elaboration\"\n\t\t\t\tsrc={exerciseFormEmbedUrl}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'absolute inset-0 flex h-full w-full transition-opacity duration-300',\n\t\t\t\t\tiframeLoaded ? 'opacity-100' : 'opacity-0',\n\t\t\t\t)}\n\t\t\t\tstyle={{ colorScheme: theme }}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],"names":["meta","data","matches","number","exercise","exerciseNumber","toString","padStart","rootData","find","m","id","title","getSeoMetaTags","workshopTitle","description","ogTitle","ogDescription","Number","instructor","requestInfo","mdxComponents","h1","$exerciseNumber__finished","_UNSAFE_withComponentProps","loaderData","useRevalidationWS","watchPaths","className","children","jsxs","jsx","Link","to","articleId","finishedCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","ElementScrollRestoration","elementQuery","ProgressToggle","type","EditFileOnGitHub","file","exerciseFinished","relativePath","NavChevrons","prev","prevStepLink","next","nextStepLink","Survey","exerciseFormEmbedUrl","exerciseTitle","theme","useTheme","iframeLoaded","setIframeLoaded","React","useIsOnline","Loading","onLoad","onError","src","cn","style","colorScheme","Icon","name","size","href"],"mappings":"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"}
1
+ {"version":3,"file":"_exerciseNumber_.finished-D078JW2f.js","sources":["../../../app/routes/_app+/exercise+/$exerciseNumber_.finished.tsx"],"sourcesContent":["import path from 'path'\nimport { invariantResponse } from '@epic-web/invariant'\nimport { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetAppPageRoute,\n\tgetApps,\n\tgetExercise,\n\tgetWorkshopRoot,\n\tisExerciseStepApp,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport * as React from 'react'\nimport { data, type HeadersFunction, Link } from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { Icon } from '#app/components/icons.tsx'\nimport { Loading } from '#app/components/loading.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.js'\nimport { type RootLoaderData } from '#app/root.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { ProgressToggle } from '#app/routes/progress.tsx'\nimport { useTheme } from '#app/routes/theme/index.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { useIsOnline } from '#app/utils/online.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.js'\nimport { type Route } from './+types/$exerciseNumber_.finished.tsx'\n\nexport const meta: Route.MetaFunction = ({ data, matches }) => {\n\tconst number = data?.exercise.exerciseNumber.toString().padStart(2, '0')\n\n\tconst rootData = matches.find((m) => m?.id === 'root')?.data as RootLoaderData\n\tif (!data || !rootData) return [{ title: '🦉 | Error' }]\n\n\treturn getSeoMetaTags({\n\t\ttitle: `🦉 | ${number}. ${data.exercise.title} | ${rootData?.workshopTitle}`,\n\t\tdescription: `Elaboration for ${number}. ${data.exercise.title}`,\n\t\togTitle: `Finished: ${data.exercise.title}`,\n\t\togDescription: `Elaboration for exercise ${Number(number)}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('exerciseFinishedLoader')\n\tinvariantResponse(params.exerciseNumber, 'exerciseNumber is required')\n\tconst exercise = await getExercise(params.exerciseNumber, {\n\t\ttimings,\n\t\trequest,\n\t})\n\tif (!exercise) {\n\t\tthrow new Response('Not found', { status: 404 })\n\t}\n\tconst workshopConfig = getWorkshopConfig()\n\tconst exerciseFormTemplate = workshopConfig.forms.exercise\n\tconst exerciseFormEmbedUrl = exerciseFormTemplate\n\t\t.replace('{workshopTitle}', encodeURIComponent(workshopConfig.title))\n\t\t.replace('{exerciseTitle}', encodeURIComponent(exercise.title))\n\tconst nextExercise = await getExercise(exercise.exerciseNumber + 1, {\n\t\ttimings,\n\t\trequest,\n\t})\n\n\tconst finishedFilepath = path.join(\n\t\tgetWorkshopRoot(),\n\t\t'exercises',\n\t\texercise.dirName,\n\t\t'FINISHED.mdx',\n\t)\n\n\tconst apps = await getApps({ request, timings })\n\tconst exerciseApps = apps\n\t\t.filter(isExerciseStepApp)\n\t\t.filter((app) => app.exerciseNumber === exercise.exerciseNumber)\n\tconst prevApp = exerciseApps[exerciseApps.length - 1]\n\n\tconst articleId = `workshop-${slugify(workshopConfig.title)}-${\n\t\texercise.exerciseNumber\n\t}-finished`\n\n\treturn data(\n\t\t{\n\t\t\tarticleId,\n\t\t\tworkshopTitle: workshopConfig.title,\n\t\t\texercise,\n\t\t\texerciseFormEmbedUrl,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(\n\t\t\t\texercise.finishedEpicVideoEmbeds,\n\t\t\t\t{ request },\n\t\t\t),\n\t\t\texerciseFinished: {\n\t\t\t\tfile: finishedFilepath,\n\t\t\t\trelativePath: `exercises/${exercise.dirName}/FINISHED.mdx`,\n\t\t\t},\n\t\t\tprevStepLink: prevApp\n\t\t\t\t? {\n\t\t\t\t\t\tto: getAppPageRoute(prevApp),\n\t\t\t\t\t\t'aria-label': `${prevApp.title} (${prevApp.type})`,\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t\tnextStepLink: nextExercise\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/exercise/${nextExercise.exerciseNumber.toString().padStart(2, '0')}`,\n\t\t\t\t\t\t'aria-label': `${nextExercise.title}`,\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tto: '/finished',\n\t\t\t\t\t\t'aria-label': 'Finished! 🎉',\n\t\t\t\t\t},\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 const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nconst mdxComponents = { h1: () => null }\nexport default function ExerciseFinished({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tconst exerciseNumber = data.exercise.exerciseNumber\n\t\t.toString()\n\t\t.padStart(2, '0')\n\n\tuseRevalidationWS({\n\t\twatchPaths: [`./exercises/${exerciseNumber}/FINISHED.mdx`],\n\t})\n\n\treturn (\n\t\t<div className=\"flex max-w-full flex-grow flex-col\">\n\t\t\t<main className=\"flex flex-grow flex-col sm:grid sm:h-full sm:min-h-[800px] sm:grid-cols-1 sm:grid-rows-2 md:min-h-[unset] lg:grid-cols-2 lg:grid-rows-1\">\n\t\t\t\t<div className=\"relative flex flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:border-r\">\n\t\t\t\t\t<h1 className=\"h-14 border-b pl-10 pr-5 text-sm font-medium leading-tight\">\n\t\t\t\t\t\t<div className=\"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2\">\n\t\t\t\t\t\t\t\t<Link to={`/${exerciseNumber}`} className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t{`${exerciseNumber}. ${data.exercise.title}`}\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t<span>/</span>\n\t\t\t\t\t\t\t\t<span>Elaboration</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</h1>\n\n\t\t\t\t\t<article\n\t\t\t\t\t\tclassName=\"shadow-on-scrollbox h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 scrollbar-thin scrollbar-thumb-scrollbar sm:p-10 sm:pt-8\"\n\t\t\t\t\t\tid={data.articleId}\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.exercise.finishedCode ? (\n\t\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t\t<Mdx\n\t\t\t\t\t\t\t\t\t\tcode={data.exercise.finishedCode}\n\t\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t// TODO: render a random dad joke...\n\t\t\t\t\t\t\t'No finished instructions yet...'\n\t\t\t\t\t\t)}\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration elementQuery={`#${data.articleId}`} />\n\t\t\t\t\t<ProgressToggle\n\t\t\t\t\t\ttype=\"finished\"\n\t\t\t\t\t\texerciseNumber={data.exercise.exerciseNumber}\n\t\t\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"flex h-16 justify-between border-b-4 border-t lg:border-b-0\">\n\t\t\t\t\t\t<div />\n\t\t\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\t\t\tfile={data.exerciseFinished.file}\n\t\t\t\t\t\t\trelativePath={data.exerciseFinished.relativePath}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<NavChevrons prev={data.prevStepLink} next={data.nextStepLink} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<Survey\n\t\t\t\t\texerciseFormEmbedUrl={data.exerciseFormEmbedUrl}\n\t\t\t\t\texerciseTitle={data.exercise.title}\n\t\t\t\t/>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nfunction Survey({\n\texerciseFormEmbedUrl,\n\texerciseTitle,\n}: {\n\texerciseFormEmbedUrl: string\n\texerciseTitle: string\n}) {\n\tconst theme = useTheme()\n\tconst [iframeLoaded, setIframeLoaded] = React.useState(false)\n\tconst isOnline = useIsOnline()\n\tif (!isOnline) {\n\t\treturn (\n\t\t\t<div className=\"relative flex-shrink-0\">\n\t\t\t\t<div className=\"absolute inset-0 z-10 flex items-center justify-center text-body-md text-foreground-destructive\">\n\t\t\t\t\t<Icon name=\"WifiNoConnection\" size=\"xl\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{'Unable to load the '}\n\t\t\t\t\t\t\t<a href={exerciseFormEmbedUrl} className=\"underline\">\n\t\t\t\t\t\t\t\t{`${exerciseTitle} feedback form`}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t{' when offline'}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Icon>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t)\n\t}\n\treturn (\n\t\t<div className=\"relative min-h-full sm:min-h-[unset] sm:flex-shrink-0\">\n\t\t\t{!iframeLoaded ? (\n\t\t\t\t<div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n\t\t\t\t\t<Loading>\n\t\t\t\t\t\t<span>Loading {exerciseTitle} Elaboration form</span>\n\t\t\t\t\t</Loading>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<iframe\n\t\t\t\tonLoad={() => setIframeLoaded(true)}\n\t\t\t\t// show what would have shown if there is an error\n\t\t\t\tonError={() => setIframeLoaded(true)}\n\t\t\t\ttitle=\"Elaboration\"\n\t\t\t\tsrc={exerciseFormEmbedUrl}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'absolute inset-0 flex h-full w-full transition-opacity duration-300',\n\t\t\t\t\tiframeLoaded ? 'opacity-100' : 'opacity-0',\n\t\t\t\t)}\n\t\t\t\tstyle={{ colorScheme: theme }}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],"names":["meta","data","matches","number","exercise","exerciseNumber","toString","padStart","rootData","find","m","id","title","getSeoMetaTags","workshopTitle","description","ogTitle","ogDescription","Number","instructor","requestInfo","mdxComponents","h1","$exerciseNumber__finished","_UNSAFE_withComponentProps","loaderData","useRevalidationWS","watchPaths","className","children","jsxs","jsx","Link","to","articleId","finishedCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","ElementScrollRestoration","elementQuery","ProgressToggle","type","EditFileOnGitHub","file","exerciseFinished","relativePath","NavChevrons","prev","prevStepLink","next","nextStepLink","Survey","exerciseFormEmbedUrl","exerciseTitle","theme","useTheme","iframeLoaded","setIframeLoaded","React","useIsOnline","Loading","onLoad","onError","src","cn","style","colorScheme","Icon","name","size","href"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{c as E,l as ae,L as j,A as le,w as ce,a as pe,O as ue}from"./chunk-EF7DTUVF-ByhKO_Pl.js";import{j as e}from"./jsx-runtime-EKYJJIwR.js";import{E as de}from"./index-CcWv7OrP.js";import{r as l}from"./index-DatCARk7.js";import{G as fe}from"./error-boundary-CEFnSCa2.js";import{N as me}from"./nav-chevrons-BOkHwadX.js";import{u as xe}from"./revalidation-ws-BMyn5NqG.js";import{M as he,L as y,E as ve}from"./mdx-Bbi38W8y.js";import{P as ge}from"./progress-CkGdQlTp.js";import{S as H}from"./set-playground-CCf6DmQr.js";import{a as Pe,c as T,I as D,i as je,b as be}from"./misc-DjWUkK1U.js";import{g as Ne}from"./seo-t5J-DRxw.js";import{E as we}from"./epic-video-BODCgn-e.js";import{S as k,j as U,u as Ee,R as Se,d as Ce,e as ye,h as V,P as B,f as w,A as Y,g as G,k as Re,D as Oe,C as Ae,l as De}from"./tooltip-JIUlMcsz.js";import{a as ke}from"./index-MRSoBlHC.js";import{P as Le,h as _e,R as Ie,u as $e,F as Fe}from"./index-Be-5FhjB.js";import"./preload-helper-BXl3LOEh.js";import"./clsx-B-dksMZM.js";import"./index-DA15my8N.js";import"./index-Bn6wT_6F.js";import"./progress-bar-C8ErpL4p.js";import"./pe-D3WpHDnY.js";import"./index-2USrBHAC.js";import"./online-CxLmaFqb.js";import"./loading-DJq7N2Fo.js";import"./user-CJVisi_Z.js";import"./workshop-config-CcvXvaNp.js";const q=l.createContext(null);function Te(){const t=l.useContext(q);if(!t)throw new Error("useStepContext must be used within a StepContext.Provider");return t}function Me({children:t,inBrowserBrowserRef:r}){return e.jsx(q.Provider,{value:{inBrowserBrowserRef:r},children:t})}const He={DiffLink:L,PrevDiffLink:Be,NextDiffLink:Ve,InlineFile:Ye,LinkToApp:qe};function Ue({inBrowserBrowserRef:t}){const r=E();return r.exerciseStepApp.instructionsCode?e.jsx(Me,{inBrowserBrowserRef:t,children:e.jsx(we,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(he,{code:r.exerciseStepApp.instructionsCode,components:He})})})}):null}function X(t,r,o){const i=new URLSearchParams(t);return o===null?i.delete(r):i.set(r,o),i}function Ve({app:t=0,fullPage:r=!1,children:o}){return e.jsx(L,{app1:t,app2:t+1,fullPage:r,children:o})}function Be({app:t=-1,fullPage:r=!1,children:o}){return e.jsx(L,{app1:t,app2:t+1,fullPage:r,children:o})}function L({app1:t=0,app2:r=1,children:o,fullPage:i=!1,to:n}){const s=E();if(!n&&!t&&!r)return e.jsx("callout-danger",{className:"notification",children:e.jsx("div",{className:"title",children:"DiffLink Error: invalid input"})});function a(u){if(typeof u=="number"){const f=s.exerciseIndex+u;return s.allApps[f]?.name}if(!u)return null;for(const{name:f,stepName:d}of s.allApps)if(u===f||u===d)return f;return null}if(n){const u=new URLSearchParams(n);t=u.get("app1"),r=u.get("app2")}const c=a(t),p=a(r);if(!c||!p)return e.jsxs("callout-danger",{className:"notification",children:[e.jsx("div",{className:"title",children:"DiffLink Error: invalid input"}),!c&&e.jsxs("div",{children:['app1: "',t,'" is not a valid app name']}),!p&&e.jsxs("div",{children:['app2: "',r,'" is not a valid app name']})]});n||(n=`app1=${c}&app2=${p}`);const m=i?`/diff?${n}`:`?${decodeURIComponent(X(new URLSearchParams,"preview",`diff&${n}`).toString())}`;return o||(o=e.jsxs("span",{children:["Go to Diff ",i?"":"Preview"," from: ",e.jsx("code",{children:c})," to:"," ",e.jsx("code",{children:p})]})),e.jsx(j,{to:m,children:o})}function Ye({file:t,type:r="playground",children:o=e.jsx("code",{children:t}),...i}){const n=E(),s=n[r]||n[n.type],a=e.jsxs("div",{className:"launch-editor-button-wrapper flex underline underline-offset-4",children:[o," ",e.jsx("svg",{height:24,width:24,children:e.jsx("use",{href:`${je}#Keyboard`})})]});return ENV.EPICSHOP_DEPLOYED&&s?e.jsx("div",{className:"inline-block grow",children:e.jsx(y,{appFile:t,appName:s.name,...i,children:a})}):s?e.jsx("div",{className:"inline-block grow",children:e.jsx(y,{appFile:t,appName:s.name,...i,children:a})}):r==="playground"?e.jsx(k,{content:"You must 'Set to Playground' before opening a file",children:e.jsx("div",{className:"inline-block grow cursor-not-allowed",children:a})}):e.jsx(e.Fragment,{children:"children"})}function Ge(t){return t==="problem"?"problem":t==="solution"?"solution":"playground"}function qe({to:t,children:r=e.jsx("code",{children:t.toString()}),...o}){const[i]=ae(),n=`?${X(i,"pathname",t.toString()).toString()}`,s=E(),a=Ge(i.get("preview")),c=ke(),p=s[a],m=p?.dev.type==="script"?Pe({domain:c.domain,port:p.dev.portNumber}):s.playground?.dev.type==="browser"?s.playground.dev.pathname:null,{inBrowserBrowserRef:u}=Te(),f=m?m.slice(0,-1)+t.toString():null;return e.jsxs("div",{className:"inline-flex items-center justify-between gap-1",children:[e.jsx(j,{to:n,...o,className:T(o.className,{"cursor-not-allowed":ENV.EPICSHOP_DEPLOYED}),title:ENV.EPICSHOP_DEPLOYED?"Cannot link to app in deployed version":void 0,onClick:d=>{ENV.EPICSHOP_DEPLOYED&&d.preventDefault(),o.onClick?.(d),u.current?.handleExtrnalNavigation(t.toString())},children:r}),f?e.jsx(k,{content:"Open in new tab",children:e.jsx("a",{href:f,target:"_blank",rel:"noreferrer",className:T("flex aspect-square items-center justify-center",{"cursor-not-allowed":ENV.EPICSHOP_DEPLOYED}),title:ENV.EPICSHOP_DEPLOYED?"Cannot link to app in deployed version":"Open in new tab",onClick:d=>{ENV.EPICSHOP_DEPLOYED&&d.preventDefault()},children:e.jsx(D,{name:"ExternalLink"})})}):null]})}var R="Popover",[z,$t]=Ce(R,[U]),S=U(),[Xe,v]=z(R),W=t=>{const{__scopePopover:r,children:o,open:i,defaultOpen:n,onOpenChange:s,modal:a=!1}=t,c=S(r),p=l.useRef(null),[m,u]=l.useState(!1),[f,d]=Ee({prop:i,defaultProp:n??!1,onChange:s,caller:R});return e.jsx(Se,{...c,children:e.jsx(Xe,{scope:r,contentId:ye(),triggerRef:p,open:f,onOpenChange:d,onOpenToggle:l.useCallback(()=>d(x=>!x),[d]),hasCustomAnchor:m,onCustomAnchorAdd:l.useCallback(()=>u(!0),[]),onCustomAnchorRemove:l.useCallback(()=>u(!1),[]),modal:a,children:o})})};W.displayName=R;var K="PopoverAnchor",ze=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(K,o),s=S(o),{onCustomAnchorAdd:a,onCustomAnchorRemove:c}=n;return l.useEffect(()=>(a(),()=>c()),[a,c]),e.jsx(Y,{...s,...i,ref:r})});ze.displayName=K;var Q="PopoverTrigger",Z=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(Q,o),s=S(o),a=V(r,n.triggerRef),c=e.jsx(B.button,{type:"button","aria-haspopup":"dialog","aria-expanded":n.open,"aria-controls":n.contentId,"data-state":oe(n.open),...i,ref:a,onClick:w(t.onClick,n.onOpenToggle)});return n.hasCustomAnchor?c:e.jsx(Y,{asChild:!0,...s,children:c})});Z.displayName=Q;var _="PopoverPortal",[We,Ke]=z(_,{forceMount:void 0}),J=t=>{const{__scopePopover:r,forceMount:o,children:i,container:n}=t,s=v(_,r);return e.jsx(We,{scope:r,forceMount:o,children:e.jsx(G,{present:o||s.open,children:e.jsx(Le,{asChild:!0,container:n,children:i})})})};J.displayName=_;var b="PopoverContent",ee=l.forwardRef((t,r)=>{const o=Ke(b,t.__scopePopover),{forceMount:i=o.forceMount,...n}=t,s=v(b,t.__scopePopover);return e.jsx(G,{present:i||s.open,children:s.modal?e.jsx(Ze,{...n,ref:r}):e.jsx(Je,{...n,ref:r})})});ee.displayName=b;var Qe=Re("PopoverContent.RemoveScroll"),Ze=l.forwardRef((t,r)=>{const o=v(b,t.__scopePopover),i=l.useRef(null),n=V(r,i),s=l.useRef(!1);return l.useEffect(()=>{const a=i.current;if(a)return _e(a)},[]),e.jsx(Ie,{as:Qe,allowPinchZoom:!0,children:e.jsx(te,{...t,ref:n,trapFocus:o.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:w(t.onCloseAutoFocus,a=>{a.preventDefault(),s.current||o.triggerRef.current?.focus()}),onPointerDownOutside:w(t.onPointerDownOutside,a=>{const c=a.detail.originalEvent,p=c.button===0&&c.ctrlKey===!0,m=c.button===2||p;s.current=m},{checkForDefaultPrevented:!1}),onFocusOutside:w(t.onFocusOutside,a=>a.preventDefault(),{checkForDefaultPrevented:!1})})})}),Je=l.forwardRef((t,r)=>{const o=v(b,t.__scopePopover),i=l.useRef(!1),n=l.useRef(!1);return e.jsx(te,{...t,ref:r,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:s=>{t.onCloseAutoFocus?.(s),s.defaultPrevented||(i.current||o.triggerRef.current?.focus(),s.preventDefault()),i.current=!1,n.current=!1},onInteractOutside:s=>{t.onInteractOutside?.(s),s.defaultPrevented||(i.current=!0,s.detail.originalEvent.type==="pointerdown"&&(n.current=!0));const a=s.target;o.triggerRef.current?.contains(a)&&s.preventDefault(),s.detail.originalEvent.type==="focusin"&&n.current&&s.preventDefault()}})}),te=l.forwardRef((t,r)=>{const{__scopePopover:o,trapFocus:i,onOpenAutoFocus:n,onCloseAutoFocus:s,disableOutsidePointerEvents:a,onEscapeKeyDown:c,onPointerDownOutside:p,onFocusOutside:m,onInteractOutside:u,...f}=t,d=v(b,o),x=S(o);return $e(),e.jsx(Fe,{asChild:!0,loop:!0,trapped:i,onMountAutoFocus:n,onUnmountAutoFocus:s,children:e.jsx(Oe,{asChild:!0,disableOutsidePointerEvents:a,onInteractOutside:u,onEscapeKeyDown:c,onPointerDownOutside:p,onFocusOutside:m,onDismiss:()=>d.onOpenChange(!1),children:e.jsx(Ae,{"data-state":oe(d.open),role:"dialog",id:d.contentId,...x,...f,ref:r,style:{...f.style,"--radix-popover-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-popover-content-available-width":"var(--radix-popper-available-width)","--radix-popover-content-available-height":"var(--radix-popper-available-height)","--radix-popover-trigger-width":"var(--radix-popper-anchor-width)","--radix-popover-trigger-height":"var(--radix-popper-anchor-height)"}})})})}),re="PopoverClose",et=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(re,o);return e.jsx(B.button,{type:"button",...i,ref:r,onClick:w(t.onClick,()=>n.onOpenChange(!1))})});et.displayName=re;var tt="PopoverArrow",rt=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=S(o);return e.jsx(De,{...n,...i,ref:r})});rt.displayName=tt;function oe(t){return t?"open":"closed"}var ot=W,nt=Z,st=J,it=ee;function at({diffFilesPromise:t,compact:r=!1}){const o=E(),[i,n]=l.useState(!1),s=l.useRef(null);function a(){n(!1)}const c=o.playground?.appName;return e.jsx(e.Fragment,{children:e.jsxs(ot,{open:i,onOpenChange:n,children:[e.jsx(nt,{asChild:!0,children:e.jsxs("button",{className:"flex h-full items-center gap-1 border-r px-6 py-3 font-mono text-sm uppercase","aria-label":"Relevant Files",children:[e.jsx(D,{name:"Files"}),r?null:e.jsx("span",{className:"hidden xl:inline",children:"Files"})]})}),e.jsx(st,{children:e.jsx(it,{ref:s,className:"slideRightContent lg:slideUpContent invert-theme z-10 select-none rounded bg-background px-9 py-8 text-foreground",align:"start",sideOffset:5,children:e.jsxs("div",{className:"launch-editor-wrapper",children:[e.jsx("strong",{className:"inline-block px-2 pb-4 font-semibold uppercase",children:"Relevant Files"}),o.problem&&o.playground?.appName!==o.problem.name?e.jsx("div",{className:"mb-2 rounded p-1 font-mono font-medium",children:e.jsx(H,{appName:o.problem.name})}):null,e.jsx("div",{id:"files",children:e.jsx(l.Suspense,{fallback:e.jsx(k,{content:"Loading diff",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(D,{name:"Refresh",className:"h-8 w-8 animate-spin"})})}),children:e.jsx(le,{resolve:t,errorElement:e.jsx("div",{className:"text-foreground-destructive",children:"Something went wrong."}),children:p=>{if(!p)return e.jsx("p",{className:"text-foreground-destructive",children:"Unable to determine diff"});if(typeof p=="string")return e.jsx("p",{className:"text-foreground-destructive",children:p});if(!p.length)return e.jsx("p",{children:"No files changed"});const m=c||ENV.EPICSHOP_GITHUB_ROOT?{}:{title:"You must 'Set to Playground' before opening a file",className:"not-allowed"};return e.jsxs("ul",{...m,children:[p.length>1&&!ENV.EPICSHOP_DEPLOYED?e.jsx("div",{className:"mb-2 border-b border-b-gray-50 border-opacity-50 pb-2 font-sans",children:e.jsx(y,{appFile:p.map(u=>`${u.path},${u.line},1`),appName:"playground",onUpdate:a,children:e.jsx("p",{children:"Open All Files"})})}):null,p.map(u=>e.jsx("li",{"data-state":u.status,children:e.jsx(y,{appFile:`${u.path},${u.line},1`,appName:ENV.EPICSHOP_DEPLOYED?o.problem?.name??"playground":"playground",onUpdate:a,children:e.jsx("code",{children:u.path})})},u.path))]})}})})})]})})})]})})}const lt="es_split_pct";function M(t,r=50){const o=typeof t=="number"?t:Number(t);return Number.isFinite(o)?Math.min(80,Math.max(20,Math.round(o*100)/100)):r}function ne(t,r){const o=t?.exerciseStepApp.exerciseNumber.toString().padStart(2,"0")??"00",i=t?.exerciseStepApp.stepNumber.toString().padStart(2,"0")??"00",n={problem:"💪",solution:"🏁"}[t?.type??"problem"],s=t?.[t.type]?.title??"N/A";return{emoji:n,stepNumber:i,title:s,exerciseNumber:o,exerciseTitle:t?.exerciseTitle??"Unknown exercise",workshopTitle:r,type:t?.type??"problem"}}const Ft=({data:t,matches:r,params:o})=>{const i=r.find(m=>m?.id==="root")?.data;if(!t||!i)return[{title:"🦉 | Error"}];const{emoji:n,stepNumber:s,title:a,exerciseNumber:c,exerciseTitle:p}=ne(t);return Ne({title:`${n} | ${s}. ${a} | ${c}. ${p} | ${i.workshopTitle}`,description:`${o.type} step for exercise ${c}. ${p}`,ogTitle:a,ogDescription:`${p} step ${Number(s)} ${o.type}`,instructor:i.instructor,requestInfo:i.requestInfo})},Tt=ce(function({loaderData:r}){const o=l.useRef(null),i=l.useRef(null),n=l.useRef(null),[s,a]=l.useState(r.splitPercent),[c,p]=l.useState(0);l.useEffect(()=>{const d=n.current;if(!d)return;const x=new ResizeObserver(C=>{for(const g of C)p(g.contentRect.width)});return x.observe(d),p(d.getBoundingClientRect().width),()=>x.disconnect()},[]);function m(d){const x=M(d);document.cookie=`${lt}=${x}; path=/; SameSite=Lax;`}function u(d){const x=i.current;if(!x)return;const C=x.getBoundingClientRect();let g=!0;const O=Array.from(document.querySelectorAll("iframe")),se=O.map(h=>h.style.pointerEvents);O.forEach(h=>h.style.pointerEvents="none");function A(h){if(!g){P();return}const ie=(h-C.left)/C.width*100,F=M(ie);a(F),m(F)}function I(h){if(!g||h.buttons===0){P();return}A(h.clientX)}function $(h){const N=h.touches?.[0];if(!g||!N){P();return}A(N.clientX)}function P(){g&&(g=!1,O.forEach((h,N)=>h.style.pointerEvents=se[N]??""),window.removeEventListener("mousemove",I),window.removeEventListener("mouseup",P),window.removeEventListener("touchmove",$),window.removeEventListener("touchend",P),document.body.style.cursor="",document.body.style.userSelect="")}window.addEventListener("mousemove",I),window.addEventListener("mouseup",P),window.addEventListener("touchmove",$),window.addEventListener("touchend",P),document.body.style.cursor="col-resize",document.body.style.userSelect="none",A(d)}const f=ne(r);return xe({watchPaths:[`${r.exerciseStepApp.relativePath}/README.mdx`]}),e.jsx("div",{className:"flex max-w-full flex-grow flex-col",children:e.jsxs("main",{ref:i,className:"flex flex-grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row",children:[e.jsxs("div",{className:"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-[var(--split-pct)]",style:{"--split-pct":`${s}%`},ref:n,children:[e.jsx("h1",{className:"h-14 border-b pl-10 pr-5 text-sm font-medium leading-tight",children:e.jsxs("div",{className:"flex h-14 items-center justify-between gap-x-2 overflow-x-auto whitespace-nowrap py-2",children:[e.jsxs("div",{className:"flex items-center justify-start gap-x-2 uppercase",children:[e.jsxs(j,{to:be(r.exerciseStepApp.exerciseNumber),className:"hover:underline",children:[f.exerciseNumber,". ",f.exerciseTitle]}),"/",e.jsxs(j,{to:".",className:"hover:underline",children:[f.stepNumber,". ",f.title," (",f.emoji," ",f.type,")"]})]}),r.problem&&r.playground?.appName!==r.problem.name?e.jsx("div",{className:"hidden md:block",children:e.jsx(H,{appName:r.problem.name})}):null]})}),e.jsxs("article",{id:r.articleId,className:"shadow-on-scrollbox flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 scrollbar-thin scrollbar-thumb-scrollbar sm:p-10 sm:pt-8",children:[r.exerciseStepApp.instructionsCode?e.jsx(Ue,{inBrowserBrowserRef:o}):e.jsx("div",{className:"flex h-full items-center justify-center text-lg",children:e.jsx("p",{children:"No instructions yet..."})}),e.jsxs("div",{className:"mt-auto flex justify-between",children:[r.prevStepLink?e.jsxs(j,{to:r.prevStepLink.to,"aria-label":"Previous Step",prefetch:"intent",children:[e.jsx("span",{"aria-hidden":!0,children:"←"}),e.jsx("span",{className:"hidden xl:inline",children:" Previous"})]}):e.jsx("span",{}),r.nextStepLink?e.jsxs(j,{to:r.nextStepLink.to,"aria-label":"Next Step",prefetch:"intent",children:[e.jsx("span",{className:"hidden xl:inline",children:"Next "}),e.jsx("span",{"aria-hidden":!0,children:"→"})]}):e.jsx("span",{})]})]},r.articleId),e.jsx(de,{elementQuery:`#${r.articleId}`},`scroll-${r.articleId}`),r.type==="solution"?e.jsx(ge,{type:"step",exerciseNumber:r.exerciseStepApp.exerciseNumber,stepNumber:r.exerciseStepApp.stepNumber,className:"h-14 border-t px-6"}):null,e.jsxs("div",{className:"flex h-16 justify-between border-b-4 border-t lg:border-b-0",children:[e.jsx("div",{children:e.jsx("div",{className:"h-full",children:e.jsx(at,{diffFilesPromise:r.diffFiles,compact:c<640})})}),e.jsx(ve,{appName:r.exerciseStepApp.name,relativePath:r.exerciseStepApp.relativePath,compact:c<720}),e.jsx(me,{prev:r.prevStepLink?{to:r.prevStepLink.to,"aria-label":"Previous Step"}:null,next:r.nextStepLink?{to:r.nextStepLink.to,"aria-label":"Next Step"}:null})]})]}),e.jsx("div",{role:"separator","aria-orientation":"vertical",title:"Drag to resize",className:"hidden w-1 cursor-col-resize bg-border hover:bg-accent lg:block",onMouseDown:d=>u(d.clientX),onDoubleClick:()=>{a(50),m(50)},onTouchStart:d=>{const x=d.touches?.[0];x&&u(x.clientX)}}),e.jsx("div",{className:"flex min-w-0 flex-1",children:e.jsx(ue,{})})]})})}),Mt=pe(function(){return e.jsx(fe,{statusHandlers:{404:()=>e.jsx("p",{children:"Sorry, we couldn't find an app here."}),503:()=>e.jsxs("div",{children:[e.jsx("h1",{children:"Service Unavailable"}),e.jsx("p",{children:"Sorry, we're having a temporary problem. Please try again later."}),e.jsx("button",{onClick:()=>window.location.reload(),children:"Refresh"})]})}})});export{Mt as ErrorBoundary,Tt as default,Ft as meta};
2
- //# sourceMappingURL=_layout-CJr4y8eX.js.map
1
+ import{c as E,l as ae,L as j,A as le,w as ce,a as pe,O as ue}from"./chunk-EF7DTUVF-ByhKO_Pl.js";import{j as e}from"./jsx-runtime-EKYJJIwR.js";import{E as de}from"./index-CcWv7OrP.js";import{r as l}from"./index-DatCARk7.js";import{G as fe}from"./error-boundary-CEFnSCa2.js";import{N as me}from"./nav-chevrons-BOkHwadX.js";import{u as xe}from"./revalidation-ws-BMyn5NqG.js";import{M as he,L as y,E as ve}from"./mdx-BDFRig3X.js";import{P as ge}from"./progress-CkGdQlTp.js";import{S as H}from"./set-playground-CCf6DmQr.js";import{a as Pe,c as T,I as D,i as je,b as be}from"./misc-DjWUkK1U.js";import{g as Ne}from"./seo-t5J-DRxw.js";import{E as we}from"./epic-video-BODCgn-e.js";import{S as k,j as U,u as Ee,R as Se,d as Ce,e as ye,h as V,P as B,f as w,A as Y,g as G,k as Re,D as Oe,C as Ae,l as De}from"./tooltip-JIUlMcsz.js";import{a as ke}from"./index-MRSoBlHC.js";import{P as Le,h as _e,R as Ie,u as $e,F as Fe}from"./index-Be-5FhjB.js";import"./preload-helper-BXl3LOEh.js";import"./clsx-B-dksMZM.js";import"./index-DA15my8N.js";import"./index-Bn6wT_6F.js";import"./progress-bar-C8ErpL4p.js";import"./pe-D3WpHDnY.js";import"./index-2USrBHAC.js";import"./online-CxLmaFqb.js";import"./loading-DJq7N2Fo.js";import"./user-CJVisi_Z.js";import"./workshop-config-CcvXvaNp.js";const q=l.createContext(null);function Te(){const t=l.useContext(q);if(!t)throw new Error("useStepContext must be used within a StepContext.Provider");return t}function Me({children:t,inBrowserBrowserRef:r}){return e.jsx(q.Provider,{value:{inBrowserBrowserRef:r},children:t})}const He={DiffLink:L,PrevDiffLink:Be,NextDiffLink:Ve,InlineFile:Ye,LinkToApp:qe};function Ue({inBrowserBrowserRef:t}){const r=E();return r.exerciseStepApp.instructionsCode?e.jsx(Me,{inBrowserBrowserRef:t,children:e.jsx(we,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(he,{code:r.exerciseStepApp.instructionsCode,components:He})})})}):null}function X(t,r,o){const i=new URLSearchParams(t);return o===null?i.delete(r):i.set(r,o),i}function Ve({app:t=0,fullPage:r=!1,children:o}){return e.jsx(L,{app1:t,app2:t+1,fullPage:r,children:o})}function Be({app:t=-1,fullPage:r=!1,children:o}){return e.jsx(L,{app1:t,app2:t+1,fullPage:r,children:o})}function L({app1:t=0,app2:r=1,children:o,fullPage:i=!1,to:n}){const s=E();if(!n&&!t&&!r)return e.jsx("callout-danger",{className:"notification",children:e.jsx("div",{className:"title",children:"DiffLink Error: invalid input"})});function a(u){if(typeof u=="number"){const f=s.exerciseIndex+u;return s.allApps[f]?.name}if(!u)return null;for(const{name:f,stepName:d}of s.allApps)if(u===f||u===d)return f;return null}if(n){const u=new URLSearchParams(n);t=u.get("app1"),r=u.get("app2")}const c=a(t),p=a(r);if(!c||!p)return e.jsxs("callout-danger",{className:"notification",children:[e.jsx("div",{className:"title",children:"DiffLink Error: invalid input"}),!c&&e.jsxs("div",{children:['app1: "',t,'" is not a valid app name']}),!p&&e.jsxs("div",{children:['app2: "',r,'" is not a valid app name']})]});n||(n=`app1=${c}&app2=${p}`);const m=i?`/diff?${n}`:`?${decodeURIComponent(X(new URLSearchParams,"preview",`diff&${n}`).toString())}`;return o||(o=e.jsxs("span",{children:["Go to Diff ",i?"":"Preview"," from: ",e.jsx("code",{children:c})," to:"," ",e.jsx("code",{children:p})]})),e.jsx(j,{to:m,children:o})}function Ye({file:t,type:r="playground",children:o=e.jsx("code",{children:t}),...i}){const n=E(),s=n[r]||n[n.type],a=e.jsxs("div",{className:"launch-editor-button-wrapper flex underline underline-offset-4",children:[o," ",e.jsx("svg",{height:24,width:24,children:e.jsx("use",{href:`${je}#Keyboard`})})]});return ENV.EPICSHOP_DEPLOYED&&s?e.jsx("div",{className:"inline-block grow",children:e.jsx(y,{appFile:t,appName:s.name,...i,children:a})}):s?e.jsx("div",{className:"inline-block grow",children:e.jsx(y,{appFile:t,appName:s.name,...i,children:a})}):r==="playground"?e.jsx(k,{content:"You must 'Set to Playground' before opening a file",children:e.jsx("div",{className:"inline-block grow cursor-not-allowed",children:a})}):e.jsx(e.Fragment,{children:"children"})}function Ge(t){return t==="problem"?"problem":t==="solution"?"solution":"playground"}function qe({to:t,children:r=e.jsx("code",{children:t.toString()}),...o}){const[i]=ae(),n=`?${X(i,"pathname",t.toString()).toString()}`,s=E(),a=Ge(i.get("preview")),c=ke(),p=s[a],m=p?.dev.type==="script"?Pe({domain:c.domain,port:p.dev.portNumber}):s.playground?.dev.type==="browser"?s.playground.dev.pathname:null,{inBrowserBrowserRef:u}=Te(),f=m?m.slice(0,-1)+t.toString():null;return e.jsxs("div",{className:"inline-flex items-center justify-between gap-1",children:[e.jsx(j,{to:n,...o,className:T(o.className,{"cursor-not-allowed":ENV.EPICSHOP_DEPLOYED}),title:ENV.EPICSHOP_DEPLOYED?"Cannot link to app in deployed version":void 0,onClick:d=>{ENV.EPICSHOP_DEPLOYED&&d.preventDefault(),o.onClick?.(d),u.current?.handleExtrnalNavigation(t.toString())},children:r}),f?e.jsx(k,{content:"Open in new tab",children:e.jsx("a",{href:f,target:"_blank",rel:"noreferrer",className:T("flex aspect-square items-center justify-center",{"cursor-not-allowed":ENV.EPICSHOP_DEPLOYED}),title:ENV.EPICSHOP_DEPLOYED?"Cannot link to app in deployed version":"Open in new tab",onClick:d=>{ENV.EPICSHOP_DEPLOYED&&d.preventDefault()},children:e.jsx(D,{name:"ExternalLink"})})}):null]})}var R="Popover",[z,$t]=Ce(R,[U]),S=U(),[Xe,v]=z(R),W=t=>{const{__scopePopover:r,children:o,open:i,defaultOpen:n,onOpenChange:s,modal:a=!1}=t,c=S(r),p=l.useRef(null),[m,u]=l.useState(!1),[f,d]=Ee({prop:i,defaultProp:n??!1,onChange:s,caller:R});return e.jsx(Se,{...c,children:e.jsx(Xe,{scope:r,contentId:ye(),triggerRef:p,open:f,onOpenChange:d,onOpenToggle:l.useCallback(()=>d(x=>!x),[d]),hasCustomAnchor:m,onCustomAnchorAdd:l.useCallback(()=>u(!0),[]),onCustomAnchorRemove:l.useCallback(()=>u(!1),[]),modal:a,children:o})})};W.displayName=R;var K="PopoverAnchor",ze=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(K,o),s=S(o),{onCustomAnchorAdd:a,onCustomAnchorRemove:c}=n;return l.useEffect(()=>(a(),()=>c()),[a,c]),e.jsx(Y,{...s,...i,ref:r})});ze.displayName=K;var Q="PopoverTrigger",Z=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(Q,o),s=S(o),a=V(r,n.triggerRef),c=e.jsx(B.button,{type:"button","aria-haspopup":"dialog","aria-expanded":n.open,"aria-controls":n.contentId,"data-state":oe(n.open),...i,ref:a,onClick:w(t.onClick,n.onOpenToggle)});return n.hasCustomAnchor?c:e.jsx(Y,{asChild:!0,...s,children:c})});Z.displayName=Q;var _="PopoverPortal",[We,Ke]=z(_,{forceMount:void 0}),J=t=>{const{__scopePopover:r,forceMount:o,children:i,container:n}=t,s=v(_,r);return e.jsx(We,{scope:r,forceMount:o,children:e.jsx(G,{present:o||s.open,children:e.jsx(Le,{asChild:!0,container:n,children:i})})})};J.displayName=_;var b="PopoverContent",ee=l.forwardRef((t,r)=>{const o=Ke(b,t.__scopePopover),{forceMount:i=o.forceMount,...n}=t,s=v(b,t.__scopePopover);return e.jsx(G,{present:i||s.open,children:s.modal?e.jsx(Ze,{...n,ref:r}):e.jsx(Je,{...n,ref:r})})});ee.displayName=b;var Qe=Re("PopoverContent.RemoveScroll"),Ze=l.forwardRef((t,r)=>{const o=v(b,t.__scopePopover),i=l.useRef(null),n=V(r,i),s=l.useRef(!1);return l.useEffect(()=>{const a=i.current;if(a)return _e(a)},[]),e.jsx(Ie,{as:Qe,allowPinchZoom:!0,children:e.jsx(te,{...t,ref:n,trapFocus:o.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:w(t.onCloseAutoFocus,a=>{a.preventDefault(),s.current||o.triggerRef.current?.focus()}),onPointerDownOutside:w(t.onPointerDownOutside,a=>{const c=a.detail.originalEvent,p=c.button===0&&c.ctrlKey===!0,m=c.button===2||p;s.current=m},{checkForDefaultPrevented:!1}),onFocusOutside:w(t.onFocusOutside,a=>a.preventDefault(),{checkForDefaultPrevented:!1})})})}),Je=l.forwardRef((t,r)=>{const o=v(b,t.__scopePopover),i=l.useRef(!1),n=l.useRef(!1);return e.jsx(te,{...t,ref:r,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:s=>{t.onCloseAutoFocus?.(s),s.defaultPrevented||(i.current||o.triggerRef.current?.focus(),s.preventDefault()),i.current=!1,n.current=!1},onInteractOutside:s=>{t.onInteractOutside?.(s),s.defaultPrevented||(i.current=!0,s.detail.originalEvent.type==="pointerdown"&&(n.current=!0));const a=s.target;o.triggerRef.current?.contains(a)&&s.preventDefault(),s.detail.originalEvent.type==="focusin"&&n.current&&s.preventDefault()}})}),te=l.forwardRef((t,r)=>{const{__scopePopover:o,trapFocus:i,onOpenAutoFocus:n,onCloseAutoFocus:s,disableOutsidePointerEvents:a,onEscapeKeyDown:c,onPointerDownOutside:p,onFocusOutside:m,onInteractOutside:u,...f}=t,d=v(b,o),x=S(o);return $e(),e.jsx(Fe,{asChild:!0,loop:!0,trapped:i,onMountAutoFocus:n,onUnmountAutoFocus:s,children:e.jsx(Oe,{asChild:!0,disableOutsidePointerEvents:a,onInteractOutside:u,onEscapeKeyDown:c,onPointerDownOutside:p,onFocusOutside:m,onDismiss:()=>d.onOpenChange(!1),children:e.jsx(Ae,{"data-state":oe(d.open),role:"dialog",id:d.contentId,...x,...f,ref:r,style:{...f.style,"--radix-popover-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-popover-content-available-width":"var(--radix-popper-available-width)","--radix-popover-content-available-height":"var(--radix-popper-available-height)","--radix-popover-trigger-width":"var(--radix-popper-anchor-width)","--radix-popover-trigger-height":"var(--radix-popper-anchor-height)"}})})})}),re="PopoverClose",et=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(re,o);return e.jsx(B.button,{type:"button",...i,ref:r,onClick:w(t.onClick,()=>n.onOpenChange(!1))})});et.displayName=re;var tt="PopoverArrow",rt=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=S(o);return e.jsx(De,{...n,...i,ref:r})});rt.displayName=tt;function oe(t){return t?"open":"closed"}var ot=W,nt=Z,st=J,it=ee;function at({diffFilesPromise:t,compact:r=!1}){const o=E(),[i,n]=l.useState(!1),s=l.useRef(null);function a(){n(!1)}const c=o.playground?.appName;return e.jsx(e.Fragment,{children:e.jsxs(ot,{open:i,onOpenChange:n,children:[e.jsx(nt,{asChild:!0,children:e.jsxs("button",{className:"flex h-full items-center gap-1 border-r px-6 py-3 font-mono text-sm uppercase","aria-label":"Relevant Files",children:[e.jsx(D,{name:"Files"}),r?null:e.jsx("span",{className:"hidden xl:inline",children:"Files"})]})}),e.jsx(st,{children:e.jsx(it,{ref:s,className:"slideRightContent lg:slideUpContent invert-theme z-10 select-none rounded bg-background px-9 py-8 text-foreground",align:"start",sideOffset:5,children:e.jsxs("div",{className:"launch-editor-wrapper",children:[e.jsx("strong",{className:"inline-block px-2 pb-4 font-semibold uppercase",children:"Relevant Files"}),o.problem&&o.playground?.appName!==o.problem.name?e.jsx("div",{className:"mb-2 rounded p-1 font-mono font-medium",children:e.jsx(H,{appName:o.problem.name})}):null,e.jsx("div",{id:"files",children:e.jsx(l.Suspense,{fallback:e.jsx(k,{content:"Loading diff",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(D,{name:"Refresh",className:"h-8 w-8 animate-spin"})})}),children:e.jsx(le,{resolve:t,errorElement:e.jsx("div",{className:"text-foreground-destructive",children:"Something went wrong."}),children:p=>{if(!p)return e.jsx("p",{className:"text-foreground-destructive",children:"Unable to determine diff"});if(typeof p=="string")return e.jsx("p",{className:"text-foreground-destructive",children:p});if(!p.length)return e.jsx("p",{children:"No files changed"});const m=c||ENV.EPICSHOP_GITHUB_ROOT?{}:{title:"You must 'Set to Playground' before opening a file",className:"not-allowed"};return e.jsxs("ul",{...m,children:[p.length>1&&!ENV.EPICSHOP_DEPLOYED?e.jsx("div",{className:"mb-2 border-b border-b-gray-50 border-opacity-50 pb-2 font-sans",children:e.jsx(y,{appFile:p.map(u=>`${u.path},${u.line},1`),appName:"playground",onUpdate:a,children:e.jsx("p",{children:"Open All Files"})})}):null,p.map(u=>e.jsx("li",{"data-state":u.status,children:e.jsx(y,{appFile:`${u.path},${u.line},1`,appName:ENV.EPICSHOP_DEPLOYED?o.problem?.name??"playground":"playground",onUpdate:a,children:e.jsx("code",{children:u.path})})},u.path))]})}})})})]})})})]})})}const lt="es_split_pct";function M(t,r=50){const o=typeof t=="number"?t:Number(t);return Number.isFinite(o)?Math.min(80,Math.max(20,Math.round(o*100)/100)):r}function ne(t,r){const o=t?.exerciseStepApp.exerciseNumber.toString().padStart(2,"0")??"00",i=t?.exerciseStepApp.stepNumber.toString().padStart(2,"0")??"00",n={problem:"💪",solution:"🏁"}[t?.type??"problem"],s=t?.[t.type]?.title??"N/A";return{emoji:n,stepNumber:i,title:s,exerciseNumber:o,exerciseTitle:t?.exerciseTitle??"Unknown exercise",workshopTitle:r,type:t?.type??"problem"}}const Ft=({data:t,matches:r,params:o})=>{const i=r.find(m=>m?.id==="root")?.data;if(!t||!i)return[{title:"🦉 | Error"}];const{emoji:n,stepNumber:s,title:a,exerciseNumber:c,exerciseTitle:p}=ne(t);return Ne({title:`${n} | ${s}. ${a} | ${c}. ${p} | ${i.workshopTitle}`,description:`${o.type} step for exercise ${c}. ${p}`,ogTitle:a,ogDescription:`${p} step ${Number(s)} ${o.type}`,instructor:i.instructor,requestInfo:i.requestInfo})},Tt=ce(function({loaderData:r}){const o=l.useRef(null),i=l.useRef(null),n=l.useRef(null),[s,a]=l.useState(r.splitPercent),[c,p]=l.useState(0);l.useEffect(()=>{const d=n.current;if(!d)return;const x=new ResizeObserver(C=>{for(const g of C)p(g.contentRect.width)});return x.observe(d),p(d.getBoundingClientRect().width),()=>x.disconnect()},[]);function m(d){const x=M(d);document.cookie=`${lt}=${x}; path=/; SameSite=Lax;`}function u(d){const x=i.current;if(!x)return;const C=x.getBoundingClientRect();let g=!0;const O=Array.from(document.querySelectorAll("iframe")),se=O.map(h=>h.style.pointerEvents);O.forEach(h=>h.style.pointerEvents="none");function A(h){if(!g){P();return}const ie=(h-C.left)/C.width*100,F=M(ie);a(F),m(F)}function I(h){if(!g||h.buttons===0){P();return}A(h.clientX)}function $(h){const N=h.touches?.[0];if(!g||!N){P();return}A(N.clientX)}function P(){g&&(g=!1,O.forEach((h,N)=>h.style.pointerEvents=se[N]??""),window.removeEventListener("mousemove",I),window.removeEventListener("mouseup",P),window.removeEventListener("touchmove",$),window.removeEventListener("touchend",P),document.body.style.cursor="",document.body.style.userSelect="")}window.addEventListener("mousemove",I),window.addEventListener("mouseup",P),window.addEventListener("touchmove",$),window.addEventListener("touchend",P),document.body.style.cursor="col-resize",document.body.style.userSelect="none",A(d)}const f=ne(r);return xe({watchPaths:[`${r.exerciseStepApp.relativePath}/README.mdx`]}),e.jsx("div",{className:"flex max-w-full flex-grow flex-col",children:e.jsxs("main",{ref:i,className:"flex flex-grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row",children:[e.jsxs("div",{className:"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-[var(--split-pct)]",style:{"--split-pct":`${s}%`},ref:n,children:[e.jsx("h1",{className:"h-14 border-b pl-10 pr-5 text-sm font-medium leading-tight",children:e.jsxs("div",{className:"flex h-14 items-center justify-between gap-x-2 overflow-x-auto whitespace-nowrap py-2",children:[e.jsxs("div",{className:"flex items-center justify-start gap-x-2 uppercase",children:[e.jsxs(j,{to:be(r.exerciseStepApp.exerciseNumber),className:"hover:underline",children:[f.exerciseNumber,". ",f.exerciseTitle]}),"/",e.jsxs(j,{to:".",className:"hover:underline",children:[f.stepNumber,". ",f.title," (",f.emoji," ",f.type,")"]})]}),r.problem&&r.playground?.appName!==r.problem.name?e.jsx("div",{className:"hidden md:block",children:e.jsx(H,{appName:r.problem.name})}):null]})}),e.jsxs("article",{id:r.articleId,className:"shadow-on-scrollbox flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 scrollbar-thin scrollbar-thumb-scrollbar sm:p-10 sm:pt-8",children:[r.exerciseStepApp.instructionsCode?e.jsx(Ue,{inBrowserBrowserRef:o}):e.jsx("div",{className:"flex h-full items-center justify-center text-lg",children:e.jsx("p",{children:"No instructions yet..."})}),e.jsxs("div",{className:"mt-auto flex justify-between",children:[r.prevStepLink?e.jsxs(j,{to:r.prevStepLink.to,"aria-label":"Previous Step",prefetch:"intent",children:[e.jsx("span",{"aria-hidden":!0,children:"←"}),e.jsx("span",{className:"hidden xl:inline",children:" Previous"})]}):e.jsx("span",{}),r.nextStepLink?e.jsxs(j,{to:r.nextStepLink.to,"aria-label":"Next Step",prefetch:"intent",children:[e.jsx("span",{className:"hidden xl:inline",children:"Next "}),e.jsx("span",{"aria-hidden":!0,children:"→"})]}):e.jsx("span",{})]})]},r.articleId),e.jsx(de,{elementQuery:`#${r.articleId}`},`scroll-${r.articleId}`),r.type==="solution"?e.jsx(ge,{type:"step",exerciseNumber:r.exerciseStepApp.exerciseNumber,stepNumber:r.exerciseStepApp.stepNumber,className:"h-14 border-t px-6"}):null,e.jsxs("div",{className:"flex h-16 justify-between border-b-4 border-t lg:border-b-0",children:[e.jsx("div",{children:e.jsx("div",{className:"h-full",children:e.jsx(at,{diffFilesPromise:r.diffFiles,compact:c<640})})}),e.jsx(ve,{appName:r.exerciseStepApp.name,relativePath:r.exerciseStepApp.relativePath,compact:c<720}),e.jsx(me,{prev:r.prevStepLink?{to:r.prevStepLink.to,"aria-label":"Previous Step"}:null,next:r.nextStepLink?{to:r.nextStepLink.to,"aria-label":"Next Step"}:null})]})]}),e.jsx("div",{role:"separator","aria-orientation":"vertical",title:"Drag to resize",className:"hidden w-1 cursor-col-resize bg-border hover:bg-accent lg:block",onMouseDown:d=>u(d.clientX),onDoubleClick:()=>{a(50),m(50)},onTouchStart:d=>{const x=d.touches?.[0];x&&u(x.clientX)}}),e.jsx("div",{className:"flex min-w-0 flex-1",children:e.jsx(ue,{})})]})})}),Mt=pe(function(){return e.jsx(fe,{statusHandlers:{404:()=>e.jsx("p",{children:"Sorry, we couldn't find an app here."}),503:()=>e.jsxs("div",{children:[e.jsx("h1",{children:"Service Unavailable"}),e.jsx("p",{children:"Sorry, we're having a temporary problem. Please try again later."}),e.jsx("button",{onClick:()=>window.location.reload(),children:"Refresh"})]})}})});export{Mt as ErrorBoundary,Tt as default,Ft as meta};
2
+ //# sourceMappingURL=_layout-CcWrk4kg.js.map