@epic-web/workshop-app 5.4.1 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/build/client/assets/{_-BrkpfnBb.js → _-hAKYb2AG.js} +2 -2
  2. package/build/client/assets/{_-BrkpfnBb.js.map → _-hAKYb2AG.js.map} +1 -1
  3. package/build/client/assets/_exerciseNumber-PTdG9GGB.js +2 -0
  4. package/build/client/assets/_exerciseNumber-PTdG9GGB.js.map +1 -0
  5. package/build/client/assets/{_exerciseNumber_._stepNumber-BIMJh_sg.js → _exerciseNumber_._stepNumber-03erOIGo.js} +2 -2
  6. package/build/client/assets/{_exerciseNumber_._stepNumber-BIMJh_sg.js.map → _exerciseNumber_._stepNumber-03erOIGo.js.map} +1 -1
  7. package/build/client/assets/_exerciseNumber_.finished-DQg4F1NL.js +2 -0
  8. package/build/client/assets/_exerciseNumber_.finished-DQg4F1NL.js.map +1 -0
  9. package/build/client/assets/{_layout-88n0To1b.js → _layout-B4JGpA3A.js} +2 -2
  10. package/build/client/assets/{_layout-88n0To1b.js.map → _layout-B4JGpA3A.js.map} +1 -1
  11. package/build/client/assets/{_layout-Dfmv2zcn.js → _layout-BJbMl6SJ.js} +2 -2
  12. package/build/client/assets/{_layout-Dfmv2zcn.js.map → _layout-BJbMl6SJ.js.map} +1 -1
  13. package/build/client/assets/_layout-Bu0lel3p.js +6 -0
  14. package/build/client/assets/_layout-Bu0lel3p.js.map +1 -0
  15. package/build/client/assets/_layout-DHoH74NH.js +2 -0
  16. package/build/client/assets/_layout-DHoH74NH.js.map +1 -0
  17. package/build/client/assets/{accordion-D9-D-n9p.js → accordion-DLg7gJkp.js} +2 -2
  18. package/build/client/assets/{accordion-D9-D-n9p.js.map → accordion-DLg7gJkp.js.map} +1 -1
  19. package/build/client/assets/account-DLDPrc9J.js +2 -0
  20. package/build/client/assets/account-DLDPrc9J.js.map +1 -0
  21. package/build/client/assets/app-DJDjmdlu.js +2 -0
  22. package/build/client/assets/{app-DgTXXO8s.js.map → app-DJDjmdlu.js.map} +1 -1
  23. package/build/client/assets/{button-_qPvcoqR.js → button-39zQyNX6.js} +2 -2
  24. package/build/client/assets/{button-_qPvcoqR.js.map → button-39zQyNX6.js.map} +1 -1
  25. package/build/client/assets/{components-Be92gVxW.js → components-DUNtf72c.js} +2 -2
  26. package/build/client/assets/{components-Be92gVxW.js.map → components-DUNtf72c.js.map} +1 -1
  27. package/build/client/assets/diff-B3oaU_KB.js +2 -0
  28. package/build/client/assets/{diff-BhRAIPKc.js.map → diff-B3oaU_KB.js.map} +1 -1
  29. package/build/client/assets/{diff-8nlDkmpc.js → diff-BNCREJvf.js} +2 -2
  30. package/build/client/assets/{diff-8nlDkmpc.js.map → diff-BNCREJvf.js.map} +1 -1
  31. package/build/client/assets/{discord-BUWZUTEC.js → discord-CEOqKs_c.js} +2 -2
  32. package/build/client/assets/{discord-BUWZUTEC.js.map → discord-CEOqKs_c.js.map} +1 -1
  33. package/build/client/assets/discord-CpIgvYus.js +2 -0
  34. package/build/client/assets/discord-CpIgvYus.js.map +1 -0
  35. package/build/client/assets/{entry.client-DqIWuxf8.js → entry.client-CrlHhRMR.js} +2 -2
  36. package/build/client/assets/{entry.client-DqIWuxf8.js.map → entry.client-CrlHhRMR.js.map} +1 -1
  37. package/build/client/assets/epic-video-D8ex9vao.js +2 -0
  38. package/build/client/assets/epic-video-D8ex9vao.js.map +1 -0
  39. package/build/client/assets/error-boundary-3zItlMUO.js +2 -0
  40. package/build/client/assets/{error-boundary-BZA-ffa8.js.map → error-boundary-3zItlMUO.js.map} +1 -1
  41. package/build/client/assets/finished-rUzUjnEm.js +2 -0
  42. package/build/client/assets/finished-rUzUjnEm.js.map +1 -0
  43. package/build/client/assets/index-BajUQsFT.js +3053 -0
  44. package/build/client/assets/index-BajUQsFT.js.map +1 -0
  45. package/build/client/assets/{index-BCxBKsqT.js → index-CLNXC84j.js} +2 -2
  46. package/build/client/assets/{index-BCxBKsqT.js.map → index-CLNXC84j.js.map} +1 -1
  47. package/build/client/assets/{index-BCTr8uu6.js → index-CV3nxGFp.js} +2 -2
  48. package/build/client/assets/{index-BCTr8uu6.js.map → index-CV3nxGFp.js.map} +1 -1
  49. package/build/client/assets/{index-BFGhCX_U.js → index-C_B1-9rF.js} +2 -2
  50. package/build/client/assets/{index-BFGhCX_U.js.map → index-C_B1-9rF.js.map} +1 -1
  51. package/build/client/assets/{index-pkiQppkK.js → index-DDqzbGM2.js} +2 -2
  52. package/build/client/assets/{index-pkiQppkK.js.map → index-DDqzbGM2.js.map} +1 -1
  53. package/build/client/assets/index-DE-jwnOP.js +2 -0
  54. package/build/client/assets/index-DE-jwnOP.js.map +1 -0
  55. package/build/client/assets/{index-DZDhtMuq.js → index-DFqQCjCw.js} +2 -2
  56. package/build/client/assets/{index-DZDhtMuq.js.map → index-DFqQCjCw.js.map} +1 -1
  57. package/build/client/assets/{index-Bdg3v8tC.js → index-DH1w3QmP.js} +2 -2
  58. package/build/client/assets/{index-Bdg3v8tC.js.map → index-DH1w3QmP.js.map} +1 -1
  59. package/build/client/assets/{index-C9Hx0Dey.js → index-LjRZeU7x.js} +2 -2
  60. package/build/client/assets/{index-C9Hx0Dey.js.map → index-LjRZeU7x.js.map} +1 -1
  61. package/build/client/assets/index-mivnjq36.js +2 -0
  62. package/build/client/assets/index-mivnjq36.js.map +1 -0
  63. package/build/client/assets/{loading-XhMtj4mp.js → loading-DW_I206H.js} +2 -2
  64. package/build/client/assets/{loading-XhMtj4mp.js.map → loading-DW_I206H.js.map} +1 -1
  65. package/build/client/assets/{login-C1oOgi98.js → login-CdNej0Z7.js} +2 -2
  66. package/build/client/assets/{login-C1oOgi98.js.map → login-CdNej0Z7.js.map} +1 -1
  67. package/build/client/assets/manifest-62ea49c4.js +1 -0
  68. package/build/client/assets/{mdx-CEjzXoEx.js → mdx-C9dqA6IZ.js} +2 -2
  69. package/build/client/assets/{mdx-CEjzXoEx.js.map → mdx-C9dqA6IZ.js.map} +1 -1
  70. package/build/client/assets/{misc-DUy_whwE.js → misc-DIdEn_jt.js} +2 -2
  71. package/build/client/assets/{misc-DUy_whwE.js.map → misc-DIdEn_jt.js.map} +1 -1
  72. package/build/client/assets/{nav-chevrons-DnR25VLp.js → nav-chevrons-B3SvZV8B.js} +2 -2
  73. package/build/client/assets/{nav-chevrons-DnR25VLp.js.map → nav-chevrons-B3SvZV8B.js.map} +1 -1
  74. package/build/client/assets/onboarding-CC9zz4rl.js +2 -0
  75. package/build/client/assets/onboarding-CC9zz4rl.js.map +1 -0
  76. package/build/client/assets/{pe-ChIwTk8v.js → pe-D5h19vSo.js} +2 -2
  77. package/build/client/assets/{pe-ChIwTk8v.js.map → pe-D5h19vSo.js.map} +1 -1
  78. package/build/client/assets/presence-D1DPz__2.js +28 -0
  79. package/build/client/assets/presence-D1DPz__2.js.map +1 -0
  80. package/build/client/assets/{preview-DaZd0wMb.js → preview-BEtmdi0E.js} +2 -2
  81. package/build/client/assets/{preview-DaZd0wMb.js.map → preview-BEtmdi0E.js.map} +1 -1
  82. package/build/client/assets/{product-DIAmCwmZ.js → product-CYOFfeJM.js} +2 -2
  83. package/build/client/assets/{product-DIAmCwmZ.js.map → product-CYOFfeJM.js.map} +1 -1
  84. package/build/client/assets/{progress-DQt_Bn9o.js → progress-D6SP0Gec.js} +2 -2
  85. package/build/client/assets/{progress-DQt_Bn9o.js.map → progress-D6SP0Gec.js.map} +1 -1
  86. package/build/client/assets/{progress-bar-BaTU3Yx_.js → progress-bar-CBDBzRQ2.js} +2 -2
  87. package/build/client/assets/{progress-bar-BaTU3Yx_.js.map → progress-bar-CBDBzRQ2.js.map} +1 -1
  88. package/build/client/assets/{request-info-ByUEfOil.js → request-info-vBkaf3Rk.js} +2 -2
  89. package/build/client/assets/{request-info-ByUEfOil.js.map → request-info-vBkaf3Rk.js.map} +1 -1
  90. package/build/client/assets/{revalidation-ws-dUa9CAqr.js → revalidation-ws-DK5QOPlL.js} +2 -2
  91. package/build/client/assets/{revalidation-ws-dUa9CAqr.js.map → revalidation-ws-DK5QOPlL.js.map} +1 -1
  92. package/build/client/assets/{root-a3d3Qwip.js → root-Bg-hxaOK.js} +2 -2
  93. package/build/client/assets/{root-a3d3Qwip.js.map → root-Bg-hxaOK.js.map} +1 -1
  94. package/build/client/assets/{set-playground-CBHBA46B.js → set-playground-CMoUFgkO.js} +2 -2
  95. package/build/client/assets/{set-playground-CBHBA46B.js.map → set-playground-CMoUFgkO.js.map} +1 -1
  96. package/build/client/assets/{support-CIz02V_r.js → support-CPzYlWkd.js} +2 -2
  97. package/build/client/assets/{support-CIz02V_r.js.map → support-CPzYlWkd.js.map} +1 -1
  98. package/build/client/assets/test-C8wkLh9a.js +2 -0
  99. package/build/client/assets/{test-DoKJvNug.js.map → test-C8wkLh9a.js.map} +1 -1
  100. package/build/client/assets/{tests-DbuyD2cI.js → tests-CiM4RPOf.js} +2 -2
  101. package/build/client/assets/tests-CiM4RPOf.js.map +1 -0
  102. package/build/client/assets/{tooltip-DO9uwurQ.js → tooltip-BoVikCa-.js} +2 -2
  103. package/build/client/assets/{tooltip-DO9uwurQ.js.map → tooltip-BoVikCa-.js.map} +1 -1
  104. package/build/client/assets/{use-event-source-x59d4R2Z.js → use-event-source-M87p8Tme.js} +2 -2
  105. package/build/client/assets/{use-event-source-x59d4R2Z.js.map → use-event-source-M87p8Tme.js.map} +1 -1
  106. package/build/client/assets/{user-Bv6wYhQP.js → user-CbbIYEs8.js} +2 -2
  107. package/build/client/assets/{user-Bv6wYhQP.js.map → user-CbbIYEs8.js.map} +1 -1
  108. package/build/client/assets/{version-lxUUxt3s.js → version-CIF3cX3N.js} +2 -2
  109. package/build/client/assets/{version-lxUUxt3s.js.map → version-CIF3cX3N.js.map} +1 -1
  110. package/build/client/assets/{workshop-config-WVltG_BV.js → workshop-config-C5sYl312.js} +2 -2
  111. package/build/client/assets/{workshop-config-WVltG_BV.js.map → workshop-config-C5sYl312.js.map} +1 -1
  112. package/build/server/index.js +456 -782
  113. package/build/server/index.js.map +1 -1
  114. package/package.json +8 -8
  115. package/build/client/assets/_exerciseNumber-DCSM0NCG.js +0 -2
  116. package/build/client/assets/_exerciseNumber-DCSM0NCG.js.map +0 -1
  117. package/build/client/assets/_exerciseNumber_.finished-nbpk1ToO.js +0 -2
  118. package/build/client/assets/_exerciseNumber_.finished-nbpk1ToO.js.map +0 -1
  119. package/build/client/assets/_layout-Cbz7Qt-S.js +0 -6
  120. package/build/client/assets/_layout-Cbz7Qt-S.js.map +0 -1
  121. package/build/client/assets/_layout-DTAM9xh5.js +0 -2
  122. package/build/client/assets/_layout-DTAM9xh5.js.map +0 -1
  123. package/build/client/assets/account-C4Piztoz.js +0 -2
  124. package/build/client/assets/account-C4Piztoz.js.map +0 -1
  125. package/build/client/assets/app-DgTXXO8s.js +0 -2
  126. package/build/client/assets/diff-BhRAIPKc.js +0 -2
  127. package/build/client/assets/discord-Bdnx7fu-.js +0 -2
  128. package/build/client/assets/discord-Bdnx7fu-.js.map +0 -1
  129. package/build/client/assets/epic-video-Bp4BOD2R.js +0 -3053
  130. package/build/client/assets/epic-video-Bp4BOD2R.js.map +0 -1
  131. package/build/client/assets/error-boundary-BZA-ffa8.js +0 -2
  132. package/build/client/assets/finished-C0cpfAFL.js +0 -2
  133. package/build/client/assets/finished-C0cpfAFL.js.map +0 -1
  134. package/build/client/assets/index-Bi1TbRTj.js +0 -2
  135. package/build/client/assets/index-Bi1TbRTj.js.map +0 -1
  136. package/build/client/assets/index-Ca4vBON4.js +0 -2
  137. package/build/client/assets/index-Ca4vBON4.js.map +0 -1
  138. package/build/client/assets/manifest-e5b2a6e1.js +0 -1
  139. package/build/client/assets/onboarding-C2YNq60k.js +0 -2
  140. package/build/client/assets/onboarding-C2YNq60k.js.map +0 -1
  141. package/build/client/assets/presence-DJGFvdDh.js +0 -28
  142. package/build/client/assets/presence-DJGFvdDh.js.map +0 -1
  143. package/build/client/assets/test-DoKJvNug.js +0 -2
  144. package/build/client/assets/tests-DbuyD2cI.js.map +0 -1
  145. /package/build/client/assets/{epic-video-DUnRvy1A.css → index-DUnRvy1A.css} +0 -0
@@ -1,2 +0,0 @@
1
- import{a as i,b as a,j as o,i as c}from"./index-BFGhCX_U.js";import{g as m}from"./misc-DUy_whwE.js";function f({defaultStatusHandler:s=({error:r})=>o.jsxs("p",{children:[r.status," ",r.data]}),statusHandlers:e,unexpectedErrorHandler:t=r=>o.jsx("p",{children:m(r)})}){const r=i(),n=a();return typeof document<"u"&&console.error(r),o.jsx("div",{className:"container flex items-center justify-center p-20 text-h2",children:c(r)?((e==null?void 0:e[r.status])??s)({error:r,params:n}):t(r)})}export{f as G};
2
- //# sourceMappingURL=error-boundary-BZA-ffa8.js.map
@@ -1,2 +0,0 @@
1
- import{j as e,r as t}from"./index-BFGhCX_U.js";import{E as l}from"./index-BCxBKsqT.js";import{E as n}from"./epic-video-Bp4BOD2R.js";import{L as a}from"./loading-XhMtj4mp.js";import{N as d}from"./nav-chevrons-DnR25VLp.js";import{u as c}from"./revalidation-ws-dUa9CAqr.js";import{M as m,E as p}from"./mdx-CEjzXoEx.js";import{a as f}from"./misc-DUy_whwE.js";import{g as h}from"./seo-pBpFCWsy.js";import{P as x}from"./progress-DQt_Bn9o.js";import{u,L as j}from"./components-Be92gVxW.js";import"./index-Bdg3v8tC.js";import"./request-info-ByUEfOil.js";import"./tooltip-DO9uwurQ.js";import"./pe-ChIwTk8v.js";import"./user-Bv6wYhQP.js";import"./workshop-config-WVltG_BV.js";import"./progress-bar-BaTU3Yx_.js";const H={getSitemapEntries:()=>[{route:"/finished"}]},U=({matches:s})=>{var i;const r=(i=s.find(o=>o.id==="root"))==null?void 0:i.data;return r?h({title:`🎉 ${r==null?void 0:r.workshopTitle}`,description:`Elaboration for ${r==null?void 0:r.workshopTitle}`,ogTitle:`Finished ${r==null?void 0:r.workshopTitle}`,ogDescription:"You finished! Time to submit feedback.",instructor:r.instructor,requestInfo:r.requestInfo}):[]},b={h1:()=>null};function z(){const s=u();return c({watchPaths:["./exercises/FINISHED.mdx"]}),e.jsx("div",{className:"flex h-full flex-grow flex-col",children:e.jsxs("main",{className:"grid h-full flex-grow grid-cols-1 grid-rows-2 lg:grid-cols-2 lg:grid-rows-1",children:[e.jsxs("div",{className:"relative col-span-1 row-span-1 flex h-full flex-col lg:border-r",children:[e.jsx("h1",{className:"h-14 border-b pl-10 pr-5 text-sm font-medium uppercase leading-none",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(j,{to:"/",className:"hover:underline",children:s.workshopTitle}),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:s.articleId,children:s.finishedCode?e.jsx(n,{epicVideoInfosPromise:s.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(m,{code:s.finishedCode,components:b})})}):"No finished instructions yet..."}),e.jsx(l,{elementQuery:`#${s.articleId}`}),e.jsx(x,{type:"workshop-finished",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",{}),s.workshopFinished.status==="success"?e.jsx(p,{file:s.workshopFinished.file,relativePath:s.workshopFinished.relativePath}):null,e.jsx(d,{prev:s.prevStepLink,next:{to:"/"}})]})]}),e.jsx(g,{workshopTitle:s.workshopTitle,workshopFormEmbedUrl:s.workshopFormEmbedUrl})]})})}function g({workshopTitle:s,workshopFormEmbedUrl:r}){const[i,o]=t.useState(!1);return e.jsxs("div",{className:"relative flex-shrink-0",children:[i?null:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center",children:e.jsx(a,{children:e.jsxs("span",{children:["Loading ",s," Elaboration form"]})})}),e.jsx("iframe",{onLoad:()=>o(!0),onError:()=>o(!0),title:"Elaboration",src:r,className:f("absolute inset-0 flex h-full w-full transition-opacity duration-300",i?"opacity-100":"opacity-0")})]})}export{z as default,H as handle,U as meta};
2
- //# sourceMappingURL=finished-C0cpfAFL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"finished-C0cpfAFL.js","sources":["../../../app/routes/_app+/finished.tsx"],"sourcesContent":["import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopFinished,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport {\n\tunstable_data as data,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n\ttype MetaFunction,\n} from '@remix-run/node'\nimport { Link, useLoaderData } from '@remix-run/react'\nimport slugify from '@sindresorhus/slugify'\nimport * as React from 'react'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.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 loader as rootLoader } from '#app/root.tsx'\nimport { getEpicVideoInfos } from '#app/utils/epic-api.ts'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { getSeoMetaTags } from '#app/utils/seo.js'\nimport { EditFileOnGitHub } from '../launch-editor.tsx'\nimport { ProgressToggle } from '../progress.tsx'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => [{ route: '/finished' }],\n}\n\nexport const meta: MetaFunction<typeof loader, { root: typeof rootLoader }> = ({\n\tmatches,\n}) => {\n\tconst rootData = matches.find((m) => m.id === 'root')?.data\n\tif (!rootData) return []\n\n\treturn getSeoMetaTags({\n\t\ttitle: `🎉 ${rootData?.workshopTitle}`,\n\t\tdescription: `Elaboration for ${rootData?.workshopTitle}`,\n\t\togTitle: `Finished ${rootData?.workshopTitle}`,\n\t\togDescription: `You finished! Time to submit feedback.`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('finishedLoader')\n\tconst exercises = await getExercises({ request, timings })\n\tconst compiledFinished = await time(() => getWorkshopFinished({ request }), {\n\t\ttimings,\n\t\ttype: 'compileMdx',\n\t\tdesc: 'compileMdx in finished',\n\t})\n\n\tconst lastExercises = exercises[exercises.length - 1]\n\tconst workshopConfig = getWorkshopConfig()\n\tconst workshopTitle = workshopConfig.title\n\tconst workshopFormTemplate = workshopConfig.forms.workshop\n\tconst workshopFormEmbedUrl = workshopFormTemplate.replace(\n\t\t'{workshopTitle}',\n\t\tencodeURIComponent(workshopTitle),\n\t)\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(workshopTitle)}-finished`,\n\t\t\tworkshopTitle,\n\t\t\tworkshopFormEmbedUrl,\n\t\t\tfinishedCode:\n\t\t\t\tcompiledFinished.compiled.status === 'success'\n\t\t\t\t\t? compiledFinished.compiled.code\n\t\t\t\t\t: null,\n\t\t\tepicVideoInfosPromise:\n\t\t\t\tcompiledFinished.compiled.status === 'success'\n\t\t\t\t\t? getEpicVideoInfos(compiledFinished.compiled.epicVideoEmbeds, {\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t})\n\t\t\t\t\t: null,\n\t\t\tworkshopFinished: {\n\t\t\t\tstatus: compiledFinished.compiled.status,\n\t\t\t\tfile: compiledFinished.file,\n\t\t\t\trelativePath: compiledFinished.relativePath,\n\t\t\t},\n\t\t\tprevStepLink: lastExercises\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/${lastExercises.exerciseNumber}/finished`,\n\t\t\t\t\t}\n\t\t\t\t: null,\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 }\n\nexport default function ExerciseFinished() {\n\tconst data = useLoaderData<typeof loader>()\n\tuseRevalidationWS({ watchPaths: ['./exercises/FINISHED.mdx'] })\n\treturn (\n\t\t<div className=\"flex h-full flex-grow flex-col\">\n\t\t\t<main className=\"grid h-full flex-grow grid-cols-1 grid-rows-2 lg:grid-cols-2 lg:grid-rows-1\">\n\t\t\t\t<div className=\"relative col-span-1 row-span-1 flex h-full flex-col lg:border-r\">\n\t\t\t\t\t<h1 className=\"h-14 border-b pl-10 pr-5 text-sm font-medium uppercase leading-none\">\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=\"/\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t{data.workshopTitle}\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\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.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 code={data.finishedCode} components={mdxComponents} />\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=\"workshop-finished\"\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{data.workshopFinished.status === 'success' ? (\n\t\t\t\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\t\t\t\tfile={data.workshopFinished.file}\n\t\t\t\t\t\t\t\trelativePath={data.workshopFinished.relativePath}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<NavChevrons prev={data.prevStepLink} next={{ to: '/' }} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<Survey\n\t\t\t\t\tworkshopTitle={data.workshopTitle}\n\t\t\t\t\tworkshopFormEmbedUrl={data.workshopFormEmbedUrl}\n\t\t\t\t/>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nfunction Survey({\n\tworkshopTitle,\n\tworkshopFormEmbedUrl,\n}: {\n\tworkshopTitle: string\n\tworkshopFormEmbedUrl: string\n}) {\n\tconst [iframeLoaded, setIframeLoaded] = React.useState(false)\n\treturn (\n\t\t<div className=\"relative 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 {workshopTitle} 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={workshopFormEmbedUrl}\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/>\n\t\t</div>\n\t)\n}\n"],"names":["handle","getSitemapEntries","route","meta","matches","rootData","find","m","id","data","getSeoMetaTags","title","workshopTitle","description","ogTitle","ogDescription","instructor","requestInfo","mdxComponents","h1","ExerciseFinished","useLoaderData","useRevalidationWS","watchPaths","className","children","jsxs","jsx","Link","to","articleId","finishedCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","ElementScrollRestoration","elementQuery","ProgressToggle","type","workshopFinished","status","EditFileOnGitHub","file","relativePath","NavChevrons","prev","prevStepLink","next","Survey","workshopFormEmbedUrl","iframeLoaded","setIframeLoaded","React","Loading","onLoad","onError","src","cn"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{r as l,j as t,e as xe}from"./index-BFGhCX_U.js";import{h as pe,u as O,n as ve,P,f as N,e as K,d as he,g as ge,S as je}from"./tooltip-DO9uwurQ.js";import{f as be,u as B}from"./index-DZDhtMuq.js";import{u as $,I as E,c as we}from"./misc-DUy_whwE.js";import{D as Ne}from"./diff-8nlDkmpc.js";import{G as ye}from"./error-boundary-BZA-ffa8.js";import{L as Ce}from"./loading-XhMtj4mp.js";import{D as Te,u as Pe}from"./discord-BUWZUTEC.js";import{u as V,A as Ee,L as H,e as Ie}from"./components-Be92gVxW.js";import{J as Se}from"./index-C9Hx0Dey.js";import{S as De}from"./set-playground-CBHBA46B.js";import{P as Re,a as Fe}from"./tests-DbuyD2cI.js";import{P as F}from"./preview-DaZd0wMb.js";import"./index-BCTr8uu6.js";import"./accordion-D9-D-n9p.js";import"./mdx-CEjzXoEx.js";import"./epic-video-Bp4BOD2R.js";import"./index-Bdg3v8tC.js";import"./request-info-ByUEfOil.js";import"./pe-ChIwTk8v.js";import"./user-Bv6wYhQP.js";import"./workshop-config-WVltG_BV.js";import"./progress-bar-BaTU3Yx_.js";import"./revalidation-ws-dUa9CAqr.js";import"./use-event-source-x59d4R2Z.js";import"./button-_qPvcoqR.js";function _e(e,n=[]){let r=[];function s(p,o){const c=l.createContext(o),m=r.length;r=[...r,o];function d(u){const{scope:x,children:w,...f}=u,g=(x==null?void 0:x[e][m])||c,a=l.useMemo(()=>f,Object.values(f));return t.jsx(g.Provider,{value:a,children:w})}function v(u,x){const w=(x==null?void 0:x[e][m])||c,f=l.useContext(w);if(f)return f;if(o!==void 0)return o;throw new Error(`\`${u}\` must be used within \`${p}\``)}return d.displayName=p+"Provider",[d,v]}const i=()=>{const p=r.map(o=>l.createContext(o));return function(c){const m=(c==null?void 0:c[e])||p;return l.useMemo(()=>({[`__scope${e}`]:{...c,[e]:m}}),[c,m])}};return i.scopeName=e,[s,Ae(i,...n)]}function Ae(...e){const n=e[0];if(e.length===1)return n;const r=()=>{const s=e.map(i=>({useScope:i(),scopeName:i.scopeName}));return function(p){const o=s.reduce((c,{useScope:m,scopeName:d})=>{const u=m(p)[`__scope${d}`];return{...c,...u}},{});return l.useMemo(()=>({[`__scope${n.scopeName}`]:o}),[o])}};return r.scopeName=n.scopeName,r}var R="rovingFocusGroup.onEntryFocus",ke={bubbles:!1,cancelable:!0},I="RovingFocusGroup",[_,Y,Le]=be(I),[Ue,z]=_e(I,[Le]),[Me,Ge]=Ue(I),J=l.forwardRef((e,n)=>t.jsx(_.Provider,{scope:e.__scopeRovingFocusGroup,children:t.jsx(_.Slot,{scope:e.__scopeRovingFocusGroup,children:t.jsx(Oe,{...e,ref:n})})}));J.displayName=I;var Oe=l.forwardRef((e,n)=>{const{__scopeRovingFocusGroup:r,orientation:s,loop:i=!1,dir:p,currentTabStopId:o,defaultCurrentTabStopId:c,onCurrentTabStopIdChange:m,onEntryFocus:d,preventScrollOnEntryFocus:v=!1,...u}=e,x=l.useRef(null),w=pe(n,x),f=B(p),[g=null,a]=O({prop:o,defaultProp:c,onChange:m}),[h,b]=l.useState(!1),C=ve(d),le=Y(r),S=l.useRef(!1),[ce,U]=l.useState(0);return l.useEffect(()=>{const j=x.current;if(j)return j.addEventListener(R,C),()=>j.removeEventListener(R,C)},[C]),t.jsx(Me,{scope:r,orientation:s,dir:f,loop:i,currentTabStopId:g,onItemFocus:l.useCallback(j=>a(j),[a]),onItemShiftTab:l.useCallback(()=>b(!0),[]),onFocusableItemAdd:l.useCallback(()=>U(j=>j+1),[]),onFocusableItemRemove:l.useCallback(()=>U(j=>j-1),[]),children:t.jsx(P.div,{tabIndex:h||ce===0?-1:0,"data-orientation":s,...u,ref:w,style:{outline:"none",...e.style},onMouseDown:N(e.onMouseDown,()=>{S.current=!0}),onFocus:N(e.onFocus,j=>{const ue=!S.current;if(j.target===j.currentTarget&&ue&&!h){const M=new CustomEvent(R,ke);if(j.currentTarget.dispatchEvent(M),!M.defaultPrevented){const D=le().filter(y=>y.focusable),de=D.find(y=>y.active),fe=D.find(y=>y.id===g),me=[de,fe,...D].filter(Boolean).map(y=>y.ref.current);Q(me,v)}}S.current=!1}),onBlur:N(e.onBlur,()=>b(!1))})})}),W="RovingFocusGroupItem",q=l.forwardRef((e,n)=>{const{__scopeRovingFocusGroup:r,focusable:s=!0,active:i=!1,tabStopId:p,...o}=e,c=K(),m=p||c,d=Ge(W,r),v=d.currentTabStopId===m,u=Y(r),{onFocusableItemAdd:x,onFocusableItemRemove:w}=d;return l.useEffect(()=>{if(s)return x(),()=>w()},[s,x,w]),t.jsx(_.ItemSlot,{scope:r,id:m,focusable:s,active:i,children:t.jsx(P.span,{tabIndex:v?0:-1,"data-orientation":d.orientation,...o,ref:n,onMouseDown:N(e.onMouseDown,f=>{s?d.onItemFocus(m):f.preventDefault()}),onFocus:N(e.onFocus,()=>d.onItemFocus(m)),onKeyDown:N(e.onKeyDown,f=>{if(f.key==="Tab"&&f.shiftKey){d.onItemShiftTab();return}if(f.target!==f.currentTarget)return;const g=$e(f,d.orientation,d.dir);if(g!==void 0){if(f.metaKey||f.ctrlKey||f.altKey||f.shiftKey)return;f.preventDefault();let h=u().filter(b=>b.focusable).map(b=>b.ref.current);if(g==="last")h.reverse();else if(g==="prev"||g==="next"){g==="prev"&&h.reverse();const b=h.indexOf(f.currentTarget);h=d.loop?Ve(h,b+1):h.slice(b+1)}setTimeout(()=>Q(h))}})})})});q.displayName=W;var Ke={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function Be(e,n){return n!=="rtl"?e:e==="ArrowLeft"?"ArrowRight":e==="ArrowRight"?"ArrowLeft":e}function $e(e,n,r){const s=Be(e.key,r);if(!(n==="vertical"&&["ArrowLeft","ArrowRight"].includes(s))&&!(n==="horizontal"&&["ArrowUp","ArrowDown"].includes(s)))return Ke[s]}function Q(e,n=!1){const r=document.activeElement;for(const s of e)if(s===r||(s.focus({preventScroll:n}),document.activeElement!==r))return}function Ve(e,n){return e.map((r,s)=>e[(n+s)%e.length])}var He=J,Ye=q,k="Tabs",[ze,Rt]=he(k,[z]),X=z(),[Je,L]=ze(k),Z=l.forwardRef((e,n)=>{const{__scopeTabs:r,value:s,onValueChange:i,defaultValue:p,orientation:o="horizontal",dir:c,activationMode:m="automatic",...d}=e,v=B(c),[u,x]=O({prop:s,onChange:i,defaultProp:p});return t.jsx(Je,{scope:r,baseId:K(),value:u,onValueChange:x,orientation:o,dir:v,activationMode:m,children:t.jsx(P.div,{dir:v,"data-orientation":o,...d,ref:n})})});Z.displayName=k;var ee="TabsList",te=l.forwardRef((e,n)=>{const{__scopeTabs:r,loop:s=!0,...i}=e,p=L(ee,r),o=X(r);return t.jsx(He,{asChild:!0,...o,orientation:p.orientation,dir:p.dir,loop:s,children:t.jsx(P.div,{role:"tablist","aria-orientation":p.orientation,...i,ref:n})})});te.displayName=ee;var re="TabsTrigger",se=l.forwardRef((e,n)=>{const{__scopeTabs:r,value:s,disabled:i=!1,...p}=e,o=L(re,r),c=X(r),m=ae(o.baseId,s),d=ie(o.baseId,s),v=s===o.value;return t.jsx(Ye,{asChild:!0,...c,focusable:!i,active:v,children:t.jsx(P.button,{type:"button",role:"tab","aria-selected":v,"aria-controls":d,"data-state":v?"active":"inactive","data-disabled":i?"":void 0,disabled:i,id:m,...p,ref:n,onMouseDown:N(e.onMouseDown,u=>{!i&&u.button===0&&u.ctrlKey===!1?o.onValueChange(s):u.preventDefault()}),onKeyDown:N(e.onKeyDown,u=>{[" ","Enter"].includes(u.key)&&o.onValueChange(s)}),onFocus:N(e.onFocus,()=>{const u=o.activationMode!=="manual";!v&&!i&&u&&o.onValueChange(s)})})})});se.displayName=re;var ne="TabsContent",oe=l.forwardRef((e,n)=>{const{__scopeTabs:r,value:s,forceMount:i,children:p,...o}=e,c=L(ne,r),m=ae(c.baseId,s),d=ie(c.baseId,s),v=s===c.value,u=l.useRef(v);return l.useEffect(()=>{const x=requestAnimationFrame(()=>u.current=!1);return()=>cancelAnimationFrame(x)},[]),t.jsx(ge,{present:i||v,children:({present:x})=>t.jsx(P.div,{"data-state":v?"active":"inactive","data-orientation":c.orientation,role:"tabpanel","aria-labelledby":m,hidden:!x,id:d,tabIndex:0,...o,ref:n,style:{...e.style,animationDuration:u.current?"0s":void 0},children:x&&p})})});oe.displayName=ne;function ae(e,n){return`${e}-trigger-${n}`}function ie(e,n){return`${e}-content-${n}`}var We=Z,qe=te,Qe=se,T=oe;function Xe(){return t.jsxs("div",{className:"flex h-full w-full flex-col gap-4 pt-4",children:[t.jsx("div",{className:"text-center",children:t.jsx(Te,{})}),t.jsx("div",{className:"flex-1 overflow-y-scroll bg-accent pb-4 scrollbar-thin scrollbar-thumb-scrollbar",children:t.jsx(Ze,{})})]})}function Ze(){const e=V(),n=Pe(),r=$();return t.jsxs("div",{className:"flex h-full flex-col items-center justify-between",children:[t.jsx(l.Suspense,{fallback:t.jsx("div",{className:"flex h-full w-full flex-col items-center justify-center",children:t.jsx(Ce,{children:"Loading Discord Posts"})}),children:t.jsx(Ee,{resolve:e.discordPostsPromise,errorElement:t.jsx("div",{className:"text-red-500",children:"There was a problem loading the discord posts"}),children:s=>t.jsx("ul",{className:"flex w-full flex-col gap-4 p-3 xl:p-12",children:s.map(i=>t.jsx("li",{className:"rounded-xl border bg-background transition-all duration-200 focus-within:-translate-y-1 focus-within:shadow-lg hover:-translate-y-1 hover:shadow-lg",children:t.jsx(et,{thread:i})},i.id))})})}),t.jsx("div",{children:t.jsxs(H,{to:r&&!n.includes("oauth")?n.replace(/^https/,"discord"):n,target:n.includes("oauth")?void 0:"_blank",rel:"noreferrer noopener",onClick:r?s=>{s.preventDefault(),window.open(s.currentTarget.href,"_blank","noreferrer noopener")}:void 0,className:"flex items-center gap-2 p-2 text-xl hover:underline",children:["Create Post ",t.jsx(E,{name:"ExternalLink"})]})})]})}function et({thread:e}){const n=e.reactions.filter(r=>r.count);return t.jsx("div",{children:t.jsxs("div",{className:"flex flex-col gap-2 p-4",children:[t.jsxs("div",{className:"flex gap-4",children:[t.jsxs("div",{className:"flex flex-col gap-1",children:[e.tags.length?t.jsx("div",{className:"flex gap-2",children:e.tags.map(r=>t.jsxs("div",{className:"flex items-center justify-center gap-1 rounded-full bg-accent px-2 py-1 text-sm",children:[t.jsx("span",{className:"h-3 w-3 leading-3",children:t.jsx(G,{name:r.emojiName,url:r.emojiUrl})}),t.jsx("span",{children:r.name})]},r.name))}):null,t.jsx("strong",{className:"text-xl font-bold",children:e.name}),t.jsxs("div",{className:"flex items-start gap-1",children:[t.jsxs("div",{className:"flex items-center gap-1",children:[e.authorAvatarUrl?t.jsx("img",{src:e.authorAvatarUrl,alt:"",className:"h-6 w-6 rounded-full"}):null,t.jsxs("span",{children:[t.jsx("span",{className:"font-bold",style:e.authorHexAccentColor?{color:e.authorHexAccentColor}:{},children:e.authorDisplayName}),":"," "]})]}),t.jsx("span",{className:"flex-1 overflow-ellipsis text-muted-foreground",children:e.messagePreview})]})]}),e.previewImageUrl?t.jsx("img",{src:e.previewImageUrl,alt:"",className:"h-28 w-28 rounded-lg object-cover"}):null]}),t.jsxs("div",{className:"flex justify-between",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("span",{children:n.length?t.jsx("ul",{className:"flex items-center gap-2",children:n.map((r,s)=>t.jsxs("li",{className:"flex items-center gap-1 rounded-md border border-blue-600 bg-blue-500/20 px-[5px] py-[0.5px] text-sm",children:[t.jsx("span",{className:"h-3 w-3 leading-3",children:t.jsx(G,{name:r.emojiName,url:r.emojiUrl})}),t.jsx("span",{children:r.count})]},s))}):null}),t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(E,{name:"Chat"})," ",e.messageCount]}),` · ${e.lastUpdatedDisplay}`]})]}),t.jsxs("span",{className:"flex items-center gap-4",children:[t.jsx("a",{href:e.link.replace(/^https/,"discord"),children:t.jsx(E,{name:"Discord"})}),t.jsx("a",{href:e.link,target:"_blank",rel:"noreferrer noopener",children:t.jsx(E,{name:"ExternalLink"})})]})]})]})})}function G({name:e,url:n}){return n?t.jsx("img",{src:n,alt:e,className:"h-full w-full"}):e||null}function tt({appInfo:e,inBrowserBrowserRef:n,problemAppName:r,allApps:s,isUpToDate:i}){return t.jsx(Re,{playgroundAppName:e==null?void 0:e.appName,problemAppName:r,allApps:s,isUpToDate:i,children:(e==null?void 0:e.dev.type)==="none"?t.jsxs("div",{children:[t.jsx("div",{className:"text-foreground-secondary flex h-full items-center justify-center text-2xl",children:"Non-UI playground"}),t.jsx("div",{children:t.jsxs("div",{className:"text-foreground-secondary flex flex-wrap gap-1 text-center",children:["Navigate to"," ",t.jsx(je,{content:e.fullPath,children:t.jsx("span",{className:"underline",onClick:()=>{navigator.clipboard.writeText(e.fullPath),Se.success("Copied playground path to clipboard")},children:"the playground directory"})})," ","in your editor and terminal to work on this exercise!"]})})]}):e?t.jsx(F,{id:e.appName,appInfo:e,inBrowserBrowserRef:n}):t.jsxs("div",{className:"flex flex-col justify-center gap-2",children:[t.jsx("p",{children:"Please set the playground first"}),r?t.jsx(De,{appName:r}):null]})})}const A=["playground","problem","solution","tests","diff","chat"],rt=e=>!!(e&&A.includes(e));function st(e,n,r){const s=new URLSearchParams(e);return r===null?s.delete(n):s.set(n,r),s}function Ft(){var v,u,x,w,f,g;const e=V(),[n]=Ie(),r=n.get("preview"),s=l.useRef(null),i=$(),p=xe();function o(a){var h,b,C;if(a==="tests")return ENV.EPICSHOP_DEPLOYED||!e.playground||e.playground.test.type==="none";if(a==="problem"||a==="solution"){if(((h=e[a])==null?void 0:h.dev.type)==="none")return!0;if(ENV.EPICSHOP_DEPLOYED)return((b=e[a])==null?void 0:b.dev.type)!=="browser"&&!((C=e[a])!=null&&C.stackBlitzUrl)}return!!(a==="playground"&&ENV.EPICSHOP_DEPLOYED)}const c=rt(r)?r:A.find(a=>!o(a)),m=`/diff?${new URLSearchParams({app1:((v=e.problem)==null?void 0:v.name)??"",app2:((u=e.solution)==null?void 0:u.name)??""})}`;function d(a){a.altKey&&!a.ctrlKey&&!a.shiftKey&&!a.metaKey&&(a.preventDefault(),p(m))}return t.jsxs(We,{className:"relative flex flex-col overflow-y-auto sm:col-span-1 sm:row-span-1",value:c,children:[t.jsx(qe,{className:"h-14 min-h-14 overflow-x-hidden border-b scrollbar-thin scrollbar-thumb-scrollbar",children:A.map(a=>{const h=o(a);return t.jsx(Qe,{value:a,hidden:h,asChild:!0,children:t.jsx(H,{id:`${a}-tab`,className:we("clip-path-button relative h-full px-6 py-4 font-mono text-sm uppercase outline-none radix-state-active:z-10 radix-state-active:bg-foreground radix-state-active:text-background radix-state-active:hover:bg-foreground/80 radix-state-active:hover:text-background/80 radix-state-inactive:hover:bg-foreground/20 radix-state-inactive:hover:text-foreground/80 focus:bg-foreground/80 focus:text-background/80",h?"hidden":"inline-block"),preventScrollReset:!0,prefetch:"intent",onClick:d,to:a==="diff"&&i?m:`?${st(n,"preview",a==="playground"?null:a)}`,children:a})},a)})}),t.jsxs("div",{className:"relative z-10 flex min-h-96 flex-grow flex-col overflow-y-auto",children:[t.jsx(T,{value:"playground",className:"flex w-full flex-grow items-center justify-center self-start radix-state-inactive:hidden",children:t.jsx(tt,{appInfo:e.playground,problemAppName:(x=e.problem)==null?void 0:x.name,inBrowserBrowserRef:s,allApps:e.allApps,isUpToDate:((w=e.playground)==null?void 0:w.isUpToDate)??!1})}),t.jsx(T,{value:"problem",className:"flex w-full flex-grow items-center justify-center self-start radix-state-inactive:hidden",children:t.jsx(F,{appInfo:e.problem,inBrowserBrowserRef:s})}),t.jsx(T,{value:"solution",className:"flex w-full flex-grow items-center justify-center self-start radix-state-inactive:hidden",children:t.jsx(F,{appInfo:e.solution,inBrowserBrowserRef:s})}),t.jsx(T,{value:"tests",className:"flex w-full flex-grow items-start justify-center self-start overflow-hidden radix-state-inactive:hidden",children:t.jsx(Fe,{appInfo:e.playground,problemAppName:(f=e.problem)==null?void 0:f.name,allApps:e.allApps,isUpToDate:((g=e.playground)==null?void 0:g.isUpToDate)??!1})}),t.jsx(T,{value:"diff",className:"flex h-full w-full flex-grow items-start justify-center self-start radix-state-inactive:hidden",children:t.jsx(Ne,{diff:e.diff,allApps:e.allApps})}),t.jsx(T,{value:"chat",className:"flex h-full w-full flex-grow items-start justify-center self-start radix-state-inactive:hidden",children:t.jsx(Xe,{})})]})]})}function _t(){return t.jsx(ye,{statusHandlers:{404:()=>t.jsx("p",{children:"Sorry, we couldn't find an app here."})}})}export{_t as ErrorBoundary,Ft as default};
2
- //# sourceMappingURL=index-Bi1TbRTj.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-Bi1TbRTj.js","sources":["../../../../../node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context/dist/index.mjs","../../../../../node_modules/@radix-ui/react-roving-focus/dist/index.mjs","../../../../../node_modules/@radix-ui/react-tabs/dist/index.mjs","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/discord.tsx","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/playground.tsx","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/index.tsx"],"sourcesContent":["// packages/react/context/src/createContext.tsx\nimport * as React from \"react\";\nimport { jsx } from \"react/jsx-runtime\";\nfunction createContext2(rootComponentName, defaultContext) {\n const Context = React.createContext(defaultContext);\n function Provider(props) {\n const { children, ...context } = props;\n const value = React.useMemo(() => context, Object.values(context));\n return /* @__PURE__ */ jsx(Context.Provider, { value, children });\n }\n function useContext2(consumerName) {\n const context = React.useContext(Context);\n if (context) return context;\n if (defaultContext !== void 0) return defaultContext;\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n Provider.displayName = rootComponentName + \"Provider\";\n return [Provider, useContext2];\n}\nfunction createContextScope(scopeName, createContextScopeDeps = []) {\n let defaultContexts = [];\n function createContext3(rootComponentName, defaultContext) {\n const BaseContext = React.createContext(defaultContext);\n const index = defaultContexts.length;\n defaultContexts = [...defaultContexts, defaultContext];\n function Provider(props) {\n const { scope, children, ...context } = props;\n const Context = scope?.[scopeName][index] || BaseContext;\n const value = React.useMemo(() => context, Object.values(context));\n return /* @__PURE__ */ jsx(Context.Provider, { value, children });\n }\n function useContext2(consumerName, scope) {\n const Context = scope?.[scopeName][index] || BaseContext;\n const context = React.useContext(Context);\n if (context) return context;\n if (defaultContext !== void 0) return defaultContext;\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n Provider.displayName = rootComponentName + \"Provider\";\n return [Provider, useContext2];\n }\n const createScope = () => {\n const scopeContexts = defaultContexts.map((defaultContext) => {\n return React.createContext(defaultContext);\n });\n return function useScope(scope) {\n const contexts = scope?.[scopeName] || scopeContexts;\n return React.useMemo(\n () => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }),\n [scope, contexts]\n );\n };\n };\n createScope.scopeName = scopeName;\n return [createContext3, composeContextScopes(createScope, ...createContextScopeDeps)];\n}\nfunction composeContextScopes(...scopes) {\n const baseScope = scopes[0];\n if (scopes.length === 1) return baseScope;\n const createScope = () => {\n const scopeHooks = scopes.map((createScope2) => ({\n useScope: createScope2(),\n scopeName: createScope2.scopeName\n }));\n return function useComposedScopes(overrideScopes) {\n const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {\n const scopeProps = useScope(overrideScopes);\n const currentScope = scopeProps[`__scope${scopeName}`];\n return { ...nextScopes2, ...currentScope };\n }, {});\n return React.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]);\n };\n };\n createScope.scopeName = baseScope.scopeName;\n return createScope;\n}\nexport {\n createContext2 as createContext,\n createContextScope\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// packages/react/roving-focus/src/RovingFocusGroup.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { createCollection } from \"@radix-ui/react-collection\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport { jsx } from \"react/jsx-runtime\";\nvar ENTRY_FOCUS = \"rovingFocusGroup.onEntryFocus\";\nvar EVENT_OPTIONS = { bubbles: false, cancelable: true };\nvar GROUP_NAME = \"RovingFocusGroup\";\nvar [Collection, useCollection, createCollectionScope] = createCollection(GROUP_NAME);\nvar [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(\n GROUP_NAME,\n [createCollectionScope]\n);\nvar [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext(GROUP_NAME);\nvar RovingFocusGroup = React.forwardRef(\n (props, forwardedRef) => {\n return /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });\n }\n);\nRovingFocusGroup.displayName = GROUP_NAME;\nvar RovingFocusGroupImpl = React.forwardRef((props, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n orientation,\n loop = false,\n dir,\n currentTabStopId: currentTabStopIdProp,\n defaultCurrentTabStopId,\n onCurrentTabStopIdChange,\n onEntryFocus,\n preventScrollOnEntryFocus = false,\n ...groupProps\n } = props;\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const direction = useDirection(dir);\n const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({\n prop: currentTabStopIdProp,\n defaultProp: defaultCurrentTabStopId,\n onChange: onCurrentTabStopIdChange\n });\n const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);\n const handleEntryFocus = useCallbackRef(onEntryFocus);\n const getItems = useCollection(__scopeRovingFocusGroup);\n const isClickFocusRef = React.useRef(false);\n const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n node.addEventListener(ENTRY_FOCUS, handleEntryFocus);\n return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);\n }\n }, [handleEntryFocus]);\n return /* @__PURE__ */ jsx(\n RovingFocusProvider,\n {\n scope: __scopeRovingFocusGroup,\n orientation,\n dir: direction,\n loop,\n currentTabStopId,\n onItemFocus: React.useCallback(\n (tabStopId) => setCurrentTabStopId(tabStopId),\n [setCurrentTabStopId]\n ),\n onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),\n onFocusableItemAdd: React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount + 1),\n []\n ),\n onFocusableItemRemove: React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount - 1),\n []\n ),\n children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,\n \"data-orientation\": orientation,\n ...groupProps,\n ref: composedRefs,\n style: { outline: \"none\", ...props.style },\n onMouseDown: composeEventHandlers(props.onMouseDown, () => {\n isClickFocusRef.current = true;\n }),\n onFocus: composeEventHandlers(props.onFocus, (event) => {\n const isKeyboardFocus = !isClickFocusRef.current;\n if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {\n const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n event.currentTarget.dispatchEvent(entryFocusEvent);\n if (!entryFocusEvent.defaultPrevented) {\n const items = getItems().filter((item) => item.focusable);\n const activeItem = items.find((item) => item.active);\n const currentItem = items.find((item) => item.id === currentTabStopId);\n const candidateItems = [activeItem, currentItem, ...items].filter(\n Boolean\n );\n const candidateNodes = candidateItems.map((item) => item.ref.current);\n focusFirst(candidateNodes, preventScrollOnEntryFocus);\n }\n }\n isClickFocusRef.current = false;\n }),\n onBlur: composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))\n }\n )\n }\n );\n});\nvar ITEM_NAME = \"RovingFocusGroupItem\";\nvar RovingFocusGroupItem = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n focusable = true,\n active = false,\n tabStopId,\n ...itemProps\n } = props;\n const autoId = useId();\n const id = tabStopId || autoId;\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\n const { onFocusableItemAdd, onFocusableItemRemove } = context;\n React.useEffect(() => {\n if (focusable) {\n onFocusableItemAdd();\n return () => onFocusableItemRemove();\n }\n }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);\n return /* @__PURE__ */ jsx(\n Collection.ItemSlot,\n {\n scope: __scopeRovingFocusGroup,\n id,\n focusable,\n active,\n children: /* @__PURE__ */ jsx(\n Primitive.span,\n {\n tabIndex: isCurrentTabStop ? 0 : -1,\n \"data-orientation\": context.orientation,\n ...itemProps,\n ref: forwardedRef,\n onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {\n if (!focusable) event.preventDefault();\n else context.onItemFocus(id);\n }),\n onFocus: composeEventHandlers(props.onFocus, () => context.onItemFocus(id)),\n onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === \"Tab\" && event.shiftKey) {\n context.onItemShiftTab();\n return;\n }\n if (event.target !== event.currentTarget) return;\n const focusIntent = getFocusIntent(event, context.orientation, context.dir);\n if (focusIntent !== void 0) {\n if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;\n event.preventDefault();\n const items = getItems().filter((item) => item.focusable);\n let candidateNodes = items.map((item) => item.ref.current);\n if (focusIntent === \"last\") candidateNodes.reverse();\n else if (focusIntent === \"prev\" || focusIntent === \"next\") {\n if (focusIntent === \"prev\") candidateNodes.reverse();\n const currentIndex = candidateNodes.indexOf(event.currentTarget);\n candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);\n }\n setTimeout(() => focusFirst(candidateNodes));\n }\n })\n }\n )\n }\n );\n }\n);\nRovingFocusGroupItem.displayName = ITEM_NAME;\nvar MAP_KEY_TO_FOCUS_INTENT = {\n ArrowLeft: \"prev\",\n ArrowUp: \"prev\",\n ArrowRight: \"next\",\n ArrowDown: \"next\",\n PageUp: \"first\",\n Home: \"first\",\n PageDown: \"last\",\n End: \"last\"\n};\nfunction getDirectionAwareKey(key, dir) {\n if (dir !== \"rtl\") return key;\n return key === \"ArrowLeft\" ? \"ArrowRight\" : key === \"ArrowRight\" ? \"ArrowLeft\" : key;\n}\nfunction getFocusIntent(event, orientation, dir) {\n const key = getDirectionAwareKey(event.key, dir);\n if (orientation === \"vertical\" && [\"ArrowLeft\", \"ArrowRight\"].includes(key)) return void 0;\n if (orientation === \"horizontal\" && [\"ArrowUp\", \"ArrowDown\"].includes(key)) return void 0;\n return MAP_KEY_TO_FOCUS_INTENT[key];\n}\nfunction focusFirst(candidates, preventScroll = false) {\n const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;\n for (const candidate of candidates) {\n if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;\n candidate.focus({ preventScroll });\n if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;\n }\n}\nfunction wrapArray(array, startIndex) {\n return array.map((_, index) => array[(startIndex + index) % array.length]);\n}\nvar Root = RovingFocusGroup;\nvar Item = RovingFocusGroupItem;\nexport {\n Item,\n Root,\n RovingFocusGroup,\n RovingFocusGroupItem,\n createRovingFocusGroupScope\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// packages/react/tabs/src/Tabs.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { createRovingFocusGroupScope } from \"@radix-ui/react-roving-focus\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport * as RovingFocusGroup from \"@radix-ui/react-roving-focus\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { jsx } from \"react/jsx-runtime\";\nvar TABS_NAME = \"Tabs\";\nvar [createTabsContext, createTabsScope] = createContextScope(TABS_NAME, [\n createRovingFocusGroupScope\n]);\nvar useRovingFocusGroupScope = createRovingFocusGroupScope();\nvar [TabsProvider, useTabsContext] = createTabsContext(TABS_NAME);\nvar Tabs = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopeTabs,\n value: valueProp,\n onValueChange,\n defaultValue,\n orientation = \"horizontal\",\n dir,\n activationMode = \"automatic\",\n ...tabsProps\n } = props;\n const direction = useDirection(dir);\n const [value, setValue] = useControllableState({\n prop: valueProp,\n onChange: onValueChange,\n defaultProp: defaultValue\n });\n return /* @__PURE__ */ jsx(\n TabsProvider,\n {\n scope: __scopeTabs,\n baseId: useId(),\n value,\n onValueChange: setValue,\n orientation,\n dir: direction,\n activationMode,\n children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n dir: direction,\n \"data-orientation\": orientation,\n ...tabsProps,\n ref: forwardedRef\n }\n )\n }\n );\n }\n);\nTabs.displayName = TABS_NAME;\nvar TAB_LIST_NAME = \"TabsList\";\nvar TabsList = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeTabs, loop = true, ...listProps } = props;\n const context = useTabsContext(TAB_LIST_NAME, __scopeTabs);\n const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);\n return /* @__PURE__ */ jsx(\n RovingFocusGroup.Root,\n {\n asChild: true,\n ...rovingFocusGroupScope,\n orientation: context.orientation,\n dir: context.dir,\n loop,\n children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n role: \"tablist\",\n \"aria-orientation\": context.orientation,\n ...listProps,\n ref: forwardedRef\n }\n )\n }\n );\n }\n);\nTabsList.displayName = TAB_LIST_NAME;\nvar TRIGGER_NAME = \"TabsTrigger\";\nvar TabsTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeTabs, value, disabled = false, ...triggerProps } = props;\n const context = useTabsContext(TRIGGER_NAME, __scopeTabs);\n const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);\n const triggerId = makeTriggerId(context.baseId, value);\n const contentId = makeContentId(context.baseId, value);\n const isSelected = value === context.value;\n return /* @__PURE__ */ jsx(\n RovingFocusGroup.Item,\n {\n asChild: true,\n ...rovingFocusGroupScope,\n focusable: !disabled,\n active: isSelected,\n children: /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n role: \"tab\",\n \"aria-selected\": isSelected,\n \"aria-controls\": contentId,\n \"data-state\": isSelected ? \"active\" : \"inactive\",\n \"data-disabled\": disabled ? \"\" : void 0,\n disabled,\n id: triggerId,\n ...triggerProps,\n ref: forwardedRef,\n onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {\n if (!disabled && event.button === 0 && event.ctrlKey === false) {\n context.onValueChange(value);\n } else {\n event.preventDefault();\n }\n }),\n onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {\n if ([\" \", \"Enter\"].includes(event.key)) context.onValueChange(value);\n }),\n onFocus: composeEventHandlers(props.onFocus, () => {\n const isAutomaticActivation = context.activationMode !== \"manual\";\n if (!isSelected && !disabled && isAutomaticActivation) {\n context.onValueChange(value);\n }\n })\n }\n )\n }\n );\n }\n);\nTabsTrigger.displayName = TRIGGER_NAME;\nvar CONTENT_NAME = \"TabsContent\";\nvar TabsContent = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeTabs, value, forceMount, children, ...contentProps } = props;\n const context = useTabsContext(CONTENT_NAME, __scopeTabs);\n const triggerId = makeTriggerId(context.baseId, value);\n const contentId = makeContentId(context.baseId, value);\n const isSelected = value === context.value;\n const isMountAnimationPreventedRef = React.useRef(isSelected);\n React.useEffect(() => {\n const rAF = requestAnimationFrame(() => isMountAnimationPreventedRef.current = false);\n return () => cancelAnimationFrame(rAF);\n }, []);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || isSelected, children: ({ present }) => /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": isSelected ? \"active\" : \"inactive\",\n \"data-orientation\": context.orientation,\n role: \"tabpanel\",\n \"aria-labelledby\": triggerId,\n hidden: !present,\n id: contentId,\n tabIndex: 0,\n ...contentProps,\n ref: forwardedRef,\n style: {\n ...props.style,\n animationDuration: isMountAnimationPreventedRef.current ? \"0s\" : void 0\n },\n children: present && children\n }\n ) });\n }\n);\nTabsContent.displayName = CONTENT_NAME;\nfunction makeTriggerId(baseId, value) {\n return `${baseId}-trigger-${value}`;\n}\nfunction makeContentId(baseId, value) {\n return `${baseId}-content-${value}`;\n}\nvar Root2 = Tabs;\nvar List = TabsList;\nvar Trigger = TabsTrigger;\nvar Content = TabsContent;\nexport {\n Content,\n List,\n Root2 as Root,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Trigger,\n createTabsScope\n};\n//# sourceMappingURL=index.mjs.map\n","import { type SerializeFrom } from '@remix-run/node'\nimport { Await, Link, useLoaderData } from '@remix-run/react'\nimport * as React from 'react'\nimport { Icon } from '#app/components/icons.tsx'\nimport { Loading } from '#app/components/loading.tsx'\nimport { DiscordCTA, useDiscordCTALink } from '#app/routes/_app+/discord.tsx'\nimport { useAltDown } from '#app/utils/misc.tsx'\nimport { type loader } from '../index.tsx'\n\nexport function DiscordChat() {\n\treturn (\n\t\t<div className=\"flex h-full w-full flex-col gap-4 pt-4\">\n\t\t\t<div className=\"text-center\">\n\t\t\t\t<DiscordCTA />\n\t\t\t</div>\n\t\t\t<div className=\"flex-1 overflow-y-scroll bg-accent pb-4 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t<DiscordPosts />\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction DiscordPosts() {\n\tconst data = useLoaderData<typeof loader>()\n\tconst ctaLink = useDiscordCTALink()\n\tconst altDown = useAltDown()\n\treturn (\n\t\t<div className=\"flex h-full flex-col items-center justify-between\">\n\t\t\t<React.Suspense\n\t\t\t\tfallback={\n\t\t\t\t\t<div className=\"flex h-full w-full flex-col items-center justify-center\">\n\t\t\t\t\t\t<Loading>Loading Discord Posts</Loading>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t>\n\t\t\t\t<Await\n\t\t\t\t\tresolve={data.discordPostsPromise}\n\t\t\t\t\terrorElement={\n\t\t\t\t\t\t<div className=\"text-red-500\">\n\t\t\t\t\t\t\tThere was a problem loading the discord posts\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t>\n\t\t\t\t\t{(posts) => (\n\t\t\t\t\t\t<ul className=\"flex w-full flex-col gap-4 p-3 xl:p-12\">\n\t\t\t\t\t\t\t{posts.map((post) => (\n\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\tkey={post.id}\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-xl border bg-background transition-all duration-200 focus-within:-translate-y-1 focus-within:shadow-lg hover:-translate-y-1 hover:shadow-lg\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<DiscordPost thread={post} />\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t)}\n\t\t\t\t</Await>\n\t\t\t</React.Suspense>\n\t\t\t<div>\n\t\t\t\t<Link\n\t\t\t\t\tto={\n\t\t\t\t\t\taltDown && !ctaLink.includes('oauth')\n\t\t\t\t\t\t\t? ctaLink.replace(/^https/, 'discord')\n\t\t\t\t\t\t\t: ctaLink\n\t\t\t\t\t}\n\t\t\t\t\ttarget={ctaLink.includes('oauth') ? undefined : '_blank'}\n\t\t\t\t\trel=\"noreferrer noopener\"\n\t\t\t\t\tonClick={\n\t\t\t\t\t\taltDown\n\t\t\t\t\t\t\t? (e) => {\n\t\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\t\twindow.open(\n\t\t\t\t\t\t\t\t\t\te.currentTarget.href,\n\t\t\t\t\t\t\t\t\t\t'_blank',\n\t\t\t\t\t\t\t\t\t\t'noreferrer noopener',\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tclassName=\"flex items-center gap-2 p-2 text-xl hover:underline\"\n\t\t\t\t>\n\t\t\t\t\tCreate Post <Icon name=\"ExternalLink\" />\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction DiscordPost({\n\tthread,\n}: {\n\tthread: Awaited<SerializeFrom<typeof loader>['discordPostsPromise']>[number]\n}) {\n\tconst reactionsWithCounts = thread.reactions.filter((r) => r.count)\n\n\treturn (\n\t\t<div>\n\t\t\t<div className=\"flex flex-col gap-2 p-4\">\n\t\t\t\t<div className=\"flex gap-4\">\n\t\t\t\t\t<div className=\"flex flex-col gap-1\">\n\t\t\t\t\t\t{thread.tags.length ? (\n\t\t\t\t\t\t\t<div className=\"flex gap-2\">\n\t\t\t\t\t\t\t\t{thread.tags.map((t) => (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tkey={t.name}\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center justify-center gap-1 rounded-full bg-accent px-2 py-1 text-sm\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span className=\"h-3 w-3 leading-3\">\n\t\t\t\t\t\t\t\t\t\t\t<Emoji name={t.emojiName} url={t.emojiUrl} />\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<span>{t.name}</span>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<strong className=\"text-xl font-bold\">{thread.name}</strong>\n\t\t\t\t\t\t<div className=\"flex items-start gap-1\">\n\t\t\t\t\t\t\t<div className=\"flex items-center gap-1\">\n\t\t\t\t\t\t\t\t{thread.authorAvatarUrl ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tsrc={thread.authorAvatarUrl}\n\t\t\t\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"h-6 w-6 rounded-full\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclassName=\"font-bold\"\n\t\t\t\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\t\t\t\tthread.authorHexAccentColor\n\t\t\t\t\t\t\t\t\t\t\t\t? { color: thread.authorHexAccentColor }\n\t\t\t\t\t\t\t\t\t\t\t\t: {}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{thread.authorDisplayName}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<span className=\"flex-1 overflow-ellipsis text-muted-foreground\">\n\t\t\t\t\t\t\t\t{thread.messagePreview}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{thread.previewImageUrl ? (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tsrc={thread.previewImageUrl}\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tclassName=\"h-28 w-28 rounded-lg object-cover\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\n\t\t\t\t<div className=\"flex justify-between\">\n\t\t\t\t\t<div className=\"flex items-center gap-3\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{reactionsWithCounts.length ? (\n\t\t\t\t\t\t\t\t<ul className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t{reactionsWithCounts.map((r, i) => (\n\t\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center gap-1 rounded-md border border-blue-600 bg-blue-500/20 px-[5px] py-[0.5px] text-sm\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"h-3 w-3 leading-3\">\n\t\t\t\t\t\t\t\t\t\t\t\t<Emoji name={r.emojiName} url={r.emojiUrl} />\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t<span>{r.count}</span>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span className=\"flex items-center gap-1\">\n\t\t\t\t\t\t\t<span className=\"inline-flex items-center gap-1\">\n\t\t\t\t\t\t\t\t<Icon name=\"Chat\" /> {thread.messageCount}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{` · ${thread.lastUpdatedDisplay}`}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<span className=\"flex items-center gap-4\">\n\t\t\t\t\t\t<a href={thread.link.replace(/^https/, 'discord')}>\n\t\t\t\t\t\t\t<Icon name=\"Discord\" />\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<a href={thread.link} target=\"_blank\" rel=\"noreferrer noopener\">\n\t\t\t\t\t\t\t<Icon name=\"ExternalLink\" />\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction Emoji({ name, url }: { name?: string; url?: string }) {\n\treturn url ? (\n\t\t<img src={url} alt={name} className=\"h-full w-full\" />\n\t) : name ? (\n\t\tname\n\t) : null\n}\n","import { toast as showToast } from 'sonner'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser'\nimport { SimpleTooltip } from '#app/components/ui/tooltip'\nimport { SetAppToPlayground } from '#app/routes/set-playground'\nimport { PlaygroundWindow } from './playground-window'\nimport { Preview } from './preview'\n\nexport function Playground({\n\tappInfo: playgroundAppInfo,\n\tinBrowserBrowserRef,\n\tproblemAppName,\n\tallApps,\n\tisUpToDate,\n}: {\n\tappInfo: Parameters<typeof Preview>['0']['appInfo'] | null\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n\tproblemAppName?: string\n\tallApps: Array<{ name: string; displayName: string }>\n\tisUpToDate: boolean\n}) {\n\treturn (\n\t\t<PlaygroundWindow\n\t\t\tplaygroundAppName={playgroundAppInfo?.appName}\n\t\t\tproblemAppName={problemAppName}\n\t\t\tallApps={allApps}\n\t\t\tisUpToDate={isUpToDate}\n\t\t>\n\t\t\t{playgroundAppInfo?.dev.type === 'none' ? (\n\t\t\t\t<div>\n\t\t\t\t\t<div className=\"text-foreground-secondary flex h-full items-center justify-center text-2xl\">\n\t\t\t\t\t\tNon-UI playground\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<div className=\"text-foreground-secondary flex flex-wrap gap-1 text-center\">\n\t\t\t\t\t\t\tNavigate to{' '}\n\t\t\t\t\t\t\t<SimpleTooltip content={playgroundAppInfo.fullPath}>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tvoid navigator.clipboard.writeText(\n\t\t\t\t\t\t\t\t\t\t\tplaygroundAppInfo.fullPath,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\tshowToast.success('Copied playground path to clipboard')\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tthe playground directory\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</SimpleTooltip>{' '}\n\t\t\t\t\t\t\tin your editor and terminal to work on this exercise!\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : playgroundAppInfo ? (\n\t\t\t\t<Preview\n\t\t\t\t\tid={playgroundAppInfo.appName}\n\t\t\t\t\tappInfo={playgroundAppInfo}\n\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<div className=\"flex flex-col justify-center gap-2\">\n\t\t\t\t\t<p>Please set the playground first</p>\n\t\t\t\t\t{problemAppName ? (\n\t\t\t\t\t\t<SetAppToPlayground appName={problemAppName} />\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</PlaygroundWindow>\n\t)\n}\n","import {\n\tgetAppByName,\n\tgetAppDisplayName,\n\tgetApps,\n\tgetExerciseApp,\n\tisExerciseStepApp,\n\tisPlaygroundApp,\n\trequireExerciseApp,\n\ttype App,\n\ttype ExerciseStepApp,\n} from '@epic-web/workshop-utils/apps.server'\nimport { compileMarkdownString } from '@epic-web/workshop-utils/compile-mdx.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport * as Tabs from '@radix-ui/react-tabs'\nimport {\n\tunstable_data as data,\n\tredirect,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n} from '@remix-run/node'\nimport {\n\tLink,\n\tuseLoaderData,\n\tuseNavigate,\n\tuseSearchParams,\n} from '@remix-run/react'\nimport { clsx } from 'clsx'\nimport * as React from 'react'\nimport { useRef } from 'react'\nimport { Diff } from '#app/components/diff.tsx'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.tsx'\nimport { getDiffCode } from '#app/utils/diff.server.ts'\nimport { userHasAccessToWorkshop } from '#app/utils/epic-api.js'\nimport { useAltDown } from '#app/utils/misc.tsx'\nimport { fetchDiscordPosts } from './__shared/discord.server.ts'\nimport { DiscordChat } from './__shared/discord.tsx'\nimport { Playground } from './__shared/playground.tsx'\nimport { Preview } from './__shared/preview.tsx'\nimport { Tests } from './__shared/tests.tsx'\nimport { getAppRunningState } from './__shared/utils.tsx'\n\nexport async function loader({ request, params }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('exerciseStepTypeIndexLoader')\n\tconst userHasAccess = await userHasAccessToWorkshop({\n\t\trequest,\n\t\ttimings,\n\t})\n\tconst searchParams = new URL(request.url).searchParams\n\tconst cacheOptions = { request, timings }\n\tconst exerciseStepApp = await requireExerciseApp(params, cacheOptions)\n\tconst reqUrl = new URL(request.url)\n\n\tconst pathnameParam = reqUrl.searchParams.get('pathname')\n\tif (pathnameParam === '' || pathnameParam === '/') {\n\t\treqUrl.searchParams.delete('pathname')\n\t\tthrow redirect(reqUrl.toString())\n\t}\n\n\tconst problemApp = await getExerciseApp(\n\t\t{ ...params, type: 'problem' },\n\t\tcacheOptions,\n\t)\n\tconst solutionApp = await getExerciseApp(\n\t\t{ ...params, type: 'solution' },\n\t\tcacheOptions,\n\t)\n\n\tif (!problemApp && !solutionApp) {\n\t\tthrow new Response('Not found', { status: 404 })\n\t}\n\n\tconst allAppsFull = await getApps(cacheOptions)\n\tconst playgroundApp = allAppsFull.find(isPlaygroundApp)\n\n\tconst app1Name = reqUrl.searchParams.get('app1')\n\tconst app2Name = reqUrl.searchParams.get('app2')\n\tconst app1 = app1Name\n\t\t? await getAppByName(app1Name)\n\t\t: playgroundApp || problemApp\n\tconst app2 = app2Name ? await getAppByName(app2Name) : solutionApp\n\n\tfunction getStepId(a: ExerciseStepApp) {\n\t\treturn (\n\t\t\ta.exerciseNumber * 1000 +\n\t\t\ta.stepNumber * 10 +\n\t\t\t(a.type === 'problem' ? 0 : 1)\n\t\t)\n\t}\n\n\tfunction getStepNameAndId(a: App) {\n\t\tif (isExerciseStepApp(a)) {\n\t\t\tconst exerciseNumberStr = String(a.exerciseNumber).padStart(2, '0')\n\t\t\tconst stepNumberStr = String(a.stepNumber).padStart(2, '0')\n\n\t\t\treturn {\n\t\t\t\tstepName: `${exerciseNumberStr}/${stepNumberStr}.${a.type}`,\n\t\t\t\tstepId: getStepId(a),\n\t\t\t}\n\t\t}\n\t\treturn { stepName: '', stepId: -1 }\n\t}\n\n\tconst allApps = allAppsFull\n\t\t.filter((a, i, ar) => ar.findIndex((b) => a.name === b.name) === i)\n\t\t.map((a) => ({\n\t\t\tdisplayName: getAppDisplayName(a, allAppsFull),\n\t\t\tname: a.name,\n\t\t\ttitle: a.title,\n\t\t\ttype: a.type,\n\t\t\t...getStepNameAndId(a),\n\t\t}))\n\n\tallApps.sort((a, b) => {\n\t\t// order them by their stepId\n\t\tif (a.stepId > 0 && b.stepId > 0) return a.stepId - b.stepId\n\n\t\t// non-step apps should come after step apps\n\t\tif (a.stepId > 0) return -1\n\t\tif (b.stepId > 0) return 1\n\n\t\treturn 0\n\t})\n\n\tasync function getDiffProp() {\n\t\tif (!app1 || !app2) {\n\t\t\treturn {\n\t\t\t\tapp1: app1?.name,\n\t\t\t\tapp2: app2?.name,\n\t\t\t\tdiffCode: null,\n\t\t\t}\n\t\t}\n\t\tif (!userHasAccess) {\n\t\t\treturn {\n\t\t\t\tapp1: app1?.name,\n\t\t\t\tapp2: app2?.name,\n\t\t\t\tdiffCode: await compileMarkdownString(\n\t\t\t\t\t`<h1>Access Denied</h1><p>You must login or register for the workshop to view the diff</p>`,\n\t\t\t\t),\n\t\t\t}\n\t\t}\n\t\tconst diffCode = await getDiffCode(app1, app2, {\n\t\t\t...cacheOptions,\n\t\t\tforceFresh: searchParams.get('forceFresh') === 'diff',\n\t\t}).catch((e) => {\n\t\t\tconsole.error(e)\n\t\t\treturn null\n\t\t})\n\t\treturn {\n\t\t\tapp1: app1.name,\n\t\t\tapp2: app2.name,\n\t\t\tdiffCode,\n\t\t}\n\t}\n\n\treturn data(\n\t\t{\n\t\t\ttype: params.type as 'problem' | 'solution',\n\t\t\texerciseStepApp,\n\t\t\tallApps,\n\t\t\t// defer this promise so that we don't block the response from being sent\n\t\t\tdiscordPostsPromise: fetchDiscordPosts({ request }),\n\t\t\tplayground: playgroundApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'playground',\n\t\t\t\t\t\tfullPath: playgroundApp.fullPath,\n\t\t\t\t\t\tdev: playgroundApp.dev,\n\t\t\t\t\t\ttest: playgroundApp.test,\n\t\t\t\t\t\ttitle: playgroundApp.title,\n\t\t\t\t\t\tname: playgroundApp.name,\n\t\t\t\t\t\tappName: playgroundApp.appName,\n\t\t\t\t\t\tisUpToDate: playgroundApp.isUpToDate,\n\t\t\t\t\t\tstackBlitzUrl: playgroundApp.stackBlitzUrl,\n\t\t\t\t\t\t...(await getAppRunningState(playgroundApp)),\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tproblem: problemApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'problem',\n\t\t\t\t\t\tfullPath: problemApp.fullPath,\n\t\t\t\t\t\tdev: problemApp.dev,\n\t\t\t\t\t\ttest: problemApp.test,\n\t\t\t\t\t\ttitle: problemApp.title,\n\t\t\t\t\t\tname: problemApp.name,\n\t\t\t\t\t\tstackBlitzUrl: problemApp.stackBlitzUrl,\n\t\t\t\t\t\t...(await getAppRunningState(problemApp)),\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tsolution: solutionApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'solution',\n\t\t\t\t\t\tfullPath: solutionApp.fullPath,\n\t\t\t\t\t\tdev: solutionApp.dev,\n\t\t\t\t\t\ttest: solutionApp.test,\n\t\t\t\t\t\ttitle: solutionApp.title,\n\t\t\t\t\t\tname: solutionApp.name,\n\t\t\t\t\t\tstackBlitzUrl: solutionApp.stackBlitzUrl,\n\t\t\t\t\t\t...(await getAppRunningState(solutionApp)),\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tdiff: getDiffProp(),\n\t\t} as const,\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'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nconst tabs = [\n\t'playground',\n\t'problem',\n\t'solution',\n\t'tests',\n\t'diff',\n\t'chat',\n] as const\nconst isValidPreview = (s: string | null): s is (typeof tabs)[number] =>\n\tBoolean(s && tabs.includes(s as (typeof tabs)[number]))\n\nfunction withParam(\n\tsearchParams: URLSearchParams,\n\tkey: string,\n\tvalue: string | null,\n) {\n\tconst newSearchParams = new URLSearchParams(searchParams)\n\tif (value === null) {\n\t\tnewSearchParams.delete(key)\n\t} else {\n\t\tnewSearchParams.set(key, value)\n\t}\n\treturn newSearchParams\n}\n\nexport default function ExercisePartRoute() {\n\tconst data = useLoaderData<typeof loader>()\n\tconst [searchParams] = useSearchParams()\n\n\tconst preview = searchParams.get('preview')\n\tconst inBrowserBrowserRef = useRef<InBrowserBrowserRef>(null)\n\n\tconst altDown = useAltDown()\n\tconst navigate = useNavigate()\n\n\tfunction shouldHideTab(tab: (typeof tabs)[number]) {\n\t\tif (tab === 'tests') {\n\t\t\treturn (\n\t\t\t\tENV.EPICSHOP_DEPLOYED ||\n\t\t\t\t!data.playground ||\n\t\t\t\tdata.playground.test.type === 'none'\n\t\t\t)\n\t\t}\n\t\tif (tab === 'problem' || tab === 'solution') {\n\t\t\tif (data[tab]?.dev.type === 'none') return true\n\t\t\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\t\t\treturn data[tab]?.dev.type !== 'browser' && !data[tab]?.stackBlitzUrl\n\t\t\t}\n\t\t}\n\t\tif (tab === 'playground' && ENV.EPICSHOP_DEPLOYED) return true\n\t\treturn false\n\t}\n\n\tconst activeTab = isValidPreview(preview)\n\t\t? preview\n\t\t: tabs.find((t) => !shouldHideTab(t))\n\n\t// when alt is held down, the diff tab should open to the full-page diff view\n\t// between the problem and solution (this is more for the instructor than the student)\n\tconst altDiffUrl = `/diff?${new URLSearchParams({\n\t\tapp1: data.problem?.name ?? '',\n\t\tapp2: data.solution?.name ?? '',\n\t})}`\n\n\tfunction handleDiffTabClick(event: React.MouseEvent<HTMLAnchorElement>) {\n\t\tif (event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) {\n\t\t\tevent.preventDefault()\n\t\t\tnavigate(altDiffUrl)\n\t\t}\n\t}\n\n\treturn (\n\t\t<Tabs.Root\n\t\t\tclassName=\"relative flex flex-col overflow-y-auto sm:col-span-1 sm:row-span-1\"\n\t\t\tvalue={activeTab}\n\t\t\t// intentionally no onValueChange here because the Link will trigger the\n\t\t\t// change.\n\t\t>\n\t\t\t<Tabs.List className=\"h-14 min-h-14 overflow-x-hidden border-b scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t{tabs.map((tab) => {\n\t\t\t\t\tconst hidden = shouldHideTab(tab)\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Tabs.Trigger key={tab} value={tab} hidden={hidden} asChild>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tid={`${tab}-tab`}\n\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t'clip-path-button relative h-full px-6 py-4 font-mono text-sm uppercase outline-none radix-state-active:z-10 radix-state-active:bg-foreground radix-state-active:text-background radix-state-active:hover:bg-foreground/80 radix-state-active:hover:text-background/80 radix-state-inactive:hover:bg-foreground/20 radix-state-inactive:hover:text-foreground/80 focus:bg-foreground/80 focus:text-background/80',\n\t\t\t\t\t\t\t\t\thidden ? 'hidden' : 'inline-block',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tpreventScrollReset\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\tonClick={handleDiffTabClick}\n\t\t\t\t\t\t\t\tto={\n\t\t\t\t\t\t\t\t\ttab === 'diff' && altDown\n\t\t\t\t\t\t\t\t\t\t? altDiffUrl\n\t\t\t\t\t\t\t\t\t\t: `?${withParam(\n\t\t\t\t\t\t\t\t\t\t\t\tsearchParams,\n\t\t\t\t\t\t\t\t\t\t\t\t'preview',\n\t\t\t\t\t\t\t\t\t\t\t\ttab === 'playground' ? null : tab,\n\t\t\t\t\t\t\t\t\t\t\t)}`\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{tab}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t</Tabs.List>\n\t\t\t<div className=\"relative z-10 flex min-h-96 flex-grow flex-col overflow-y-auto\">\n\t\t\t\t<Tabs.Content\n\t\t\t\t\tvalue=\"playground\"\n\t\t\t\t\tclassName=\"flex w-full flex-grow items-center justify-center self-start radix-state-inactive:hidden\"\n\t\t\t\t>\n\t\t\t\t\t<Playground\n\t\t\t\t\t\tappInfo={data.playground}\n\t\t\t\t\t\tproblemAppName={data.problem?.name}\n\t\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t\t\tallApps={data.allApps}\n\t\t\t\t\t\tisUpToDate={data.playground?.isUpToDate ?? false}\n\t\t\t\t\t/>\n\t\t\t\t</Tabs.Content>\n\t\t\t\t<Tabs.Content\n\t\t\t\t\tvalue=\"problem\"\n\t\t\t\t\tclassName=\"flex w-full flex-grow items-center justify-center self-start radix-state-inactive:hidden\"\n\t\t\t\t>\n\t\t\t\t\t<Preview\n\t\t\t\t\t\tappInfo={data.problem}\n\t\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t\t/>\n\t\t\t\t</Tabs.Content>\n\t\t\t\t<Tabs.Content\n\t\t\t\t\tvalue=\"solution\"\n\t\t\t\t\tclassName=\"flex w-full flex-grow items-center justify-center self-start radix-state-inactive:hidden\"\n\t\t\t\t>\n\t\t\t\t\t<Preview\n\t\t\t\t\t\tappInfo={data.solution}\n\t\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t\t/>\n\t\t\t\t</Tabs.Content>\n\t\t\t\t<Tabs.Content\n\t\t\t\t\tvalue=\"tests\"\n\t\t\t\t\tclassName=\"flex w-full flex-grow items-start justify-center self-start overflow-hidden radix-state-inactive:hidden\"\n\t\t\t\t>\n\t\t\t\t\t<Tests\n\t\t\t\t\t\tappInfo={data.playground}\n\t\t\t\t\t\tproblemAppName={data.problem?.name}\n\t\t\t\t\t\tallApps={data.allApps}\n\t\t\t\t\t\tisUpToDate={data.playground?.isUpToDate ?? false}\n\t\t\t\t\t/>\n\t\t\t\t</Tabs.Content>\n\t\t\t\t<Tabs.Content\n\t\t\t\t\tvalue=\"diff\"\n\t\t\t\t\tclassName=\"flex h-full w-full flex-grow items-start justify-center self-start radix-state-inactive:hidden\"\n\t\t\t\t>\n\t\t\t\t\t<Diff diff={data.diff} allApps={data.allApps} />\n\t\t\t\t</Tabs.Content>\n\t\t\t\t<Tabs.Content\n\t\t\t\t\tvalue=\"chat\"\n\t\t\t\t\tclassName=\"flex h-full w-full flex-grow items-start justify-center self-start radix-state-inactive:hidden\"\n\t\t\t\t>\n\t\t\t\t\t<DiscordChat />\n\t\t\t\t</Tabs.Content>\n\t\t\t</div>\n\t\t</Tabs.Root>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn (\n\t\t<GeneralErrorBoundary\n\t\t\tstatusHandlers={{\n\t\t\t\t404: () => <p>Sorry, we couldn't find an app here.</p>,\n\t\t\t}}\n\t\t/>\n\t)\n}\n"],"names":["createContextScope","scopeName","createContextScopeDeps","defaultContexts","createContext3","rootComponentName","defaultContext","BaseContext","React.createContext","index","Provider","props","scope","children","context","Context","value","React.useMemo","jsx","useContext2","consumerName","React.useContext","createScope","scopeContexts","contexts","composeContextScopes","scopes","baseScope","scopeHooks","createScope2","overrideScopes","nextScopes","nextScopes2","useScope","currentScope","ENTRY_FOCUS","EVENT_OPTIONS","GROUP_NAME","Collection","useCollection","createCollectionScope","createCollection","createRovingFocusGroupContext","createRovingFocusGroupScope","RovingFocusProvider","useRovingFocusContext","RovingFocusGroup","React.forwardRef","forwardedRef","RovingFocusGroupImpl","__scopeRovingFocusGroup","orientation","loop","dir","currentTabStopIdProp","defaultCurrentTabStopId","onCurrentTabStopIdChange","onEntryFocus","preventScrollOnEntryFocus","groupProps","ref","React.useRef","composedRefs","useComposedRefs","direction","useDirection","currentTabStopId","setCurrentTabStopId","useControllableState","isTabbingBackOut","setIsTabbingBackOut","React.useState","handleEntryFocus","useCallbackRef","getItems","isClickFocusRef","focusableItemsCount","setFocusableItemsCount","React.useEffect","node","React.useCallback","tabStopId","prevCount","Primitive","composeEventHandlers","event","isKeyboardFocus","entryFocusEvent","items","item","activeItem","currentItem","candidateNodes","focusFirst","ITEM_NAME","RovingFocusGroupItem","focusable","active","itemProps","autoId","useId","id","isCurrentTabStop","onFocusableItemAdd","onFocusableItemRemove","focusIntent","getFocusIntent","currentIndex","wrapArray","MAP_KEY_TO_FOCUS_INTENT","getDirectionAwareKey","key","candidates","preventScroll","PREVIOUSLY_FOCUSED_ELEMENT","candidate","array","startIndex","_","Root","Item","TABS_NAME","createTabsContext","createTabsScope","useRovingFocusGroupScope","TabsProvider","useTabsContext","Tabs","__scopeTabs","valueProp","onValueChange","defaultValue","activationMode","tabsProps","setValue","TAB_LIST_NAME","TabsList","listProps","rovingFocusGroupScope","RovingFocusGroup.Root","TRIGGER_NAME","TabsTrigger","disabled","triggerProps","triggerId","makeTriggerId","contentId","makeContentId","isSelected","RovingFocusGroup.Item","isAutomaticActivation","CONTENT_NAME","TabsContent","forceMount","contentProps","isMountAnimationPreventedRef","rAF","Presence","present","baseId","Root2","List","Trigger","Content","DiscordChat","jsxs","DiscordCTA","DiscordPosts","data","useLoaderData","ctaLink","useDiscordCTALink","altDown","useAltDown","React.Suspense","Loading","Await","posts","post","DiscordPost","Link","e","Icon","thread","reactionsWithCounts","t","Emoji","i","name","url","Playground","playgroundAppInfo","inBrowserBrowserRef","problemAppName","allApps","isUpToDate","PlaygroundWindow","SimpleTooltip","showToast","Preview","SetAppToPlayground","tabs","isValidPreview","s","Boolean","includes","withParam","searchParams","newSearchParams","URLSearchParams","delete","set","ExercisePartRoute","useSearchParams","preview","get","useRef","navigate","useNavigate","shouldHideTab","tab","ENV","EPICSHOP_DEPLOYED","playground","test","type","dev","stackBlitzUrl","activeTab","find","altDiffUrl","app1","problem","app2","solution","handleDiffTabClick","altKey","ctrlKey","shiftKey","metaKey","preventDefault","className","map","hidden","asChild","clsx","preventScrollReset","prefetch","onClick","to","appInfo","Tests","Diff","diff","ErrorBoundary","GeneralErrorBoundary","statusHandlers"],"mappings":"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","x_google_ignoreList":[0,1,2]}
@@ -1,2 +0,0 @@
1
- import{j as e}from"./index-BFGhCX_U.js";import{E as t}from"./index-BCxBKsqT.js";import{E as a}from"./epic-video-Bp4BOD2R.js";import{G as i}from"./error-boundary-BZA-ffa8.js";import{M as l,E as m}from"./mdx-CEjzXoEx.js";import{a as n}from"./misc-DUy_whwE.js";import{P as d,u as c}from"./progress-DQt_Bn9o.js";import{u as p,L as x}from"./components-Be92gVxW.js";import"./index-Bdg3v8tC.js";import"./request-info-ByUEfOil.js";import"./tooltip-DO9uwurQ.js";import"./pe-ChIwTk8v.js";import"./loading-XhMtj4mp.js";import"./user-Bv6wYhQP.js";import"./workshop-config-WVltG_BV.js";import"./progress-bar-BaTU3Yx_.js";function h({exercise:r}){const s=c(r.exerciseNumber);return e.jsx("li",{children:e.jsxs(x,{className:n("relative flex items-center gap-4 px-4 py-3 text-lg font-semibold transition after:absolute after:right-10 after:-translate-x-2 after:opacity-0 after:transition after:content-['→'] hover:bg-gray-50 hover:after:translate-x-0 hover:after:opacity-100 dark:hover:bg-white/5",s),to:`${r.exerciseNumber.toString().padStart(2,"0")}`,children:[e.jsx("span",{className:"text-xs font-normal tabular-nums opacity-50",children:r.exerciseNumber}),e.jsx("span",{children:r.title})]})},r.exerciseNumber)}const f={h1:()=>null};function S(){const r=p(),s=e.jsxs("ul",{className:"flex flex-col divide-y divide-border dark:divide-border/50",children:[e.jsx("strong",{className:"px-10 pb-3 font-mono text-xs uppercase",children:"Exercises"}),r.exercises.map(o=>e.jsx(h,{exercise:o},o.exerciseNumber))]});return e.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:[e.jsxs("article",{id:r.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:[e.jsx("div",{children:e.jsx("h1",{className:"px-10 text-[clamp(3rem,6vw,7.5rem)] font-extrabold leading-none",children:r.title})}),e.jsxs("div",{className:"w-full max-w-none scroll-pt-6 border-t px-3 pt-3 md:px-10 md:pt-8",children:[e.jsx("h2",{className:"pb-5 font-mono text-xs font-semibold uppercase",children:"Intro"}),r.workshopReadme.compiled.status==="success"&&r.workshopReadme.compiled.code?e.jsx(a,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(l,{code:r.workshopReadme.compiled.code,components:f})})}):r.workshopReadme.compiled.status==="error"?e.jsxs("div",{className:"text-red-500",children:["There was an error:",e.jsx("pre",{children:r.workshopReadme.compiled.error})]}):"No instructions yet..."]}),e.jsx("div",{className:"pb-5 pt-10",children:r.workshopReadme.compiled.status==="success"&&r.workshopReadme.compiled.code&&r.workshopReadme.compiled.code.length>500?s:null})]}),e.jsx(t,{elementQuery:`#${r.articleId}`}),e.jsx(d,{type:"workshop-instructions",className:"h-14 border-t px-6"}),e.jsx("div",{className:"flex h-16 justify-center border-t",children:e.jsx(m,{file:r.workshopReadme.file,relativePath:r.workshopReadme.relativePath})})]})}function V(){return e.jsx(i,{})}export{V as ErrorBoundary,S as default};
2
- //# sourceMappingURL=index-Ca4vBON4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-Ca4vBON4.js","sources":["../../../app/routes/_app+/index.tsx"],"sourcesContent":["import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopInstructions,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport {\n\tunstable_data as data,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n\ttype SerializeFrom,\n} from '@remix-run/node'\nimport { Link, useLoaderData } from '@remix-run/react'\nimport slugify from '@sindresorhus/slugify'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { getEpicVideoInfos } from '#app/utils/epic-api.ts'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { ProgressToggle, useExerciseProgressClassName } from '../progress.tsx'\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('indexLoader')\n\tconst { title } = getWorkshopConfig()\n\tconst [exercises, workshopReadme] = await Promise.all([\n\t\ttime(() => getExercises({ request, timings }), {\n\t\t\ttimings,\n\t\t\ttype: 'getExercises',\n\t\t\tdesc: 'getExercises in index',\n\t\t}),\n\t\ttime(() => getWorkshopInstructions({ request }), {\n\t\t\ttimings,\n\t\t\ttype: 'compileMdx',\n\t\t\tdesc: 'compileMdx in index',\n\t\t}),\n\t])\n\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(title)}-instructions`,\n\t\t\ttitle:\n\t\t\t\tworkshopReadme.compiled.status === 'success'\n\t\t\t\t\t? workshopReadme.compiled.title\n\t\t\t\t\t: title,\n\t\t\texercises: exercises.map((e) => ({\n\t\t\t\texerciseNumber: e.exerciseNumber,\n\t\t\t\ttitle: e.title,\n\t\t\t})),\n\t\t\tworkshopReadme,\n\t\t\tepicVideoInfosPromise:\n\t\t\t\tworkshopReadme.compiled.status === 'success'\n\t\t\t\t\t? getEpicVideoInfos(workshopReadme.compiled.epicVideoEmbeds, {\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t})\n\t\t\t\t\t: null,\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\nfunction ExerciseListItem({\n\texercise,\n}: {\n\texercise: SerializeFrom<typeof loader>['exercises'][number]\n}) {\n\tconst progressClassName = useExerciseProgressClassName(\n\t\texercise.exerciseNumber,\n\t)\n\treturn (\n\t\t<li key={exercise.exerciseNumber}>\n\t\t\t<Link\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative flex items-center gap-4 px-4 py-3 text-lg font-semibold transition after:absolute after:right-10 after:-translate-x-2 after:opacity-0 after:transition after:content-['→'] hover:bg-gray-50 hover:after:translate-x-0 hover:after:opacity-100 dark:hover:bg-white/5\",\n\t\t\t\t\tprogressClassName,\n\t\t\t\t)}\n\t\t\t\tto={`${exercise.exerciseNumber.toString().padStart(2, '0')}`}\n\t\t\t>\n\t\t\t\t<span className=\"text-xs font-normal tabular-nums opacity-50\">\n\t\t\t\t\t{exercise.exerciseNumber}\n\t\t\t\t</span>\n\t\t\t\t<span>{exercise.title}</span>\n\t\t\t</Link>\n\t\t</li>\n\t)\n}\n\nconst mdxComponents = { h1: () => null }\n\nexport default function Index() {\n\tconst data = useLoaderData<typeof loader>()\n\n\tconst exerciseLinks = (\n\t\t<ul className=\"flex flex-col divide-y divide-border dark:divide-border/50\">\n\t\t\t<strong className=\"px-10 pb-3 font-mono text-xs uppercase\">\n\t\t\t\tExercises\n\t\t\t</strong>\n\t\t\t{data.exercises.map((exercise) => (\n\t\t\t\t<ExerciseListItem key={exercise.exerciseNumber} exercise={exercise} />\n\t\t\t))}\n\t\t</ul>\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\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=\"px-10 text-[clamp(3rem,6vw,7.5rem)] font-extrabold leading-none\">\n\t\t\t\t\t\t{data.title}\n\t\t\t\t\t</h1>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"w-full max-w-none scroll-pt-6 border-t px-3 pt-3 md:px-10 md:pt-8\">\n\t\t\t\t\t<h2 className=\"pb-5 font-mono text-xs font-semibold uppercase\">\n\t\t\t\t\t\tIntro\n\t\t\t\t\t</h2>\n\t\t\t\t\t{data.workshopReadme.compiled.status === 'success' &&\n\t\t\t\t\tdata.workshopReadme.compiled.code ? (\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.workshopReadme.compiled.code}\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) : data.workshopReadme.compiled.status === 'error' ? (\n\t\t\t\t\t\t<div className=\"text-red-500\">\n\t\t\t\t\t\t\tThere was an error:\n\t\t\t\t\t\t\t<pre>{data.workshopReadme.compiled.error}</pre>\n\t\t\t\t\t\t</div>\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\t<div className=\"pb-5 pt-10\">\n\t\t\t\t\t{data.workshopReadme.compiled.status === 'success' &&\n\t\t\t\t\tdata.workshopReadme.compiled.code &&\n\t\t\t\t\tdata.workshopReadme.compiled.code.length > 500\n\t\t\t\t\t\t? exerciseLinks\n\t\t\t\t\t\t: null}\n\t\t\t\t</div>\n\t\t\t</article>\n\t\t\t<ElementScrollRestoration elementQuery={`#${data.articleId}`} />\n\t\t\t<ProgressToggle\n\t\t\t\ttype=\"workshop-instructions\"\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-center border-t\">\n\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\tfile={data.workshopReadme.file}\n\t\t\t\t\trelativePath={data.workshopReadme.relativePath}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</main>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn <GeneralErrorBoundary />\n}\n"],"names":["ExerciseListItem","exercise","progressClassName","useExerciseProgressClassName","exerciseNumber","children","jsxs","Link","className","cn","to","toString","padStart","jsx","title","mdxComponents","h1","Index","data","useLoaderData","exerciseLinks","exercises","map","id","articleId","workshopReadme","compiled","status","code","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","components","error","length","ElementScrollRestoration","elementQuery","ProgressToggle","type","EditFileOnGitHub","file","relativePath","ErrorBoundary","GeneralErrorBoundary"],"mappings":"gmBA+EA,SAASA,EAAiB,CACzBC,SAAAA,CACD,EAEG,CACF,MAAMC,EAAoBC,EACzBF,EAASG,cACV,EACA,aACE,KACA,CAAAC,SAAAC,EAAA,KAACC,EAAA,CACAC,UAAWC,EACV,+QACAP,CACD,EACAQ,GAAI,GAAGT,EAASG,eAAeO,SAAW,EAAAC,SAAS,EAAG,GAAG,CAAC,GAE1DP,SAAA,CAAAQ,EAAA,IAAC,OAAK,CAAAL,UAAU,8CACdH,SAAAJ,EAASG,cACX,CAAA,EACAS,EAAA,IAAC,OAAM,CAAAR,SAAAJ,EAASa,KAAM,CAAA,CAAA,EACvB,CAAA,EAZQb,EAASG,cAalB,CAEF,CAEA,MAAMW,EAAgB,CAAEC,GAAIA,IAAM,IAAK,EAEvC,SAAwBC,GAAQ,CAC/B,MAAMC,EAAOC,IAEPC,EACLd,EAAA,KAAC,KAAG,CAAAE,UAAU,6DACbH,SAAA,CAACQ,EAAA,IAAA,SAAA,CAAOL,UAAU,yCAAyCH,SAE3D,WAAA,CAAA,EACCa,EAAKG,UAAUC,IAAKrB,SACnBD,EAA+C,CAAAC,SAAAA,CAAA,EAAzBA,EAASG,cAAoC,CACpE,CAAA,CACF,CAAA,EAGA,OAAAE,EAAAA,KAAC,OAAK,CAAAE,UAAU,4FACfH,SAAA,CAAAC,EAAA,KAAC,UAAA,CACAiB,GAAIL,EAAKM,UACThB,UAAU,8JAEVH,SAAA,CAACQ,EAAA,IAAA,MAAA,CACAR,eAAC,KAAG,CAAAG,UAAU,kEACZH,SAAAa,EAAKJ,MACP,CACD,CAAA,EACAR,EAAA,KAAC,MAAI,CAAAE,UAAU,oEACdH,SAAA,CAACQ,EAAA,IAAA,KAAA,CAAGL,UAAU,iDAAiDH,SAE/D,OAAA,CAAA,EACCa,EAAKO,eAAeC,SAASC,SAAW,WACzCT,EAAKO,eAAeC,SAASE,KAC5Bf,EAAAA,IAACgB,EAAA,CACAC,sBAAuBZ,EAAKY,sBAE5BzB,SAAAQ,EAAA,IAAC,MAAI,CAAAL,UAAU,sCACdH,SAAAQ,EAAA,IAACkB,EAAA,CACAH,KAAMV,EAAKO,eAAeC,SAASE,KACnCI,WAAYjB,EACb,EACD,CAAA,CACD,EACGG,EAAKO,eAAeC,SAASC,SAAW,QAC3CrB,EAAA,KAAC,MAAI,CAAAE,UAAU,eAAeH,SAAA,CAAA,4BAE5B,MAAK,CAAAA,SAAAa,EAAKO,eAAeC,SAASO,KAAM,CAAA,CAAA,CAC1C,CAAA,EAEA,wBAAA,CAEF,CAAA,EACApB,EAAA,IAAC,OAAIL,UAAU,aACbH,SAAAa,EAAKO,eAAeC,SAASC,SAAW,WACzCT,EAAKO,eAAeC,SAASE,MAC7BV,EAAKO,eAAeC,SAASE,KAAKM,OAAS,IACxCd,EACA,IACJ,CAAA,CAAA,CAAA,CACD,QACCe,EAAyB,CAAAC,aAAc,IAAIlB,EAAKM,SAAS,EAAI,CAAA,EAC9DX,EAAA,IAACwB,EAAA,CACAC,KAAK,wBACL9B,UAAU,oBAAA,CACX,EACAK,EAAA,IAAC,MAAI,CAAAL,UAAU,oCACdH,SAAAQ,EAAA,IAAC0B,EAAA,CACAC,KAAMtB,EAAKO,eAAee,KAC1BC,aAAcvB,EAAKO,eAAegB,aACnC,CACD,CAAA,CAAA,CACD,CAAA,CAEF,CAEO,SAASC,GAAgB,CAC/B,aAAQC,EAAqB,CAAA,CAAA,CAC9B"}
@@ -1 +0,0 @@
1
- window.__remixManifest={"entry":{"module":"/assets/entry.client-DqIWuxf8.js","imports":["/assets/index-BFGhCX_U.js","/assets/components-Be92gVxW.js"],"css":[]},"routes":{"root":{"id":"root","path":"","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":true,"module":"/assets/root-a3d3Qwip.js","imports":["/assets/index-BFGhCX_U.js","/assets/components-Be92gVxW.js","/assets/misc-DUy_whwE.js","/assets/pe-ChIwTk8v.js","/assets/error-boundary-BZA-ffa8.js","/assets/progress-bar-BaTU3Yx_.js","/assets/index-C9Hx0Dey.js","/assets/tooltip-DO9uwurQ.js","/assets/index-Bdg3v8tC.js","/assets/presence-DJGFvdDh.js","/assets/seo-pBpFCWsy.js","/assets/request-info-ByUEfOil.js"],"css":[]},"routes/$":{"id":"routes/$","parentId":"root","path":"*","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":true,"module":"/assets/_-BrkpfnBb.js","imports":["/assets/index-BFGhCX_U.js","/assets/error-boundary-BZA-ffa8.js","/assets/misc-DUy_whwE.js","/assets/components-Be92gVxW.js"],"css":[]},"routes/_app+/_layout":{"id":"routes/_app+/_layout","parentId":"root","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_layout-Cbz7Qt-S.js","imports":["/assets/index-BFGhCX_U.js","/assets/misc-DUy_whwE.js","/assets/pe-ChIwTk8v.js","/assets/product-DIAmCwmZ.js","/assets/revalidation-ws-dUa9CAqr.js","/assets/tooltip-DO9uwurQ.js","/assets/index-BCTr8uu6.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/presence-DJGFvdDh.js","/assets/progress-DQt_Bn9o.js","/assets/index-Bdg3v8tC.js","/assets/components-Be92gVxW.js","/assets/request-info-ByUEfOil.js"],"css":[]},"routes/_app+/account":{"id":"routes/_app+/account","parentId":"routes/_app+/_layout","path":"account","hasAction":true,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/account-C4Piztoz.js","imports":["/assets/index-BFGhCX_U.js","/assets/button-_qPvcoqR.js","/assets/misc-DUy_whwE.js","/assets/tooltip-DO9uwurQ.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/presence-DJGFvdDh.js","/assets/components-Be92gVxW.js","/assets/request-info-ByUEfOil.js"],"css":[]},"routes/_app+/app.$appName+/$":{"id":"routes/_app+/app.$appName+/$","parentId":"routes/_app+/_layout","path":"app/:appName/*","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/app.$appName+/api.$":{"id":"routes/_app+/app.$appName+/api.$","parentId":"routes/_app+/_layout","path":"app/:appName/api/*","hasAction":true,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/api._-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/app.$appName+/epic_ws[.js]":{"id":"routes/_app+/app.$appName+/epic_ws[.js]","parentId":"routes/_app+/_layout","path":"app/:appName/epic_ws.js","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/epic_ws_.js_-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/app.$appName+/index":{"id":"routes/_app+/app.$appName+/index","parentId":"routes/_app+/_layout","path":"app/:appName/","index":true,"hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/index-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/app.$appName+/test.$testName":{"id":"routes/_app+/app.$appName+/test.$testName","parentId":"routes/_app+/_layout","path":"app/:appName/test/:testName","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/test._testName-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/app.$appName+/test.epic_ws[.js]":{"id":"routes/_app+/app.$appName+/test.epic_ws[.js]","parentId":"routes/_app+/_layout","path":"app/:appName/test/epic_ws.js","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/test.epic_ws_.js_-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/app.epic_ws[.js]":{"id":"routes/_app+/app.epic_ws[.js]","parentId":"routes/_app+/_layout","path":"app/epic_ws.js","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/app.epic_ws_.js_-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/discord":{"id":"routes/_app+/discord","parentId":"routes/_app+/_layout","path":"discord","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/discord-Bdnx7fu-.js","imports":["/assets/discord-BUWZUTEC.js","/assets/index-BFGhCX_U.js","/assets/misc-DUy_whwE.js","/assets/components-Be92gVxW.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js"],"css":[]},"routes/_app+/exercise+/_layout":{"id":"routes/_app+/exercise+/_layout","parentId":"routes/_app+/_layout","path":"exercise","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_layout-88n0To1b.js","imports":["/assets/index-BFGhCX_U.js"],"css":[]},"routes/_app+/exercise+/$exerciseNumber":{"id":"routes/_app+/exercise+/$exerciseNumber","parentId":"routes/_app+/exercise+/_layout","path":":exerciseNumber","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":true,"module":"/assets/_exerciseNumber-DCSM0NCG.js","imports":["/assets/index-BFGhCX_U.js","/assets/index-BCxBKsqT.js","/assets/epic-video-Bp4BOD2R.js","/assets/revalidation-ws-dUa9CAqr.js","/assets/mdx-CEjzXoEx.js","/assets/progress-DQt_Bn9o.js","/assets/misc-DUy_whwE.js","/assets/seo-pBpFCWsy.js","/assets/components-Be92gVxW.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js","/assets/loading-XhMtj4mp.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/progress-bar-BaTU3Yx_.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/_app+/exercise+/$exerciseNumber_.$stepNumber":{"id":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber","parentId":"routes/_app+/exercise+/_layout","path":":exerciseNumber/:stepNumber","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":true,"module":"/assets/_exerciseNumber_._stepNumber-BIMJh_sg.js","imports":["/assets/index-BFGhCX_U.js","/assets/misc-DUy_whwE.js","/assets/components-Be92gVxW.js"],"css":[]},"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout":{"id":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout","parentId":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber","path":":type","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":true,"module":"/assets/_layout-DTAM9xh5.js","imports":["/assets/index-BFGhCX_U.js","/assets/index-BCxBKsqT.js","/assets/error-boundary-BZA-ffa8.js","/assets/nav-chevrons-DnR25VLp.js","/assets/revalidation-ws-dUa9CAqr.js","/assets/mdx-CEjzXoEx.js","/assets/progress-DQt_Bn9o.js","/assets/set-playground-CBHBA46B.js","/assets/seo-pBpFCWsy.js","/assets/misc-DUy_whwE.js","/assets/epic-video-Bp4BOD2R.js","/assets/tooltip-DO9uwurQ.js","/assets/request-info-ByUEfOil.js","/assets/components-Be92gVxW.js","/assets/index-BCTr8uu6.js","/assets/progress-bar-BaTU3Yx_.js","/assets/pe-ChIwTk8v.js","/assets/index-DZDhtMuq.js","/assets/index-Bdg3v8tC.js","/assets/loading-XhMtj4mp.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/app":{"id":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/app","parentId":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout","path":"app","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/app-DgTXXO8s.js","imports":["/assets/index-BFGhCX_U.js","/assets/preview-DaZd0wMb.js","/assets/components-Be92gVxW.js","/assets/misc-DUy_whwE.js","/assets/request-info-ByUEfOil.js","/assets/button-_qPvcoqR.js","/assets/loading-XhMtj4mp.js","/assets/index-Bdg3v8tC.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js","/assets/progress-bar-BaTU3Yx_.js"],"css":[]},"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/index":{"id":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/index","parentId":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout","index":true,"hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":true,"module":"/assets/index-Bi1TbRTj.js","imports":["/assets/index-BFGhCX_U.js","/assets/tooltip-DO9uwurQ.js","/assets/index-DZDhtMuq.js","/assets/misc-DUy_whwE.js","/assets/diff-8nlDkmpc.js","/assets/error-boundary-BZA-ffa8.js","/assets/loading-XhMtj4mp.js","/assets/discord-BUWZUTEC.js","/assets/components-Be92gVxW.js","/assets/index-C9Hx0Dey.js","/assets/set-playground-CBHBA46B.js","/assets/tests-DbuyD2cI.js","/assets/preview-DaZd0wMb.js","/assets/index-BCTr8uu6.js","/assets/accordion-D9-D-n9p.js","/assets/mdx-CEjzXoEx.js","/assets/epic-video-Bp4BOD2R.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/pe-ChIwTk8v.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/progress-bar-BaTU3Yx_.js","/assets/revalidation-ws-dUa9CAqr.js","/assets/use-event-source-x59d4R2Z.js","/assets/button-_qPvcoqR.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/test":{"id":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/test","parentId":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout","path":"test","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/test-DoKJvNug.js","imports":["/assets/index-BFGhCX_U.js","/assets/tests-DbuyD2cI.js","/assets/components-Be92gVxW.js","/assets/epic-video-Bp4BOD2R.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/misc-DUy_whwE.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js","/assets/loading-XhMtj4mp.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/accordion-D9-D-n9p.js","/assets/index-DZDhtMuq.js","/assets/index-BCTr8uu6.js","/assets/use-event-source-x59d4R2Z.js","/assets/set-playground-CBHBA46B.js","/assets/progress-bar-BaTU3Yx_.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.index":{"id":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber.index","parentId":"routes/_app+/exercise+/$exerciseNumber_.$stepNumber","index":true,"hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_exerciseNumber_._stepNumber.index-l0sNRNKZ.js","imports":[],"css":[]},"routes/_app+/exercise+/$exerciseNumber_.finished":{"id":"routes/_app+/exercise+/$exerciseNumber_.finished","parentId":"routes/_app+/exercise+/_layout","path":":exerciseNumber/finished","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_exerciseNumber_.finished-nbpk1ToO.js","imports":["/assets/index-BFGhCX_U.js","/assets/index-BCxBKsqT.js","/assets/epic-video-Bp4BOD2R.js","/assets/loading-XhMtj4mp.js","/assets/nav-chevrons-DnR25VLp.js","/assets/revalidation-ws-dUa9CAqr.js","/assets/mdx-CEjzXoEx.js","/assets/progress-DQt_Bn9o.js","/assets/misc-DUy_whwE.js","/assets/seo-pBpFCWsy.js","/assets/components-Be92gVxW.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/progress-bar-BaTU3Yx_.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/_app+/finished":{"id":"routes/_app+/finished","parentId":"routes/_app+/_layout","path":"finished","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/finished-C0cpfAFL.js","imports":["/assets/index-BFGhCX_U.js","/assets/index-BCxBKsqT.js","/assets/epic-video-Bp4BOD2R.js","/assets/loading-XhMtj4mp.js","/assets/nav-chevrons-DnR25VLp.js","/assets/revalidation-ws-dUa9CAqr.js","/assets/mdx-CEjzXoEx.js","/assets/misc-DUy_whwE.js","/assets/seo-pBpFCWsy.js","/assets/progress-DQt_Bn9o.js","/assets/components-Be92gVxW.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/progress-bar-BaTU3Yx_.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/_app+/index":{"id":"routes/_app+/index","parentId":"routes/_app+/_layout","index":true,"hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":true,"module":"/assets/index-Ca4vBON4.js","imports":["/assets/index-BFGhCX_U.js","/assets/index-BCxBKsqT.js","/assets/epic-video-Bp4BOD2R.js","/assets/error-boundary-BZA-ffa8.js","/assets/mdx-CEjzXoEx.js","/assets/misc-DUy_whwE.js","/assets/progress-DQt_Bn9o.js","/assets/components-Be92gVxW.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js","/assets/loading-XhMtj4mp.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/progress-bar-BaTU3Yx_.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/_app+/login":{"id":"routes/_app+/login","parentId":"routes/_app+/_layout","path":"login","hasAction":true,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/login-C1oOgi98.js","imports":["/assets/index-BFGhCX_U.js","/assets/use-event-source-x59d4R2Z.js","/assets/button-_qPvcoqR.js","/assets/loading-XhMtj4mp.js","/assets/product-DIAmCwmZ.js","/assets/workshop-config-WVltG_BV.js","/assets/request-info-ByUEfOil.js","/assets/components-Be92gVxW.js","/assets/misc-DUy_whwE.js","/assets/index-Bdg3v8tC.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js"],"css":[]},"routes/_app+/support":{"id":"routes/_app+/support","parentId":"routes/_app+/_layout","path":"support","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/support-CIz02V_r.js","imports":["/assets/index-BFGhCX_U.js","/assets/components-Be92gVxW.js"],"css":[]},"routes/admin+/_layout":{"id":"routes/admin+/_layout","parentId":"root","path":"admin","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_layout-Dfmv2zcn.js","imports":["/assets/index-BFGhCX_U.js","/assets/components-Be92gVxW.js"],"css":[]},"routes/admin+/apps":{"id":"routes/admin+/apps","parentId":"routes/admin+/_layout","path":"apps","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/apps-l0sNRNKZ.js","imports":[],"css":[]},"routes/admin+/cache":{"id":"routes/admin+/cache","parentId":"routes/admin+/_layout","path":"cache","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/cache-l0sNRNKZ.js","imports":[],"css":[]},"routes/admin+/index":{"id":"routes/admin+/index","parentId":"routes/admin+/_layout","index":true,"hasAction":true,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/index-pkiQppkK.js","imports":["/assets/index-BFGhCX_U.js","/assets/misc-DUy_whwE.js","/assets/tooltip-DO9uwurQ.js","/assets/progress-DQt_Bn9o.js","/assets/components-Be92gVxW.js","/assets/pe-ChIwTk8v.js"],"css":[]},"routes/admin+/version":{"id":"routes/admin+/version","parentId":"routes/admin+/_layout","path":"version","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/version-lxUUxt3s.js","imports":["/assets/index-BFGhCX_U.js","/assets/workshop-config-WVltG_BV.js","/assets/components-Be92gVxW.js"],"css":[]},"routes/apps":{"id":"routes/apps","parentId":"root","path":"apps","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/apps-DP2rzg_V.js","imports":[],"css":[]},"routes/diff":{"id":"routes/diff","parentId":"root","path":"diff","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/diff-BhRAIPKc.js","imports":["/assets/index-BFGhCX_U.js","/assets/misc-DUy_whwE.js","/assets/diff-8nlDkmpc.js","/assets/nav-chevrons-DnR25VLp.js","/assets/components-Be92gVxW.js","/assets/accordion-D9-D-n9p.js","/assets/tooltip-DO9uwurQ.js","/assets/index-DZDhtMuq.js","/assets/index-BCTr8uu6.js","/assets/mdx-CEjzXoEx.js","/assets/epic-video-Bp4BOD2R.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/pe-ChIwTk8v.js","/assets/loading-XhMtj4mp.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js","/assets/progress-bar-BaTU3Yx_.js","/assets/revalidation-ws-dUa9CAqr.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/exercises":{"id":"routes/exercises","parentId":"root","path":"exercises","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/exercises-l0sNRNKZ.js","imports":[],"css":[]},"routes/launch-editor":{"id":"routes/launch-editor","parentId":"root","path":"launch-editor","hasAction":true,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/launch-editor-l0sNRNKZ.js","imports":[],"css":[]},"routes/login-sse":{"id":"routes/login-sse","parentId":"root","path":"login-sse","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/login-sse-l0sNRNKZ.js","imports":[],"css":[]},"routes/og":{"id":"routes/og","parentId":"root","path":"og","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/og-l0sNRNKZ.js","imports":[],"css":[]},"routes/onboarding":{"id":"routes/onboarding","parentId":"root","path":"onboarding","hasAction":true,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/onboarding-C2YNq60k.js","imports":["/assets/index-BFGhCX_U.js","/assets/button-_qPvcoqR.js","/assets/epic-video-Bp4BOD2R.js","/assets/components-Be92gVxW.js","/assets/misc-DUy_whwE.js","/assets/index-Bdg3v8tC.js","/assets/request-info-ByUEfOil.js","/assets/tooltip-DO9uwurQ.js","/assets/pe-ChIwTk8v.js","/assets/loading-XhMtj4mp.js","/assets/user-Bv6wYhQP.js","/assets/workshop-config-WVltG_BV.js"],"css":["/assets/epic-video-DUnRvy1A.css"]},"routes/processes":{"id":"routes/processes","parentId":"root","path":"processes","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/processes-l0sNRNKZ.js","imports":[],"css":[]},"routes/progress":{"id":"routes/progress","parentId":"root","path":"progress","hasAction":true,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/progress-l0sNRNKZ.js","imports":[],"css":[]},"routes/robots[.]txt":{"id":"routes/robots[.]txt","parentId":"root","path":"robots.txt","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/robots_._txt-l0sNRNKZ.js","imports":[],"css":[]},"routes/set-playground":{"id":"routes/set-playground","parentId":"root","path":"set-playground","hasAction":true,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/set-playground-l0sNRNKZ.js","imports":[],"css":[]},"routes/sitemap[.]xml":{"id":"routes/sitemap[.]xml","parentId":"root","path":"sitemap.xml","hasAction":false,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/sitemap_._xml-l0sNRNKZ.js","imports":[],"css":[]},"routes/start":{"id":"routes/start","parentId":"root","path":"start","hasAction":true,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/start-l0sNRNKZ.js","imports":[],"css":[]},"routes/test":{"id":"routes/test","parentId":"root","path":"test","hasAction":true,"hasLoader":true,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/test-l0sNRNKZ.js","imports":[],"css":[]},"routes/theme/index":{"id":"routes/theme/index","parentId":"root","path":"theme","hasAction":true,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/index-DP2rzg_V.js","imports":[],"css":[]},"routes/video-player/index":{"id":"routes/video-player/index","parentId":"root","path":"video-player","hasAction":true,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/index-K6Dvbx-E.js","imports":[],"css":[]}},"url":"/assets/manifest-e5b2a6e1.js","version":"e5b2a6e1"};
@@ -1,2 +0,0 @@
1
- import{j as e}from"./index-BFGhCX_U.js";import{B as t}from"./button-_qPvcoqR.js";import{E as r,D as i}from"./epic-video-Bp4BOD2R.js";import{u as s,F as l}from"./components-Be92gVxW.js";import"./misc-DUy_whwE.js";import"./index-Bdg3v8tC.js";import"./request-info-ByUEfOil.js";import"./tooltip-DO9uwurQ.js";import"./pe-ChIwTk8v.js";import"./loading-XhMtj4mp.js";import"./user-Bv6wYhQP.js";import"./workshop-config-WVltG_BV.js";const w={getSitemapEntries:()=>null};function b(){const o=s();return e.jsxs("main",{className:"flex h-full w-full flex-col items-center justify-between gap-4",children:[e.jsxs("div",{className:"container flex h-full w-full max-w-5xl flex-1 flex-col items-center gap-4 overflow-y-scroll py-12 scrollbar-thin scrollbar-thumb-scrollbar",children:[e.jsx("h1",{className:"text-5xl",children:"Onboarding"}),e.jsx("p",{className:"text-xl",children:"Welcome to EpicWeb.dev!"}),e.jsxs("p",{className:"text-lg",children:["Before you get started, ",e.jsx("strong",{children:"you must watch the tour video"}),"! You're going to be spending a lot of time in here, so it's important you understand how to work effectively in this workshop"]}),e.jsx("div",{className:"w-[780px] max-w-full",children:e.jsx(r,{epicVideoInfosPromise:o.videoInfos,children:e.jsx(i,{url:o.onboardingVideo})})})]}),e.jsx(l,{method:"post",className:"pb-4",children:e.jsx(t,{name:"intent",value:"complete",varient:"primary",children:"I've watched it. Let's go!"})})]})}export{b as default,w as handle};
2
- //# sourceMappingURL=onboarding-C2YNq60k.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"onboarding-C2YNq60k.js","sources":["../../../app/routes/onboarding.tsx"],"sourcesContent":["import { invariantResponse } from '@epic-web/invariant'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport {\n\tgetAuthInfo,\n\tmarkOnboardingVideoWatched,\n} from '@epic-web/workshop-utils/db.server'\nimport { makeTimings } from '@epic-web/workshop-utils/timing.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport {\n\tunstable_data as data,\n\tredirect,\n\ttype ActionFunctionArgs,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n} from '@remix-run/node'\nimport { Form, useLoaderData } from '@remix-run/react'\nimport { Button } from '#app/components/button.tsx'\nimport {\n\tDeferredEpicVideo,\n\tEpicVideoInfoProvider,\n} from '#app/components/epic-video.tsx'\nimport { getEpicVideoInfos } from '#app/utils/epic-api.ts'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => null,\n}\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('onboarding')\n\n\tconst { onboardingVideo } = getWorkshopConfig()\n\tconst videoInfos = getEpicVideoInfos([onboardingVideo], { request, timings })\n\treturn data(\n\t\t{ onboardingVideo, videoInfos },\n\t\t{ headers: { 'Server-Timing': timings.toString() } },\n\t)\n}\n\nexport const headers: HeadersFunction = ({ loaderHeaders }) => {\n\tconst headers = {\n\t\t'Server-Timing': loaderHeaders.get('Server-Timing') ?? '',\n\t}\n\treturn headers\n}\n\nexport async function action({ request }: ActionFunctionArgs) {\n\tconst data = await request.formData()\n\tconst authInfo = await getAuthInfo()\n\tconst intent = data.get('intent')\n\tinvariantResponse(intent === 'complete', 'Invalid intent')\n\tconst { onboardingVideo } = getWorkshopConfig()\n\tawait markOnboardingVideoWatched(onboardingVideo)\n\n\tif (authInfo) throw redirect('/')\n\telse throw redirect('/login')\n}\n\nexport default function Onboarding() {\n\tconst data = useLoaderData<typeof loader>()\n\treturn (\n\t\t<main className=\"flex h-full w-full flex-col items-center justify-between gap-4\">\n\t\t\t<div className=\"container flex h-full w-full max-w-5xl flex-1 flex-col items-center gap-4 overflow-y-scroll py-12 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t<h1 className=\"text-5xl\">Onboarding</h1>\n\t\t\t\t<p className=\"text-xl\">Welcome to EpicWeb.dev!</p>\n\t\t\t\t<p className=\"text-lg\">\n\t\t\t\t\tBefore you get started, <strong>you must watch the tour video</strong>\n\t\t\t\t\t! You're going to be spending a lot of time in here, so it's important\n\t\t\t\t\tyou understand how to work effectively in this workshop\n\t\t\t\t</p>\n\t\t\t\t<div className=\"w-[780px] max-w-full\">\n\t\t\t\t\t<EpicVideoInfoProvider epicVideoInfosPromise={data.videoInfos}>\n\t\t\t\t\t\t<DeferredEpicVideo url={data.onboardingVideo} />\n\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<Form method=\"post\" className=\"pb-4\">\n\t\t\t\t<Button name=\"intent\" value=\"complete\" varient=\"primary\">\n\t\t\t\t\tI've watched it. Let's go!\n\t\t\t\t</Button>\n\t\t\t</Form>\n\t\t</main>\n\t)\n}\n"],"names":["handle","getSitemapEntries","Onboarding","data","useLoaderData","jsxs","className","children","jsx","EpicVideoInfoProvider","epicVideoInfosPromise","videoInfos","DeferredEpicVideo","url","onboardingVideo","Form","method","Button","name","value","varient"],"mappings":"yaAuBO,MAAMA,EAAoB,CAChCC,kBAAmBA,IAAM,IAC1B,EAgCA,SAAwBC,GAAa,CACpC,MAAMC,EAAOC,IAEZ,OAAAC,EAAAA,KAAC,OAAK,CAAAC,UAAU,iEACfC,SAAA,CAACF,EAAA,KAAA,MAAA,CAAIC,UAAU,6IACdC,SAAA,CAACC,EAAA,IAAA,KAAA,CAAGF,UAAU,WAAWC,SAAU,YAAA,CAAA,EAClCC,EAAA,IAAA,IAAA,CAAEF,UAAU,UAAUC,SAAuB,yBAAA,CAAA,EAC9CF,EAAA,KAAC,IAAE,CAAAC,UAAU,UAAUC,SAAA,CAAA,2BACEC,EAAA,IAAC,UAAOD,SAA6B,+BAAA,CAAA,EAAS,gIAAA,CAGvE,CAAA,EACCC,EAAA,IAAA,MAAA,CAAIF,UAAU,uBACdC,eAACE,EAAsB,CAAAC,sBAAuBP,EAAKQ,WAClDJ,eAACK,EAAkB,CAAAC,IAAKV,EAAKW,gBAAiB,EAC/C,CACD,CAAA,CAAA,CACD,CAAA,EACCN,EAAA,IAAAO,EAAA,CAAKC,OAAO,OAAOV,UAAU,OAC7BC,SAAAC,EAAA,IAACS,EAAO,CAAAC,KAAK,SAASC,MAAM,WAAWC,QAAQ,UAAUb,sCAEzD,CACD,CAAA,CAAA,CACD,CAAA,CAEF"}
@@ -1,28 +0,0 @@
1
- var it=Object.defineProperty;var ct=(e,n,t)=>n in e?it(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t;var p=(e,n,t)=>ct(e,typeof n!="symbol"?n+"":n,t);import{n as te,r as x,j as at,b as ut}from"./index-BFGhCX_U.js";import{z as d,u as lt}from"./request-info-ByUEfOil.js";import{c as q}from"./components-Be92gVxW.js";const ae="epic-web-presence",ht=`https://epic-web-presence.kentcdodds.partykit.dev/parties/main/${ae}`,V=d.object({id:d.string(),hasAccess:d.boolean().nullable().optional(),avatarUrl:d.string().nullable().optional(),imageUrlSmall:d.string().nullable().optional(),imageUrlLarge:d.string().nullable().optional(),name:d.string().nullable().optional(),location:d.object({workshopTitle:d.string().nullable().optional(),origin:d.string().nullable().optional(),exercise:d.object({type:d.union([d.literal("problem"),d.literal("solution")]).nullable().optional(),exerciseNumber:d.number().nullable().optional(),stepNumber:d.number().nullable().optional()}).nullable().optional()}).nullable().optional()}),ft=d.object({type:d.literal("remove-user"),payload:d.object({id:d.string()})}).or(d.object({type:d.literal("add-user"),payload:V})).or(d.object({type:d.literal("presence"),payload:d.object({users:d.array(V)})}));d.object({users:d.array(V)});var B={},_={},S={};Object.defineProperty(S,"__esModule",{value:!0});S.isBytes=le;S.number=G;S.bool=ue;S.bytes=J;S.hash=he;S.exists=fe;S.output=de;function G(e){if(!Number.isSafeInteger(e)||e<0)throw new Error(`positive integer expected, not ${e}`)}function ue(e){if(typeof e!="boolean")throw new Error(`boolean expected, not ${e}`)}function le(e){return e instanceof Uint8Array||e!=null&&typeof e=="object"&&e.constructor.name==="Uint8Array"}function J(e,...n){if(!le(e))throw new Error("Uint8Array expected");if(n.length>0&&!n.includes(e.length))throw new Error(`Uint8Array expected of length ${n}, not of length=${e.length}`)}function he(e){if(typeof e!="function"||typeof e.create!="function")throw new Error("Hash should be wrapped by utils.wrapConstructor");G(e.outputLen),G(e.blockLen)}function fe(e,n=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(n&&e.finished)throw new Error("Hash#digest() has already been called")}function de(e,n){J(e);const t=n.outputLen;if(e.length<t)throw new Error(`digestInto() expects output buffer of length at least ${t}`)}const dt={number:G,bool:ue,bytes:J,hash:he,exists:fe,output:de};S.default=dt;var u={};Object.defineProperty(u,"__esModule",{value:!0});u.add5L=u.add5H=u.add4H=u.add4L=u.add3H=u.add3L=u.rotlBL=u.rotlBH=u.rotlSL=u.rotlSH=u.rotr32L=u.rotr32H=u.rotrBL=u.rotrBH=u.rotrSL=u.rotrSH=u.shrSL=u.shrSH=u.toBig=void 0;u.fromBig=Y;u.split=pe;u.add=Oe;const $=BigInt(2**32-1),K=BigInt(32);function Y(e,n=!1){return n?{h:Number(e&$),l:Number(e>>K&$)}:{h:Number(e>>K&$)|0,l:Number(e&$)|0}}function pe(e,n=!1){let t=new Uint32Array(e.length),s=new Uint32Array(e.length);for(let r=0;r<e.length;r++){const{h:i,l:c}=Y(e[r],n);[t[r],s[r]]=[i,c]}return[t,s]}const ye=(e,n)=>BigInt(e>>>0)<<K|BigInt(n>>>0);u.toBig=ye;const _e=(e,n,t)=>e>>>t;u.shrSH=_e;const ge=(e,n,t)=>e<<32-t|n>>>t;u.shrSL=ge;const me=(e,n,t)=>e>>>t|n<<32-t;u.rotrSH=me;const be=(e,n,t)=>e<<32-t|n>>>t;u.rotrSL=be;const we=(e,n,t)=>e<<64-t|n>>>t-32;u.rotrBH=we;const Le=(e,n,t)=>e>>>t-32|n<<64-t;u.rotrBL=Le;const ke=(e,n)=>n;u.rotr32H=ke;const xe=(e,n)=>e;u.rotr32L=xe;const ve=(e,n,t)=>e<<t|n>>>32-t;u.rotlSH=ve;const Ee=(e,n,t)=>n<<t|e>>>32-t;u.rotlSL=Ee;const Se=(e,n,t)=>n<<t-32|e>>>64-t;u.rotlBH=Se;const Te=(e,n,t)=>e<<t-32|n>>>64-t;u.rotlBL=Te;function Oe(e,n,t,s){const r=(n>>>0)+(s>>>0);return{h:e+t+(r/2**32|0)|0,l:r|0}}const Ce=(e,n,t)=>(e>>>0)+(n>>>0)+(t>>>0);u.add3L=Ce;const Ie=(e,n,t,s)=>n+t+s+(e/2**32|0)|0;u.add3H=Ie;const Be=(e,n,t,s)=>(e>>>0)+(n>>>0)+(t>>>0)+(s>>>0);u.add4L=Be;const Ue=(e,n,t,s,r)=>n+t+s+r+(e/2**32|0)|0;u.add4H=Ue;const Ae=(e,n,t,s,r)=>(e>>>0)+(n>>>0)+(t>>>0)+(s>>>0)+(r>>>0);u.add5L=Ae;const Ne=(e,n,t,s,r,i)=>n+t+s+r+i+(e/2**32|0)|0;u.add5H=Ne;const pt={fromBig:Y,split:pe,toBig:ye,shrSH:_e,shrSL:ge,rotrSH:me,rotrSL:be,rotrBH:we,rotrBL:Le,rotr32H:ke,rotr32L:xe,rotlSH:ve,rotlSL:Ee,rotlBH:Se,rotlBL:Te,add:Oe,add3L:Ce,add3H:Ie,add4L:Be,add4H:Ue,add5H:Ne,add5L:Ae};u.default=pt;var Pe={},X={};Object.defineProperty(X,"__esModule",{value:!0});X.crypto=void 0;X.crypto=typeof globalThis=="object"&&"crypto"in globalThis?globalThis.crypto:void 0;(function(e){/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */Object.defineProperty(e,"__esModule",{value:!0}),e.Hash=e.nextTick=e.byteSwapIfBE=e.byteSwap=e.isLE=e.rotl=e.rotr=e.createView=e.u32=e.u8=void 0,e.isBytes=s,e.byteSwap32=y,e.bytesToHex=v,e.hexToBytes=C,e.asyncLoop=I,e.utf8ToBytes=T,e.toBytes=D,e.concatBytes=Je,e.checkOpts=et,e.wrapConstructor=tt,e.wrapConstructorWithOpts=nt,e.wrapXOFConstructorWithOpts=st,e.randomBytes=rt;const n=X,t=S;function s(o){return o instanceof Uint8Array||o!=null&&typeof o=="object"&&o.constructor.name==="Uint8Array"}const r=o=>new Uint8Array(o.buffer,o.byteOffset,o.byteLength);e.u8=r;const i=o=>new Uint32Array(o.buffer,o.byteOffset,Math.floor(o.byteLength/4));e.u32=i;const c=o=>new DataView(o.buffer,o.byteOffset,o.byteLength);e.createView=c;const a=(o,l)=>o<<32-l|o>>>l;e.rotr=a;const h=(o,l)=>o<<l|o>>>32-l>>>0;e.rotl=h,e.isLE=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;const f=o=>o<<24&4278190080|o<<8&16711680|o>>>8&65280|o>>>24&255;e.byteSwap=f,e.byteSwapIfBE=e.isLE?o=>o:o=>(0,e.byteSwap)(o);function y(o){for(let l=0;l<o.length;l++)o[l]=(0,e.byteSwap)(o[l])}const L=Array.from({length:256},(o,l)=>l.toString(16).padStart(2,"0"));function v(o){(0,t.bytes)(o);let l="";for(let b=0;b<o.length;b++)l+=L[o[b]];return l}const m={_0:48,_9:57,_A:65,_F:70,_a:97,_f:102};function E(o){if(o>=m._0&&o<=m._9)return o-m._0;if(o>=m._A&&o<=m._F)return o-(m._A-10);if(o>=m._a&&o<=m._f)return o-(m._a-10)}function C(o){if(typeof o!="string")throw new Error("hex string expected, got "+typeof o);const l=o.length,b=l/2;if(l%2)throw new Error("padded hex string expected, got unpadded hex of length "+l);const g=new Uint8Array(b);for(let w=0,k=0;w<b;w++,k+=2){const Z=E(o.charCodeAt(k)),ee=E(o.charCodeAt(k+1));if(Z===void 0||ee===void 0){const ot=o[k]+o[k+1];throw new Error('hex string expected, got non-hex character "'+ot+'" at index '+k)}g[w]=Z*16+ee}return g}const j=async()=>{};e.nextTick=j;async function I(o,l,b){let g=Date.now();for(let w=0;w<o;w++){b(w);const k=Date.now()-g;k>=0&&k<l||(await(0,e.nextTick)(),g+=k)}}function T(o){if(typeof o!="string")throw new Error(`utf8ToBytes expected string, got ${typeof o}`);return new Uint8Array(new TextEncoder().encode(o))}function D(o){return typeof o=="string"&&(o=T(o)),(0,t.bytes)(o),o}function Je(...o){let l=0;for(let g=0;g<o.length;g++){const w=o[g];(0,t.bytes)(w),l+=w.length}const b=new Uint8Array(l);for(let g=0,w=0;g<o.length;g++){const k=o[g];b.set(k,w),w+=k.length}return b}class Ye{clone(){return this._cloneInto()}}e.Hash=Ye;const Ze={}.toString;function et(o,l){if(l!==void 0&&Ze.call(l)!=="[object Object]")throw new Error("Options should be object or undefined");return Object.assign(o,l)}function tt(o){const l=g=>o().update(D(g)).digest(),b=o();return l.outputLen=b.outputLen,l.blockLen=b.blockLen,l.create=()=>o(),l}function nt(o){const l=(g,w)=>o(w).update(D(g)).digest(),b=o({});return l.outputLen=b.outputLen,l.blockLen=b.blockLen,l.create=g=>o(g),l}function st(o){const l=(g,w)=>o(w).update(D(g)).digest(),b=o({});return l.outputLen=b.outputLen,l.blockLen=b.blockLen,l.create=g=>o(g),l}function rt(o=32){if(n.crypto&&typeof n.crypto.getRandomValues=="function")return n.crypto.getRandomValues(new Uint8Array(o));if(n.crypto&&typeof n.crypto.randomBytes=="function")return n.crypto.randomBytes(o);throw new Error("crypto.getRandomValues must be defined")}})(Pe);Object.defineProperty(_,"__esModule",{value:!0});_.shake256=_.shake128=_.keccak_512=_.keccak_384=_.keccak_256=_.keccak_224=_.sha3_512=_.sha3_384=_.sha3_256=_.sha3_224=_.Keccak=void 0;_.keccakP=We;const P=S,M=u,O=Pe,He=[],Re=[],Me=[],yt=BigInt(0),H=BigInt(1),_t=BigInt(2),gt=BigInt(7),mt=BigInt(256),bt=BigInt(113);for(let e=0,n=H,t=1,s=0;e<24;e++){[t,s]=[s,(2*t+3*s)%5],He.push(2*(5*s+t)),Re.push((e+1)*(e+2)/2%64);let r=yt;for(let i=0;i<7;i++)n=(n<<H^(n>>gt)*bt)%mt,n&_t&&(r^=H<<(H<<BigInt(i))-H);Me.push(r)}const[wt,Lt]=(0,M.split)(Me,!0),ne=(e,n,t)=>t>32?(0,M.rotlBH)(e,n,t):(0,M.rotlSH)(e,n,t),se=(e,n,t)=>t>32?(0,M.rotlBL)(e,n,t):(0,M.rotlSL)(e,n,t);function We(e,n=24){const t=new Uint32Array(10);for(let s=24-n;s<24;s++){for(let c=0;c<10;c++)t[c]=e[c]^e[c+10]^e[c+20]^e[c+30]^e[c+40];for(let c=0;c<10;c+=2){const a=(c+8)%10,h=(c+2)%10,f=t[h],y=t[h+1],L=ne(f,y,1)^t[a],v=se(f,y,1)^t[a+1];for(let m=0;m<50;m+=10)e[c+m]^=L,e[c+m+1]^=v}let r=e[2],i=e[3];for(let c=0;c<24;c++){const a=Re[c],h=ne(r,i,a),f=se(r,i,a),y=He[c];r=e[y],i=e[y+1],e[y]=h,e[y+1]=f}for(let c=0;c<50;c+=10){for(let a=0;a<10;a++)t[a]=e[c+a];for(let a=0;a<10;a++)e[c+a]^=~t[(a+2)%10]&t[(a+4)%10]}e[0]^=wt[s],e[1]^=Lt[s]}t.fill(0)}class W extends O.Hash{constructor(n,t,s,r=!1,i=24){if(super(),this.blockLen=n,this.suffix=t,this.outputLen=s,this.enableXOF=r,this.rounds=i,this.pos=0,this.posOut=0,this.finished=!1,this.destroyed=!1,(0,P.number)(s),0>=this.blockLen||this.blockLen>=200)throw new Error("Sha3 supports only keccak-f1600 function");this.state=new Uint8Array(200),this.state32=(0,O.u32)(this.state)}keccak(){O.isLE||(0,O.byteSwap32)(this.state32),We(this.state32,this.rounds),O.isLE||(0,O.byteSwap32)(this.state32),this.posOut=0,this.pos=0}update(n){(0,P.exists)(this);const{blockLen:t,state:s}=this;n=(0,O.toBytes)(n);const r=n.length;for(let i=0;i<r;){const c=Math.min(t-this.pos,r-i);for(let a=0;a<c;a++)s[this.pos++]^=n[i++];this.pos===t&&this.keccak()}return this}finish(){if(this.finished)return;this.finished=!0;const{state:n,suffix:t,pos:s,blockLen:r}=this;n[s]^=t,t&128&&s===r-1&&this.keccak(),n[r-1]^=128,this.keccak()}writeInto(n){(0,P.exists)(this,!1),(0,P.bytes)(n),this.finish();const t=this.state,{blockLen:s}=this;for(let r=0,i=n.length;r<i;){this.posOut>=s&&this.keccak();const c=Math.min(s-this.posOut,i-r);n.set(t.subarray(this.posOut,this.posOut+c),r),this.posOut+=c,r+=c}return n}xofInto(n){if(!this.enableXOF)throw new Error("XOF is not possible for this instance");return this.writeInto(n)}xof(n){return(0,P.number)(n),this.xofInto(new Uint8Array(n))}digestInto(n){if((0,P.output)(n,this),this.finished)throw new Error("digest() was already called");return this.writeInto(n),this.destroy(),n}digest(){return this.digestInto(new Uint8Array(this.outputLen))}destroy(){this.destroyed=!0,this.state.fill(0)}_cloneInto(n){const{blockLen:t,suffix:s,outputLen:r,rounds:i,enableXOF:c}=this;return n||(n=new W(t,s,r,c,i)),n.state32.set(this.state32),n.pos=this.pos,n.posOut=this.posOut,n.finished=this.finished,n.rounds=i,n.suffix=s,n.outputLen=r,n.enableXOF=c,n.destroyed=this.destroyed,n}}_.Keccak=W;const U=(e,n,t)=>(0,O.wrapConstructor)(()=>new W(n,e,t));_.sha3_224=U(6,144,224/8);_.sha3_256=U(6,136,256/8);_.sha3_384=U(6,104,384/8);_.sha3_512=U(6,72,512/8);_.keccak_224=U(1,144,224/8);_.keccak_256=U(1,136,256/8);_.keccak_384=U(1,104,384/8);_.keccak_512=U(1,72,512/8);const je=(e,n,t)=>(0,O.wrapXOFConstructorWithOpts)((s={})=>new W(n,e,s.dkLen===void 0?t:s.dkLen,!0));_.shake128=je(31,168,128/8);_.shake256=je(31,136,256/8);const{sha3_512:kt}=_,De=24,R=32,z=(e=4,n=Math.random)=>{let t="";for(;t.length<e;)t=t+Math.floor(n()*36).toString(36);return t};function $e(e){let n=8n,t=0n;for(const s of e.values()){const r=BigInt(s);t=(t<<n)+r}return t}const Fe=(e="")=>$e(kt(e)).toString(36).slice(1),re=Array.from({length:26},(e,n)=>String.fromCharCode(n+97)),xt=e=>re[Math.floor(e()*re.length)],qe=({globalObj:e=typeof te<"u"?te:typeof window<"u"?window:{},random:n=Math.random}={})=>{const t=Object.keys(e).toString(),s=t.length?t+z(R,n):z(R,n);return Fe(s).substring(0,R)},Ge=e=>()=>e++,vt=476782367,Xe=({random:e=Math.random,counter:n=Ge(Math.floor(e()*vt)),length:t=De,fingerprint:s=qe({random:e})}={})=>function(){const i=xt(e),c=Date.now().toString(36),a=n().toString(36),h=z(t,e),f=`${c+h+a+s}`;return`${i+Fe(f).substring(1,t)}`},Et=Xe(),St=(e,{minLength:n=2,maxLength:t=R}={})=>{const s=e.length,r=/^[0-9a-z]+$/;try{if(typeof e=="string"&&s>=n&&s<=t&&r.test(e))return!0}finally{}return!1};B.getConstants=()=>({defaultLength:De,bigLength:R});B.init=Xe;B.createId=Et;B.bufToBigInt=$e;B.createCounter=Ge;B.createFingerprint=qe;B.isCuid=St;const{createId:Tt,init:zt,getConstants:Jt,isCuid:Yt}=B;var Ot=Tt;(!globalThis.EventTarget||!globalThis.Event)&&console.error(`
2
- PartySocket requires a global 'EventTarget' class to be available!
3
- You can polyfill this global by adding this to your code before any partysocket imports:
4
-
5
- \`\`\`
6
- import 'partysocket/event-target-polyfill';
7
- \`\`\`
8
- Please file an issue at https://github.com/partykit/partykit if you're still having trouble.
9
- `);var Qe=class extends Event{constructor(n,t){super("error",t);p(this,"message");p(this,"error");this.message=n.message,this.error=n}},Ve=class extends Event{constructor(n=1e3,t="",s){super("close",s);p(this,"code");p(this,"reason");p(this,"wasClean",!0);this.code=n,this.reason=t}},Q={Event,ErrorEvent:Qe,CloseEvent:Ve};function Ct(e,n){if(!e)throw new Error(n)}function It(e){return new e.constructor(e.type,e)}function Bt(e){return"data"in e?new MessageEvent(e.type,e):"code"in e||"reason"in e?new Ve(e.code||1999,e.reason||"unknown reason",e):"error"in e?new Qe(e.error,e):new Event(e.type,e)}var ce,Ut=typeof process<"u"&&typeof((ce=process.versions)==null?void 0:ce.node)<"u"&&typeof document>"u",F=Ut?Bt:It,A={maxReconnectionDelay:1e4,minReconnectionDelay:1e3+Math.random()*4e3,minUptime:5e3,reconnectionDelayGrowFactor:1.3,connectionTimeout:4e3,maxRetries:1/0,maxEnqueuedMessages:1/0,startClosed:!1,debug:!1},oe=!1,At=class N extends EventTarget{constructor(t,s,r={}){super();p(this,"_ws");p(this,"_retryCount",-1);p(this,"_uptimeTimeout");p(this,"_connectTimeout");p(this,"_shouldReconnect",!0);p(this,"_connectLock",!1);p(this,"_binaryType","blob");p(this,"_closeCalled",!1);p(this,"_messageQueue",[]);p(this,"_debugLogger",console.log.bind(console));p(this,"_url");p(this,"_protocols");p(this,"_options");p(this,"onclose",null);p(this,"onerror",null);p(this,"onmessage",null);p(this,"onopen",null);p(this,"_handleOpen",t=>{this._debug("open event");const{minUptime:s=A.minUptime}=this._options;clearTimeout(this._connectTimeout),this._uptimeTimeout=setTimeout(()=>this._acceptOpen(),s),Ct(this._ws,"WebSocket is not defined"),this._ws.binaryType=this._binaryType,this._messageQueue.forEach(r=>{var i;return(i=this._ws)==null?void 0:i.send(r)}),this._messageQueue=[],this.onopen&&this.onopen(t),this.dispatchEvent(F(t))});p(this,"_handleMessage",t=>{this._debug("message event"),this.onmessage&&this.onmessage(t),this.dispatchEvent(F(t))});p(this,"_handleError",t=>{this._debug("error event",t.message),this._disconnect(void 0,t.message==="TIMEOUT"?"timeout":void 0),this.onerror&&this.onerror(t),this._debug("exec error listeners"),this.dispatchEvent(F(t)),this._connect()});p(this,"_handleClose",t=>{this._debug("close event"),this._clearTimeouts(),this._shouldReconnect&&this._connect(),this.onclose&&this.onclose(t),this.dispatchEvent(F(t))});this._url=t,this._protocols=s,this._options=r,this._options.startClosed&&(this._shouldReconnect=!1),this._options.debugLogger&&(this._debugLogger=this._options.debugLogger),this._connect()}static get CONNECTING(){return 0}static get OPEN(){return 1}static get CLOSING(){return 2}static get CLOSED(){return 3}get CONNECTING(){return N.CONNECTING}get OPEN(){return N.OPEN}get CLOSING(){return N.CLOSING}get CLOSED(){return N.CLOSED}get binaryType(){return this._ws?this._ws.binaryType:this._binaryType}set binaryType(t){this._binaryType=t,this._ws&&(this._ws.binaryType=t)}get retryCount(){return Math.max(this._retryCount,0)}get bufferedAmount(){return this._messageQueue.reduce((s,r)=>(typeof r=="string"?s+=r.length:r instanceof Blob?s+=r.size:s+=r.byteLength,s),0)+(this._ws?this._ws.bufferedAmount:0)}get extensions(){return this._ws?this._ws.extensions:""}get protocol(){return this._ws?this._ws.protocol:""}get readyState(){return this._ws?this._ws.readyState:this._options.startClosed?N.CLOSED:N.CONNECTING}get url(){return this._ws?this._ws.url:""}get shouldReconnect(){return this._shouldReconnect}close(t=1e3,s){if(this._closeCalled=!0,this._shouldReconnect=!1,this._clearTimeouts(),!this._ws){this._debug("close enqueued: no ws instance");return}if(this._ws.readyState===this.CLOSED){this._debug("close: already closed");return}this._ws.close(t,s)}reconnect(t,s){this._shouldReconnect=!0,this._closeCalled=!1,this._retryCount=-1,!this._ws||this._ws.readyState===this.CLOSED?this._connect():(this._disconnect(t,s),this._connect())}send(t){if(this._ws&&this._ws.readyState===this.OPEN)this._debug("send",t),this._ws.send(t);else{const{maxEnqueuedMessages:s=A.maxEnqueuedMessages}=this._options;this._messageQueue.length<s&&(this._debug("enqueue",t),this._messageQueue.push(t))}}_debug(...t){this._options.debug&&this._debugLogger("RWS>",...t)}_getNextDelay(){const{reconnectionDelayGrowFactor:t=A.reconnectionDelayGrowFactor,minReconnectionDelay:s=A.minReconnectionDelay,maxReconnectionDelay:r=A.maxReconnectionDelay}=this._options;let i=0;return this._retryCount>0&&(i=s*Math.pow(t,this._retryCount-1),i>r&&(i=r)),this._debug("next delay",i),i}_wait(){return new Promise(t=>{setTimeout(t,this._getNextDelay())})}_getNextProtocols(t){if(!t)return Promise.resolve(null);if(typeof t=="string"||Array.isArray(t))return Promise.resolve(t);if(typeof t=="function"){const s=t();if(!s)return Promise.resolve(null);if(typeof s=="string"||Array.isArray(s))return Promise.resolve(s);if(s.then)return s}throw Error("Invalid protocols")}_getNextUrl(t){if(typeof t=="string")return Promise.resolve(t);if(typeof t=="function"){const s=t();if(typeof s=="string")return Promise.resolve(s);if(s.then)return s}throw Error("Invalid URL")}_connect(){if(this._connectLock||!this._shouldReconnect)return;this._connectLock=!0;const{maxRetries:t=A.maxRetries,connectionTimeout:s=A.connectionTimeout}=this._options;if(this._retryCount>=t){this._debug("max retries reached",this._retryCount,">=",t);return}this._retryCount++,this._debug("connect",this._retryCount),this._removeListeners(),this._wait().then(()=>Promise.all([this._getNextUrl(this._url),this._getNextProtocols(this._protocols||null)])).then(([r,i])=>{if(this._closeCalled){this._connectLock=!1;return}!this._options.WebSocket&&typeof WebSocket>"u"&&!oe&&(console.error(`‼️ No WebSocket implementation available. You should define options.WebSocket.
10
-
11
- For example, if you're using node.js, run \`npm install ws\`, and then in your code:
12
-
13
- import PartySocket from 'partysocket';
14
- import WS from 'ws';
15
-
16
- const partysocket = new PartySocket({
17
- host: "127.0.0.1:1999",
18
- room: "test-room",
19
- WebSocket: WS
20
- });
21
-
22
- `),oe=!0);const c=this._options.WebSocket||WebSocket;this._debug("connect",{url:r,protocols:i}),this._ws=i?new c(r,i):new c(r),this._ws.binaryType=this._binaryType,this._connectLock=!1,this._addListeners(),this._connectTimeout=setTimeout(()=>this._handleTimeout(),s)}).catch(r=>{this._connectLock=!1,this._handleError(new Q.ErrorEvent(Error(r.message),this))})}_handleTimeout(){this._debug("timeout event"),this._handleError(new Q.ErrorEvent(Error("TIMEOUT"),this))}_disconnect(t=1e3,s){if(this._clearTimeouts(),!!this._ws){this._removeListeners();try{this._ws.close(t,s),this._handleClose(new Q.CloseEvent(t,s,this))}catch{}}}_acceptOpen(){this._debug("accept open"),this._retryCount=0}_removeListeners(){this._ws&&(this._debug("removeListeners"),this._ws.removeEventListener("open",this._handleOpen),this._ws.removeEventListener("close",this._handleClose),this._ws.removeEventListener("message",this._handleMessage),this._ws.removeEventListener("error",this._handleError))}_addListeners(){this._ws&&(this._debug("addListeners"),this._ws.addEventListener("open",this._handleOpen),this._ws.addEventListener("close",this._handleClose),this._ws.addEventListener("message",this._handleMessage),this._ws.addEventListener("error",this._handleError))}_clearTimeouts(){clearTimeout(this._connectTimeout),clearTimeout(this._uptimeTimeout)}};/*!
23
- * Reconnecting WebSocket
24
- * by Pedro Ladaria <pedro.ladaria@gmail.com>
25
- * https://github.com/pladaria/reconnecting-websocket
26
- * License MIT
27
- */var Nt=e=>e[1]!==null&&e[1]!==void 0;function Pt(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();let e=new Date().getTime(),n=typeof performance<"u"&&performance.now&&performance.now()*1e3||0;return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){let s=Math.random()*16;return e>0?(s=(e+s)%16|0,e=Math.floor(e/16)):(s=(n+s)%16|0,n=Math.floor(n/16)),(t==="x"?s:s&3|8).toString(16)})}function Ke(e,n,t={}){const{host:s,path:r,protocol:i,room:c,party:a,prefix:h,query:f}=e;let y=s.replace(/^(http|https|ws|wss):\/\//,"");if(y.endsWith("/")&&(y=y.slice(0,-1)),r&&r.startsWith("/"))throw new Error("path must not start with a slash");const L=a??"main",v=r?`/${r}`:"",m=i||(y.startsWith("localhost:")||y.startsWith("127.0.0.1:")||y.startsWith("192.168.")||y.startsWith("10.")||y.startsWith("172.")&&y.split(".")[1]>="16"&&y.split(".")[1]<="31"||y.startsWith("[::ffff:7f00:1]:")?n:n+"s"),E=`${m}://${y}/${h||`parties/${L}/${c}`}${v}`,C=(I={})=>`${E}?${new URLSearchParams([...Object.entries(t),...Object.entries(I).filter(Nt)])}`,j=typeof f=="function"?async()=>C(await f()):C(f);return{host:y,path:v,room:c,name:L,protocol:m,partyUrl:E,urlProvider:j}}var Ht=class extends At{constructor(n){const t=ie(n);super(t.urlProvider,t.protocols,t.socketOptions);p(this,"_pk");p(this,"_pkurl");p(this,"name");p(this,"room");p(this,"host");p(this,"path");this.partySocketOptions=n,this.setWSProperties(t)}updateProperties(n){const t=ie({...this.partySocketOptions,...n,host:n.host??this.host,room:n.room??this.room,path:n.path??this.path});this._url=t.urlProvider,this._protocols=t.protocols,this._options=t.socketOptions,this.setWSProperties(t)}setWSProperties(n){const{_pk:t,_pkurl:s,name:r,room:i,host:c,path:a}=n;this._pk=t,this._pkurl=s,this.name=r,this.room=i,this.host=c,this.path=a}reconnect(n,t){if(!this.room||!this.host)throw new Error("The room and host must be set before connecting, use `updateProperties` method to set them or pass them to the constructor.");super.reconnect(n,t)}get id(){return this._pk}get roomUrl(){return this._pkurl}static async fetch(n,t){const s=Ke(n,"http"),r=typeof s.urlProvider=="string"?s.urlProvider:await s.urlProvider();return(n.fetch??fetch)(r,t)}};function ie(e){const{id:n,host:t,path:s,party:r,room:i,protocol:c,query:a,protocols:h,...f}=e,y=n||Pt(),L=Ke(e,"ws",{_pk:y});return{_pk:y,_pkurl:L.partyUrl,name:L.name,room:L.room,host:L.host,path:L.path,protocols:h,socketOptions:f,urlProvider:L.urlProvider}}var Rt=(e,n)=>{const t=x.useRef(n);t.current=n,x.useEffect(()=>{const s=a=>{var h,f;return(f=(h=t.current)==null?void 0:h.onOpen)==null?void 0:f.call(h,a)},r=a=>{var h,f;return(f=(h=t.current)==null?void 0:h.onMessage)==null?void 0:f.call(h,a)},i=a=>{var h,f;return(f=(h=t.current)==null?void 0:h.onClose)==null?void 0:f.call(h,a)},c=a=>{var h,f;return(f=(h=t.current)==null?void 0:h.onError)==null?void 0:f.call(h,a)};return e.addEventListener("open",s),e.addEventListener("close",i),e.addEventListener("error",c),e.addEventListener("message",r),()=>{e.removeEventListener("open",s),e.removeEventListener("close",i),e.removeEventListener("error",c),e.removeEventListener("message",r)}},[e])},Mt=e=>[e.startClosed,e.minUptime,e.maxRetries,e.connectionTimeout,e.maxEnqueuedMessages,e.maxReconnectionDelay,e.minReconnectionDelay,e.reconnectionDelayGrowFactor,e.debug];function Wt({options:e,createSocket:n,createSocketMemoKey:t}){const s=t(e),r=x.useMemo(()=>e,[s]),[i,c]=x.useState(()=>n({...r,startClosed:!0})),a=x.useRef(null),h=x.useRef(n);return h.current=n,x.useEffect(()=>{if(a.current===i){const f=h.current({...r,startClosed:!1});c(f)}else return!a.current&&r.startClosed!==!0&&i.reconnect(),a.current=i,()=>{i.close()}},[i,r]),i}function jt(e){const{host:n,...t}=e,s=Wt({options:{host:n||(typeof window<"u"?window.location.host:"dummy-domain.com"),...t},createSocket:r=>new Ht(r),createSocketMemoKey:r=>JSON.stringify([r.query,r.id,r.host,r.room,r.party,r.path,r.protocol,r.protocols,...Mt(r)])});return Rt(s,e),s}const ze=x.createContext(null);function Dt(){var n;const e=q("root");return((n=e==null?void 0:e.preferences)==null?void 0:n.presence)??null}function $t(){const e=q("root");return(e==null?void 0:e.workshopTitle)??null}const Ft=d.object({type:d.union([d.literal("problem"),d.literal("solution")]).optional(),exerciseNumber:d.coerce.number().finite(),stepNumber:d.coerce.number().finite().optional()});function qt(e){const n=$t(),{userHasAccess:t=!1}=q("root")??{},s=lt(),r=ut(),i=Dt(),c=q("root"),[a,h]=x.useState((c==null?void 0:c.presence.users)??[]),[f]=x.useState(()=>{if(typeof document>"u")return null;if(e)return e.id;const I=sessionStorage.getItem("clientId");if(I)return I;const T=Ot();return sessionStorage.setItem("clientId",T),T}),y=jt({host:new URL(ht).host,room:ae,onMessage(I){const T=ft.safeParse(JSON.parse(String(I.data)));T.success&&T.data.type==="presence"&&h(T.data.payload.users)}}),L=Ft.safeParse(r),v=L.success?L.data:null,m={workshopTitle:n,origin:s.origin,...v?{exercise:{type:v.type,exerciseNumber:v.exerciseNumber,stepNumber:v.stepNumber}}:null};let E=null;(!e||i!=null&&i.optOut)&&f?(e&&(E={type:"remove-user",payload:{id:e.id}}),E={type:"add-user",payload:{id:f,location:m}}):e&&(E={type:"add-user",payload:{id:e.id,name:e.name,hasAccess:t,imageUrlSmall:e.imageUrlSmall,imageUrlLarge:e.imageUrlLarge,location:m}});const C=E?JSON.stringify(E):null;return x.useEffect(()=>{C&&y.send(C)},[C,y]),{users:Gt(m,a)}}function Gt(e,n){return n.map(s=>{var c,a,h,f;let r=0;const i=5;return s.hasAccess&&(r+=1),(e==null?void 0:e.workshopTitle)===((c=s.location)==null?void 0:c.workshopTitle)&&(r+=1,(a=e==null?void 0:e.exercise)!=null&&a.exerciseNumber&&e.exercise.exerciseNumber===((f=(h=s.location)==null?void 0:h.exercise)==null?void 0:f.exerciseNumber)&&(r+=1,e.exercise.stepNumber&&e.exercise.stepNumber===s.location.exercise.stepNumber&&(r+=1,e.exercise.type&&e.exercise.type===s.location.exercise.type&&(r+=1)))),{user:s,score:Math.floor(r/i*10)/10}}).sort((s,r)=>s.score===r.score?0:s.score>r.score?-1:1)}function Zt({user:e,children:n}){return at.jsx(ze.Provider,{value:qt(e),children:n})}function en(){const e=x.useContext(ze);if(!e)throw new Error("usePresence must be used within a PresenceProvider");return e}export{Zt as P,en as a,Dt as u};
28
- //# sourceMappingURL=presence-DJGFvdDh.js.map