@epic-web/workshop-app 6.69.1 → 6.71.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 (225) hide show
  1. package/build/client/assets/{_-BnmXymJG.js → _-dWSrc4Ox.js} +2 -2
  2. package/build/client/assets/{_-BnmXymJG.js.map → _-dWSrc4Ox.js.map} +1 -1
  3. package/build/client/assets/{_basePickBy-D6pFkWVF.js → _basePickBy-D77BeQbR.js} +2 -2
  4. package/build/client/assets/{_basePickBy-D6pFkWVF.js.map → _basePickBy-D77BeQbR.js.map} +1 -1
  5. package/build/client/assets/{_baseUniq-BbljtzXr.js → _baseUniq-DTO-tFvD.js} +2 -2
  6. package/build/client/assets/{_baseUniq-BbljtzXr.js.map → _baseUniq-DTO-tFvD.js.map} +1 -1
  7. package/build/client/assets/{_exerciseNumber-77g7-L-x.js → _exerciseNumber-DgMb13KP.js} +2 -2
  8. package/build/client/assets/{_exerciseNumber-77g7-L-x.js.map → _exerciseNumber-DgMb13KP.js.map} +1 -1
  9. package/build/client/assets/{_exerciseNumber_._stepNumber.index-DYb7kg06.js → _exerciseNumber_._stepNumber.index-WLW-sVZ0.js} +2 -2
  10. package/build/client/assets/{_exerciseNumber_._stepNumber.index-DYb7kg06.js.map → _exerciseNumber_._stepNumber.index-WLW-sVZ0.js.map} +1 -1
  11. package/build/client/assets/{_exerciseNumber_.finished-CGoPhVVF.js → _exerciseNumber_.finished-DkAs61X_.js} +2 -2
  12. package/build/client/assets/_exerciseNumber_.finished-DkAs61X_.js.map +1 -0
  13. package/build/client/assets/_extra-fwsy2qkP.js +2 -0
  14. package/build/client/assets/_extra-fwsy2qkP.js.map +1 -0
  15. package/build/client/assets/_layout-BQ8VYaze.js +2 -0
  16. package/build/client/assets/_layout-BQ8VYaze.js.map +1 -0
  17. package/build/client/assets/_layout-DR0LQ06M.js +2 -0
  18. package/build/client/assets/_layout-DR0LQ06M.js.map +1 -0
  19. package/build/client/assets/{accordion-CzXT3k43.js → accordion-CQ7oujC6.js} +2 -2
  20. package/build/client/assets/{accordion-CzXT3k43.js.map → accordion-CQ7oujC6.js.map} +1 -1
  21. package/build/client/assets/{account-Cs3Te0is.js → account-C96cpeZR.js} +2 -2
  22. package/build/client/assets/{account-Cs3Te0is.js.map → account-C96cpeZR.js.map} +1 -1
  23. package/build/client/assets/app-CJniokic.js +2 -0
  24. package/build/client/assets/{app-TcFAQB2o.js.map → app-CJniokic.js.map} +1 -1
  25. package/build/client/assets/{arc-BHxP6xxO.js → arc-ChVm3d4e.js} +2 -2
  26. package/build/client/assets/{arc-BHxP6xxO.js.map → arc-ChVm3d4e.js.map} +1 -1
  27. package/build/client/assets/{architectureDiagram-VXUJARFQ-oEJHJt7x.js → architectureDiagram-VXUJARFQ-DkqyKZ50.js} +2 -2
  28. package/build/client/assets/{architectureDiagram-VXUJARFQ-oEJHJt7x.js.map → architectureDiagram-VXUJARFQ-DkqyKZ50.js.map} +1 -1
  29. package/build/client/assets/{blockDiagram-VD42YOAC-7xzSJqoM.js → blockDiagram-VD42YOAC-Cqa8Z0qT.js} +2 -2
  30. package/build/client/assets/{blockDiagram-VD42YOAC-7xzSJqoM.js.map → blockDiagram-VD42YOAC-Cqa8Z0qT.js.map} +1 -1
  31. package/build/client/assets/{button-CIlVtsau.js → button-Cd-ekki5.js} +2 -2
  32. package/build/client/assets/{button-CIlVtsau.js.map → button-Cd-ekki5.js.map} +1 -1
  33. package/build/client/assets/{c4Diagram-YG6GDRKO-BUdT9rCJ.js → c4Diagram-YG6GDRKO-BHQRSJ1P.js} +2 -2
  34. package/build/client/assets/{c4Diagram-YG6GDRKO-BUdT9rCJ.js.map → c4Diagram-YG6GDRKO-BHQRSJ1P.js.map} +1 -1
  35. package/build/client/assets/{cache-MJu_dqFS.js → cache-CAr50MIB.js} +2 -2
  36. package/build/client/assets/{cache-MJu_dqFS.js.map → cache-CAr50MIB.js.map} +1 -1
  37. package/build/client/assets/channel-B7uExpgv.js +2 -0
  38. package/build/client/assets/{channel-BLJkdd1O.js.map → channel-B7uExpgv.js.map} +1 -1
  39. package/build/client/assets/{chunk-4BX2VUAB-qrzenNNi.js → chunk-4BX2VUAB-BOJM4J9w.js} +2 -2
  40. package/build/client/assets/{chunk-4BX2VUAB-qrzenNNi.js.map → chunk-4BX2VUAB-BOJM4J9w.js.map} +1 -1
  41. package/build/client/assets/{chunk-55IACEB6-BOr0rES3.js → chunk-55IACEB6-CO_GT_87.js} +2 -2
  42. package/build/client/assets/{chunk-55IACEB6-BOr0rES3.js.map → chunk-55IACEB6-CO_GT_87.js.map} +1 -1
  43. package/build/client/assets/{chunk-B4BG7PRW-C2qQTBXm.js → chunk-B4BG7PRW-CqfZTumF.js} +2 -2
  44. package/build/client/assets/{chunk-B4BG7PRW-C2qQTBXm.js.map → chunk-B4BG7PRW-CqfZTumF.js.map} +1 -1
  45. package/build/client/assets/{chunk-DI55MBZ5-CSfEUcAq.js → chunk-DI55MBZ5-CxSXOmoK.js} +2 -2
  46. package/build/client/assets/{chunk-DI55MBZ5-CSfEUcAq.js.map → chunk-DI55MBZ5-CxSXOmoK.js.map} +1 -1
  47. package/build/client/assets/{chunk-FMBD7UC4-CyJoWksV.js → chunk-FMBD7UC4-ChHVMdVq.js} +2 -2
  48. package/build/client/assets/{chunk-FMBD7UC4-CyJoWksV.js.map → chunk-FMBD7UC4-ChHVMdVq.js.map} +1 -1
  49. package/build/client/assets/{chunk-QN33PNHL-BpbvTQdp.js → chunk-QN33PNHL-DKEBwj3f.js} +2 -2
  50. package/build/client/assets/{chunk-QN33PNHL-BpbvTQdp.js.map → chunk-QN33PNHL-DKEBwj3f.js.map} +1 -1
  51. package/build/client/assets/{chunk-QZHKN3VN-C2RN0CtQ.js → chunk-QZHKN3VN-Cu5tuE5n.js} +2 -2
  52. package/build/client/assets/{chunk-QZHKN3VN-C2RN0CtQ.js.map → chunk-QZHKN3VN-Cu5tuE5n.js.map} +1 -1
  53. package/build/client/assets/{chunk-TZMSLE5B-0z8lxtDn.js → chunk-TZMSLE5B-BpvH1fVS.js} +2 -2
  54. package/build/client/assets/{chunk-TZMSLE5B-0z8lxtDn.js.map → chunk-TZMSLE5B-BpvH1fVS.js.map} +1 -1
  55. package/build/client/assets/classDiagram-2ON5EDUG-BjjlpwdW.js +2 -0
  56. package/build/client/assets/{classDiagram-2ON5EDUG-_kfNpv_f.js.map → classDiagram-2ON5EDUG-BjjlpwdW.js.map} +1 -1
  57. package/build/client/assets/classDiagram-v2-WZHVMYZB-BjjlpwdW.js +2 -0
  58. package/build/client/assets/{classDiagram-v2-WZHVMYZB-_kfNpv_f.js.map → classDiagram-v2-WZHVMYZB-BjjlpwdW.js.map} +1 -1
  59. package/build/client/assets/clone-DRkw5ylZ.js +2 -0
  60. package/build/client/assets/{clone-CztDUJhf.js.map → clone-DRkw5ylZ.js.map} +1 -1
  61. package/build/client/assets/{cose-bilkent-S5V4N54A-DQM-J4RL.js → cose-bilkent-S5V4N54A-9tAqXXXx.js} +2 -2
  62. package/build/client/assets/{cose-bilkent-S5V4N54A-DQM-J4RL.js.map → cose-bilkent-S5V4N54A-9tAqXXXx.js.map} +1 -1
  63. package/build/client/assets/{dagre-6UL2VRFP-BdfvKPZ9.js → dagre-6UL2VRFP-DdQahM76.js} +2 -2
  64. package/build/client/assets/{dagre-6UL2VRFP-BdfvKPZ9.js.map → dagre-6UL2VRFP-DdQahM76.js.map} +1 -1
  65. package/build/client/assets/{db-x6v-Uxrh.js → db-DAnX-T3_.js} +2 -2
  66. package/build/client/assets/{db-x6v-Uxrh.js.map → db-DAnX-T3_.js.map} +1 -1
  67. package/build/client/assets/{diagram-PSM6KHXK-CgwBEb3G.js → diagram-PSM6KHXK-D2ghOCFR.js} +2 -2
  68. package/build/client/assets/{diagram-PSM6KHXK-CgwBEb3G.js.map → diagram-PSM6KHXK-D2ghOCFR.js.map} +1 -1
  69. package/build/client/assets/{diagram-QEK2KX5R-DEaXdLXz.js → diagram-QEK2KX5R-CVdPnwKa.js} +2 -2
  70. package/build/client/assets/{diagram-QEK2KX5R-DEaXdLXz.js.map → diagram-QEK2KX5R-CVdPnwKa.js.map} +1 -1
  71. package/build/client/assets/{diagram-S2PKOQOG-Dq5QQWqq.js → diagram-S2PKOQOG-ByHcRNai.js} +2 -2
  72. package/build/client/assets/{diagram-S2PKOQOG-Dq5QQWqq.js.map → diagram-S2PKOQOG-ByHcRNai.js.map} +1 -1
  73. package/build/client/assets/{dialog-DnpUg3VT.js → dialog-CzO65Z5w.js} +3 -3
  74. package/build/client/assets/{dialog-DnpUg3VT.js.map → dialog-CzO65Z5w.js.map} +1 -1
  75. package/build/client/assets/{diff-CxEbhF8Q.js → diff-BhWzqoVN.js} +2 -2
  76. package/build/client/assets/{diff-CxEbhF8Q.js.map → diff-BhWzqoVN.js.map} +1 -1
  77. package/build/client/assets/{diff-eAvgXb3f.js → diff-DC-wn6-x.js} +2 -2
  78. package/build/client/assets/{diff-eAvgXb3f.js.map → diff-DC-wn6-x.js.map} +1 -1
  79. package/build/client/assets/{discord-DlU9y5Iz.js → discord-BJkw0IrB.js} +2 -2
  80. package/build/client/assets/{discord-DlU9y5Iz.js.map → discord-BJkw0IrB.js.map} +1 -1
  81. package/build/client/assets/{discord-CuxZiU8E.js → discord-r3m19sUM.js} +2 -2
  82. package/build/client/assets/discord-r3m19sUM.js.map +1 -0
  83. package/build/client/assets/{epic-video-Bx8Ctiez.js → epic-video-8Hv_HMMr.js} +2 -2
  84. package/build/client/assets/{epic-video-Bx8Ctiez.js.map → epic-video-8Hv_HMMr.js.map} +1 -1
  85. package/build/client/assets/{epic-video-BVcJzJzi.js → epic-video-D0drHmgC.js} +2 -2
  86. package/build/client/assets/{epic-video-BVcJzJzi.js.map → epic-video-D0drHmgC.js.map} +1 -1
  87. package/build/client/assets/{erDiagram-Q2GNP2WA-CW73Zw0q.js → erDiagram-Q2GNP2WA-CBRWzQzK.js} +2 -2
  88. package/build/client/assets/{erDiagram-Q2GNP2WA-CW73Zw0q.js.map → erDiagram-Q2GNP2WA-CBRWzQzK.js.map} +1 -1
  89. package/build/client/assets/{error-boundary-DFBd6s0g.js → error-boundary-DVp6wKiz.js} +2 -2
  90. package/build/client/assets/{error-boundary-DFBd6s0g.js.map → error-boundary-DVp6wKiz.js.map} +1 -1
  91. package/build/client/assets/{finished-CmV4aFjA.js → finished-CiVHAeSV.js} +2 -2
  92. package/build/client/assets/{finished-CmV4aFjA.js.map → finished-CiVHAeSV.js.map} +1 -1
  93. package/build/client/assets/{flowDiagram-NV44I4VS-BbxV9VQf.js → flowDiagram-NV44I4VS-L32__tfK.js} +2 -2
  94. package/build/client/assets/{flowDiagram-NV44I4VS-BbxV9VQf.js.map → flowDiagram-NV44I4VS-L32__tfK.js.map} +1 -1
  95. package/build/client/assets/{ganttDiagram-JELNMOA3-CRBJBlE5.js → ganttDiagram-JELNMOA3-Dpp5PKJc.js} +2 -2
  96. package/build/client/assets/{ganttDiagram-JELNMOA3-CRBJBlE5.js.map → ganttDiagram-JELNMOA3-Dpp5PKJc.js.map} +1 -1
  97. package/build/client/assets/{gitGraphDiagram-NY62KEGX-CU0X3hfs.js → gitGraphDiagram-NY62KEGX-zn4IXANG.js} +2 -2
  98. package/build/client/assets/{gitGraphDiagram-NY62KEGX-CU0X3hfs.js.map → gitGraphDiagram-NY62KEGX-zn4IXANG.js.map} +1 -1
  99. package/build/client/assets/{graph-CEUh1UxC.js → graph-Da5nhwRG.js} +2 -2
  100. package/build/client/assets/{graph-CEUh1UxC.js.map → graph-Da5nhwRG.js.map} +1 -1
  101. package/build/client/assets/guide-Cinib8Ji.js +9 -0
  102. package/build/client/assets/guide-Cinib8Ji.js.map +1 -0
  103. package/build/client/assets/{index-D3zOGeBE.js → index-BKAVQvm5.js} +2 -2
  104. package/build/client/assets/{index-D3zOGeBE.js.map → index-BKAVQvm5.js.map} +1 -1
  105. package/build/client/assets/{index-BOhw3wcM.js → index-CJDOQ1bl.js} +2 -2
  106. package/build/client/assets/{index-BOhw3wcM.js.map → index-CJDOQ1bl.js.map} +1 -1
  107. package/build/client/assets/{index-B-9GR1C2.js → index-C_wcF1aP.js} +2 -2
  108. package/build/client/assets/{index-B-9GR1C2.js.map → index-C_wcF1aP.js.map} +1 -1
  109. package/build/client/assets/{index-BW8stNyh.js → index-CdzVFL-Z.js} +3 -3
  110. package/build/client/assets/{index-BW8stNyh.js.map → index-CdzVFL-Z.js.map} +1 -1
  111. package/build/client/assets/index-CmflCPTU.js +2 -0
  112. package/build/client/assets/index-CmflCPTU.js.map +1 -0
  113. package/build/client/assets/index-DuFMeXSm.js +2 -0
  114. package/build/client/assets/index-DuFMeXSm.js.map +1 -0
  115. package/build/client/assets/index-hhQHCvb9.js +2 -0
  116. package/build/client/assets/{index-EdNV8gTk.js.map → index-hhQHCvb9.js.map} +1 -1
  117. package/build/client/assets/{index-C_KjwKVt.js → index-ynYvVAOK.js} +2 -2
  118. package/build/client/assets/{index-C_KjwKVt.js.map → index-ynYvVAOK.js.map} +1 -1
  119. package/build/client/assets/{infoDiagram-WHAUD3N6-BplcSre1.js → infoDiagram-WHAUD3N6-CToPP1ur.js} +2 -2
  120. package/build/client/assets/{infoDiagram-WHAUD3N6-BplcSre1.js.map → infoDiagram-WHAUD3N6-CToPP1ur.js.map} +1 -1
  121. package/build/client/assets/{journeyDiagram-XKPGCS4Q-yxvCkf49.js → journeyDiagram-XKPGCS4Q-BBRpqEuF.js} +2 -2
  122. package/build/client/assets/{journeyDiagram-XKPGCS4Q-yxvCkf49.js.map → journeyDiagram-XKPGCS4Q-BBRpqEuF.js.map} +1 -1
  123. package/build/client/assets/{kanban-definition-3W4ZIXB7-DFEBMrRH.js → kanban-definition-3W4ZIXB7-CyGlZ-MK.js} +2 -2
  124. package/build/client/assets/{kanban-definition-3W4ZIXB7-DFEBMrRH.js.map → kanban-definition-3W4ZIXB7-CyGlZ-MK.js.map} +1 -1
  125. package/build/client/assets/{launch-editor-B2dmpkaO.js → launch-editor-D2exGfVu.js} +2 -2
  126. package/build/client/assets/{launch-editor-B2dmpkaO.js.map → launch-editor-D2exGfVu.js.map} +1 -1
  127. package/build/client/assets/{layout-CiHrgFnf.js → layout-CUEelucj.js} +2 -2
  128. package/build/client/assets/{layout-CiHrgFnf.js.map → layout-CUEelucj.js.map} +1 -1
  129. package/build/client/assets/{linear-C-81cvJP.js → linear-DzZ9bjHs.js} +2 -2
  130. package/build/client/assets/{linear-C-81cvJP.js.map → linear-DzZ9bjHs.js.map} +1 -1
  131. package/build/client/assets/{loading-CUydCGD3.js → loading-CDNzW5oO.js} +2 -2
  132. package/build/client/assets/{loading-CUydCGD3.js.map → loading-CDNzW5oO.js.map} +1 -1
  133. package/build/client/assets/{login-DvBmP_ce.js → login-mWjVXGbJ.js} +2 -2
  134. package/build/client/assets/{login-DvBmP_ce.js.map → login-mWjVXGbJ.js.map} +1 -1
  135. package/build/client/assets/manifest-970c9ad1.js +1 -0
  136. package/build/client/assets/{mdx-vrch0szL.js → mdx-BzyhMqFg.js} +3 -3
  137. package/build/client/assets/{mdx-vrch0szL.js.map → mdx-BzyhMqFg.js.map} +1 -1
  138. package/build/client/assets/{mermaid.core-D3y7PO8B.js → mermaid.core-BdxLLjl2.js} +5 -5
  139. package/build/client/assets/{mermaid.core-D3y7PO8B.js.map → mermaid.core-BdxLLjl2.js.map} +1 -1
  140. package/build/client/assets/{mindmap-definition-VGOIOE7T-VMZ6ZZlW.js → mindmap-definition-VGOIOE7T-DeKD8ncg.js} +2 -2
  141. package/build/client/assets/{mindmap-definition-VGOIOE7T-VMZ6ZZlW.js.map → mindmap-definition-VGOIOE7T-DeKD8ncg.js.map} +1 -1
  142. package/build/client/assets/{misc-DVYuZMjW.js → misc-W4055b-0.js} +2 -2
  143. package/build/client/assets/{misc-DVYuZMjW.js.map → misc-W4055b-0.js.map} +1 -1
  144. package/build/client/assets/{nav-chevrons-DlNUibJV.js → nav-chevrons-Dk4GtZwQ.js} +2 -2
  145. package/build/client/assets/{nav-chevrons-DlNUibJV.js.map → nav-chevrons-Dk4GtZwQ.js.map} +1 -1
  146. package/build/client/assets/{offline-videos-Do9PBh87.js → offline-videos-BP7_xJkO.js} +2 -2
  147. package/build/client/assets/{offline-videos-Do9PBh87.js.map → offline-videos-BP7_xJkO.js.map} +1 -1
  148. package/build/client/assets/{onboarding-indicator-CVwXz3Cn.js → onboarding-indicator-B-XR90_G.js} +2 -2
  149. package/build/client/assets/{onboarding-indicator-CVwXz3Cn.js.map → onboarding-indicator-B-XR90_G.js.map} +1 -1
  150. package/build/client/assets/{pieDiagram-ADFJNKIX-CKbrBdQs.js → pieDiagram-ADFJNKIX-BQ4sFDrB.js} +2 -2
  151. package/build/client/assets/{pieDiagram-ADFJNKIX-CKbrBdQs.js.map → pieDiagram-ADFJNKIX-BQ4sFDrB.js.map} +1 -1
  152. package/build/client/assets/playground-DmEAkxG1.js +2 -0
  153. package/build/client/assets/playground-DmEAkxG1.js.map +1 -0
  154. package/build/client/assets/{playground-window-D9a7P7rH.js → playground-window-x2mQ5o1O.js} +2 -2
  155. package/build/client/assets/{playground-window-D9a7P7rH.js.map → playground-window-x2mQ5o1O.js.map} +1 -1
  156. package/build/client/assets/{preferences-BCvK10k2.js → preferences-D6HQ5bK1.js} +2 -2
  157. package/build/client/assets/{preferences-BCvK10k2.js.map → preferences-D6HQ5bK1.js.map} +1 -1
  158. package/build/client/assets/{preview-CiDtuQCc.js → preview-fhmjENlm.js} +2 -2
  159. package/build/client/assets/{preview-CiDtuQCc.js.map → preview-fhmjENlm.js.map} +1 -1
  160. package/build/client/assets/{product-GLsnY1u3.js → product-CvyMpYD_.js} +2 -2
  161. package/build/client/assets/{product-GLsnY1u3.js.map → product-CvyMpYD_.js.map} +1 -1
  162. package/build/client/assets/{progress-fKsNxmmt.js → progress-ILaVQtOO.js} +2 -2
  163. package/build/client/assets/{progress-fKsNxmmt.js.map → progress-ILaVQtOO.js.map} +1 -1
  164. package/build/client/assets/{progress-bar-B27isaGl.js → progress-bar-DpWhcyhC.js} +2 -2
  165. package/build/client/assets/{progress-bar-B27isaGl.js.map → progress-bar-DpWhcyhC.js.map} +1 -1
  166. package/build/client/assets/{quadrantDiagram-AYHSOK5B-Bb5EtkPw.js → quadrantDiagram-AYHSOK5B-QnjodHfi.js} +2 -2
  167. package/build/client/assets/{quadrantDiagram-AYHSOK5B-Bb5EtkPw.js.map → quadrantDiagram-AYHSOK5B-QnjodHfi.js.map} +1 -1
  168. package/build/client/assets/{requirementDiagram-UZGBJVZJ-BNsXiFG2.js → requirementDiagram-UZGBJVZJ-mL9Oeda0.js} +2 -2
  169. package/build/client/assets/{requirementDiagram-UZGBJVZJ-BNsXiFG2.js.map → requirementDiagram-UZGBJVZJ-mL9Oeda0.js.map} +1 -1
  170. package/build/client/assets/{root-Ch373D3a.js → root-Bktp3RtN.js} +2 -2
  171. package/build/client/assets/{root-Ch373D3a.js.map → root-Bktp3RtN.js.map} +1 -1
  172. package/build/client/assets/{sankeyDiagram-TZEHDZUN-qlPqhk7P.js → sankeyDiagram-TZEHDZUN-B8_zpQVR.js} +2 -2
  173. package/build/client/assets/{sankeyDiagram-TZEHDZUN-qlPqhk7P.js.map → sankeyDiagram-TZEHDZUN-B8_zpQVR.js.map} +1 -1
  174. package/build/client/assets/{sequenceDiagram-WL72ISMW-C3d31B7K.js → sequenceDiagram-WL72ISMW-BDd5tjuk.js} +2 -2
  175. package/build/client/assets/{sequenceDiagram-WL72ISMW-C3d31B7K.js.map → sequenceDiagram-WL72ISMW-BDd5tjuk.js.map} +1 -1
  176. package/build/client/assets/{set-playground-DeMY9i7p.js → set-playground-BSGwH9dH.js} +2 -2
  177. package/build/client/assets/{set-playground-DeMY9i7p.js.map → set-playground-BSGwH9dH.js.map} +1 -1
  178. package/build/client/assets/{stateDiagram-FKZM4ZOC-C1eIQm_7.js → stateDiagram-FKZM4ZOC-DGPNpRbW.js} +2 -2
  179. package/build/client/assets/{stateDiagram-FKZM4ZOC-C1eIQm_7.js.map → stateDiagram-FKZM4ZOC-DGPNpRbW.js.map} +1 -1
  180. package/build/client/assets/stateDiagram-v2-4FDKWEC3-DxaFuKxL.js +2 -0
  181. package/build/client/assets/{stateDiagram-v2-4FDKWEC3-CAmcrDIS.js.map → stateDiagram-v2-4FDKWEC3-DxaFuKxL.js.map} +1 -1
  182. package/build/client/assets/status-indicator-C6DiLYL5.js +2 -0
  183. package/build/client/assets/status-indicator-C6DiLYL5.js.map +1 -0
  184. package/build/client/assets/tailwind-B97VvnKU.css +1 -0
  185. package/build/client/assets/test-DtQCjBBX.js +2 -0
  186. package/build/client/assets/{test-CdEKoDoS.js.map → test-DtQCjBBX.js.map} +1 -1
  187. package/build/client/assets/{tests-xD9PppmM.js → tests-fDISNsE-.js} +2 -2
  188. package/build/client/assets/{tests-xD9PppmM.js.map → tests-fDISNsE-.js.map} +1 -1
  189. package/build/client/assets/{timeline-definition-IT6M3QCI-Di_ZGPjO.js → timeline-definition-IT6M3QCI-BnMOh0dz.js} +2 -2
  190. package/build/client/assets/{timeline-definition-IT6M3QCI-Di_ZGPjO.js.map → timeline-definition-IT6M3QCI-BnMOh0dz.js.map} +1 -1
  191. package/build/client/assets/{tooltip-Chzzs4KB.js → tooltip-Tlsyx2YO.js} +2 -2
  192. package/build/client/assets/{tooltip-Chzzs4KB.js.map → tooltip-Tlsyx2YO.js.map} +1 -1
  193. package/build/client/assets/{treemap-KMMF4GRG-DZrMUxqR.js → treemap-KMMF4GRG-Ds3XkDP-.js} +2 -2
  194. package/build/client/assets/{treemap-KMMF4GRG-DZrMUxqR.js.map → treemap-KMMF4GRG-Ds3XkDP-.js.map} +1 -1
  195. package/build/client/assets/{workspace-structure-i_5Tiikk.js → workspace-structure-B6Rpl-B2.js} +2 -2
  196. package/build/client/assets/{workspace-structure-i_5Tiikk.js.map → workspace-structure-B6Rpl-B2.js.map} +1 -1
  197. package/build/client/assets/{xychartDiagram-PRI3JC2R-BxuKJVc7.js → xychartDiagram-PRI3JC2R-DH_JPNZp.js} +2 -2
  198. package/build/client/assets/{xychartDiagram-PRI3JC2R-BxuKJVc7.js.map → xychartDiagram-PRI3JC2R-DH_JPNZp.js.map} +1 -1
  199. package/build/server/index.js +690 -114
  200. package/build/server/index.js.map +1 -1
  201. package/package.json +3 -3
  202. package/build/client/assets/_exerciseNumber_.finished-CGoPhVVF.js.map +0 -1
  203. package/build/client/assets/_extra-BZPB_nWQ.js +0 -2
  204. package/build/client/assets/_extra-BZPB_nWQ.js.map +0 -1
  205. package/build/client/assets/_layout-BxQPZuW6.js +0 -2
  206. package/build/client/assets/_layout-BxQPZuW6.js.map +0 -1
  207. package/build/client/assets/_layout-yxOoJ6Yg.js +0 -2
  208. package/build/client/assets/_layout-yxOoJ6Yg.js.map +0 -1
  209. package/build/client/assets/app-TcFAQB2o.js +0 -2
  210. package/build/client/assets/channel-BLJkdd1O.js +0 -2
  211. package/build/client/assets/classDiagram-2ON5EDUG-_kfNpv_f.js +0 -2
  212. package/build/client/assets/classDiagram-v2-WZHVMYZB-_kfNpv_f.js +0 -2
  213. package/build/client/assets/clone-CztDUJhf.js +0 -2
  214. package/build/client/assets/discord-CuxZiU8E.js.map +0 -1
  215. package/build/client/assets/guide-B4wAqzq_.js +0 -9
  216. package/build/client/assets/guide-B4wAqzq_.js.map +0 -1
  217. package/build/client/assets/index-C6vQqVxz.js +0 -2
  218. package/build/client/assets/index-C6vQqVxz.js.map +0 -1
  219. package/build/client/assets/index-EdNV8gTk.js +0 -2
  220. package/build/client/assets/manifest-34df6718.js +0 -1
  221. package/build/client/assets/playground-C_aP_pE8.js +0 -2
  222. package/build/client/assets/playground-C_aP_pE8.js.map +0 -1
  223. package/build/client/assets/stateDiagram-v2-4FDKWEC3-CAmcrDIS.js +0 -2
  224. package/build/client/assets/tailwind-D_K12wB7.css +0 -1
  225. package/build/client/assets/test-CdEKoDoS.js +0 -2
@@ -1 +0,0 @@
1
- {"version":3,"file":"_layout-yxOoJ6Yg.js","sources":["../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/step-mdx.tsx","../../../../../node_modules/@radix-ui/react-popover/dist/index.mjs","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/touched-files.tsx","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout.tsx"],"sourcesContent":["import * as React from 'react'\nimport { type PropsWithChildren } from 'react'\nimport {\n\tLink,\n\tuseLoaderData,\n\tuseSearchParams,\n\ttype LinkProps,\n} from 'react-router'\nimport iconsSvg from '#app/assets/icons.svg'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { Icon } from '#app/components/icons.tsx'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.tsx'\nimport { LaunchEditor } from '#app/routes/launch-editor.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn, getBaseUrl } from '#app/utils/misc.tsx'\nimport { useRequestInfo } from '#app/utils/root-loader.ts'\nimport { type loader } from '../_layout.tsx'\n\ntype StepContextType = {\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n}\nconst StepContext = React.createContext<StepContextType | null>(null)\n\nfunction useStepContext() {\n\tconst context = React.useContext(StepContext)\n\tif (!context) {\n\t\tthrow new Error('useStepContext must be used within a StepContextProvider')\n\t}\n\treturn context\n}\n\nfunction StepContextProvider({\n\tchildren,\n\tinBrowserBrowserRef,\n}: {\n\tchildren: React.ReactNode\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n}) {\n\treturn <StepContext value={{ inBrowserBrowserRef }}>{children}</StepContext>\n}\n\nconst stepMdxComponents = {\n\tDiffLink,\n\tPrevDiffLink,\n\tNextDiffLink,\n\tInlineFile,\n\tLinkToApp,\n}\n\nexport function StepMdx({\n\tinBrowserBrowserRef,\n}: {\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tif (!data.exerciseStepApp.instructionsCode) return null\n\treturn (\n\t\t<StepContextProvider inBrowserBrowserRef={inBrowserBrowserRef}>\n\t\t\t<EpicVideoInfoProvider epicVideoInfosPromise={data.epicVideoInfosPromise}>\n\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t<Mdx\n\t\t\t\t\t\tcode={data.exerciseStepApp.instructionsCode}\n\t\t\t\t\t\tcomponents={stepMdxComponents}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</EpicVideoInfoProvider>\n\t\t</StepContextProvider>\n\t)\n}\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\nfunction NextDiffLink({\n\tapp = 0,\n\tfullPage = false,\n\tchildren,\n}: {\n\tapp: number\n\tfullPage?: boolean\n\tchildren?: React.ReactNode\n}) {\n\treturn (\n\t\t<DiffLink app1={app} app2={app + 1} fullPage={fullPage}>\n\t\t\t{children}\n\t\t</DiffLink>\n\t)\n}\n\nfunction PrevDiffLink({\n\tapp = -1,\n\tfullPage = false,\n\tchildren,\n}: {\n\tapp: number\n\tfullPage?: boolean\n\tchildren?: React.ReactNode\n}) {\n\treturn (\n\t\t<DiffLink app1={app} app2={app + 1} fullPage={fullPage}>\n\t\t\t{children}\n\t\t</DiffLink>\n\t)\n}\n\nfunction DiffLink({\n\tapp1 = 0,\n\tapp2 = 1,\n\tchildren,\n\tfullPage = false,\n\tto,\n}: {\n\tapp1?: string | number | null\n\tapp2?: string | number | null\n\tto?: string\n\tfullPage?: boolean\n\tchildren?: React.ReactNode\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tif (!to && !app1 && !app2) {\n\t\treturn (\n\t\t\t<callout-danger className=\"notification\">\n\t\t\t\t<div className=\"title\">DiffLink Error: invalid input</div>\n\t\t\t</callout-danger>\n\t\t)\n\t}\n\n\tfunction getAppName(input: typeof app1) {\n\t\tif (typeof input === 'number') {\n\t\t\tconst stepIndex = data.exerciseIndex + input\n\t\t\treturn data.allApps[stepIndex]?.name\n\t\t}\n\t\tif (!input) return null\n\t\tfor (const { name, stepName } of data.allApps) {\n\t\t\tif (input === name || input === stepName) {\n\t\t\t\treturn name\n\t\t\t}\n\t\t}\n\t\treturn null\n\t}\n\n\tif (to) {\n\t\tconst params = new URLSearchParams(to)\n\t\tapp1 = params.get('app1')\n\t\tapp2 = params.get('app2')\n\t}\n\tconst app1Name = getAppName(app1)\n\tconst app2Name = getAppName(app2)\n\tif (!app1Name || !app2Name) {\n\t\treturn (\n\t\t\t<callout-danger className=\"notification\">\n\t\t\t\t<div className=\"title\">DiffLink Error: invalid input</div>\n\t\t\t\t{!app1Name && <div>app1: \"{app1}\" is not a valid app name</div>}\n\t\t\t\t{!app2Name && <div>app2: \"{app2}\" is not a valid app name</div>}\n\t\t\t</callout-danger>\n\t\t)\n\t}\n\n\tif (!to) {\n\t\tto = `app1=${app1Name}&app2=${app2Name}`\n\t}\n\tconst pathToDiff = fullPage\n\t\t? `/diff?${to}`\n\t\t: `?${decodeURIComponent(\n\t\t\t\twithParam(new URLSearchParams(), 'preview', `diff&${to}`).toString(),\n\t\t\t)}`\n\n\tif (!children) {\n\t\tchildren = (\n\t\t\t<span>\n\t\t\t\tGo to Diff {fullPage ? '' : 'Preview'} from: <code>{app1Name}</code> to:{' '}\n\t\t\t\t<code>{app2Name}</code>\n\t\t\t</span>\n\t\t)\n\t}\n\n\treturn <Link to={pathToDiff}>{children}</Link>\n}\n\nfunction InlineFile({\n\tfile,\n\ttype = 'playground',\n\tchildren = <code>{file}</code>,\n\t...props\n}: Omit<PropsWithChildren<typeof LaunchEditor>, 'appName'> & {\n\tfile: string\n\ttype?: 'playground' | 'solution' | 'problem'\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tconst app = data[type] || data[data.type]\n\n\tconst info = (\n\t\t<div className=\"launch-editor-button-wrapper flex underline underline-offset-4\">\n\t\t\t{children}{' '}\n\t\t\t<svg height={24} width={24}>\n\t\t\t\t<use href={`${iconsSvg}#Keyboard`} />\n\t\t\t</svg>\n\t\t</div>\n\t)\n\n\treturn ENV.EPICSHOP_DEPLOYED && app ? (\n\t\t<div className=\"inline-block grow\">\n\t\t\t<LaunchEditor appFile={file} appName={app.name} {...props}>\n\t\t\t\t{info}\n\t\t\t</LaunchEditor>\n\t\t</div>\n\t) : app ? (\n\t\t<div className=\"inline-block grow\">\n\t\t\t<LaunchEditor appFile={file} appName={app.name} {...props}>\n\t\t\t\t{info}\n\t\t\t</LaunchEditor>\n\t\t</div>\n\t) : type === 'playground' ? (\n\t\t// playground does not exist yet\n\t\t<SimpleTooltip content=\"You must 'Set to Playground' before opening a file\">\n\t\t\t<div className=\"inline-block grow cursor-not-allowed\">{info}</div>\n\t\t</SimpleTooltip>\n\t) : (\n\t\t<>children</>\n\t)\n}\n\nfunction getPreviewType(\n\tpreview: string | null,\n): 'playground' | 'problem' | 'solution' {\n\tif (preview === 'problem') return 'problem'\n\tif (preview === 'solution') return 'solution'\n\treturn 'playground'\n}\n\nfunction LinkToApp({\n\tto: appTo,\n\tchildren = <code>{appTo.toString()}</code>,\n\t...props\n}: LinkProps) {\n\tconst [searchParams] = useSearchParams()\n\tconst to = `?${withParam(\n\t\tsearchParams,\n\t\t'pathname',\n\t\tappTo.toString(),\n\t).toString()}`\n\tconst data = useLoaderData<typeof loader>()\n\tconst type = getPreviewType(searchParams.get('preview'))\n\tconst requestInfo = useRequestInfo()\n\tconst app = data[type]\n\tconst previewAppUrl =\n\t\tapp?.dev.type === 'script'\n\t\t\t? getBaseUrl({\n\t\t\t\t\tdomain: requestInfo.domain,\n\t\t\t\t\tport: app.dev.portNumber,\n\t\t\t\t})\n\t\t\t: data.playground?.dev.type === 'browser' ||\n\t\t\t\t data.playground?.dev.type === 'export'\n\t\t\t\t? data.playground.dev.pathname\n\t\t\t\t: null\n\tconst { inBrowserBrowserRef } = useStepContext()\n\tconst href = previewAppUrl\n\t\t? previewAppUrl.slice(0, -1) + appTo.toString()\n\t\t: null\n\treturn (\n\t\t<div className=\"inline-flex items-center justify-between gap-1\">\n\t\t\t<Link\n\t\t\t\tto={to}\n\t\t\t\t{...props}\n\t\t\t\tclassName={cn(props.className, {\n\t\t\t\t\t'cursor-not-allowed': ENV.EPICSHOP_DEPLOYED,\n\t\t\t\t})}\n\t\t\t\ttitle={\n\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t? 'Cannot link to app in deployed version'\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tonClick={(event) => {\n\t\t\t\t\tif (ENV.EPICSHOP_DEPLOYED) event.preventDefault()\n\n\t\t\t\t\tprops.onClick?.(event)\n\t\t\t\t\tinBrowserBrowserRef.current?.handleExtrnalNavigation(appTo.toString())\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Link>\n\t\t\t{href ? (\n\t\t\t\t<SimpleTooltip content=\"Open in new tab\">\n\t\t\t\t\t<a\n\t\t\t\t\t\thref={href}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\tclassName={cn('flex aspect-square items-center justify-center', {\n\t\t\t\t\t\t\t'cursor-not-allowed': ENV.EPICSHOP_DEPLOYED,\n\t\t\t\t\t\t})}\n\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t\t\t? 'Cannot link to app in deployed version'\n\t\t\t\t\t\t\t\t: 'Open in new tab'\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tif (ENV.EPICSHOP_DEPLOYED) event.preventDefault()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon name=\"ExternalLink\" />\n\t\t\t\t\t</a>\n\t\t\t\t</SimpleTooltip>\n\t\t\t) : null}\n\t\t</div>\n\t)\n}\n","\"use client\";\n\n// src/popover.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { DismissableLayer } from \"@radix-ui/react-dismissable-layer\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { useId } from \"@radix-ui/react-id\";\nimport * as PopperPrimitive from \"@radix-ui/react-popper\";\nimport { createPopperScope } from \"@radix-ui/react-popper\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { hideOthers } from \"aria-hidden\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { jsx } from \"react/jsx-runtime\";\nvar POPOVER_NAME = \"Popover\";\nvar [createPopoverContext, createPopoverScope] = createContextScope(POPOVER_NAME, [\n createPopperScope\n]);\nvar usePopperScope = createPopperScope();\nvar [PopoverProvider, usePopoverContext] = createPopoverContext(POPOVER_NAME);\nvar Popover = (props) => {\n const {\n __scopePopover,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = false\n } = props;\n const popperScope = usePopperScope(__scopePopover);\n const triggerRef = React.useRef(null);\n const [hasCustomAnchor, setHasCustomAnchor] = React.useState(false);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: POPOVER_NAME\n });\n return /* @__PURE__ */ jsx(PopperPrimitive.Root, { ...popperScope, children: /* @__PURE__ */ jsx(\n PopoverProvider,\n {\n scope: __scopePopover,\n contentId: useId(),\n triggerRef,\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n hasCustomAnchor,\n onCustomAnchorAdd: React.useCallback(() => setHasCustomAnchor(true), []),\n onCustomAnchorRemove: React.useCallback(() => setHasCustomAnchor(false), []),\n modal,\n children\n }\n ) });\n};\nPopover.displayName = POPOVER_NAME;\nvar ANCHOR_NAME = \"PopoverAnchor\";\nvar PopoverAnchor = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...anchorProps } = props;\n const context = usePopoverContext(ANCHOR_NAME, __scopePopover);\n const popperScope = usePopperScope(__scopePopover);\n const { onCustomAnchorAdd, onCustomAnchorRemove } = context;\n React.useEffect(() => {\n onCustomAnchorAdd();\n return () => onCustomAnchorRemove();\n }, [onCustomAnchorAdd, onCustomAnchorRemove]);\n return /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { ...popperScope, ...anchorProps, ref: forwardedRef });\n }\n);\nPopoverAnchor.displayName = ANCHOR_NAME;\nvar TRIGGER_NAME = \"PopoverTrigger\";\nvar PopoverTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...triggerProps } = props;\n const context = usePopoverContext(TRIGGER_NAME, __scopePopover);\n const popperScope = usePopperScope(__scopePopover);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n const trigger = /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.contentId,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n return context.hasCustomAnchor ? trigger : /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { asChild: true, ...popperScope, children: trigger });\n }\n);\nPopoverTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"PopoverPortal\";\nvar [PortalProvider, usePortalContext] = createPopoverContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar PopoverPortal = (props) => {\n const { __scopePopover, forceMount, children, container } = props;\n const context = usePopoverContext(PORTAL_NAME, __scopePopover);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopePopover, forceMount, children: /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children }) }) });\n};\nPopoverPortal.displayName = PORTAL_NAME;\nvar CONTENT_NAME = \"PopoverContent\";\nvar PopoverContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopePopover);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = usePopoverContext(CONTENT_NAME, props.__scopePopover);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(PopoverContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(PopoverContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }\n);\nPopoverContent.displayName = CONTENT_NAME;\nvar Slot = createSlot(\"PopoverContent.RemoveScroll\");\nvar PopoverContentModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = usePopoverContext(CONTENT_NAME, props.__scopePopover);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, contentRef);\n const isRightClickOutsideRef = React.useRef(false);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, children: /* @__PURE__ */ jsx(\n PopoverContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: true,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n if (!isRightClickOutsideRef.current) context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(\n props.onPointerDownOutside,\n (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n isRightClickOutsideRef.current = isRightClick;\n },\n { checkForDefaultPrevented: false }\n ),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault(),\n { checkForDefaultPrevented: false }\n )\n }\n ) });\n }\n);\nvar PopoverContentNonModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = usePopoverContext(CONTENT_NAME, props.__scopePopover);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n PopoverContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }\n);\nvar PopoverContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopePopover,\n trapFocus,\n onOpenAutoFocus,\n onCloseAutoFocus,\n disableOutsidePointerEvents,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside,\n onInteractOutside,\n ...contentProps\n } = props;\n const context = usePopoverContext(CONTENT_NAME, __scopePopover);\n const popperScope = usePopperScope(__scopePopover);\n useFocusGuards();\n return /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n asChild: true,\n disableOutsidePointerEvents,\n onInteractOutside,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside,\n onDismiss: () => context.onOpenChange(false),\n children: /* @__PURE__ */ jsx(\n PopperPrimitive.Content,\n {\n \"data-state\": getState(context.open),\n role: \"dialog\",\n id: context.contentId,\n ...popperScope,\n ...contentProps,\n ref: forwardedRef,\n style: {\n ...contentProps.style,\n // re-namespace exposed content custom properties\n ...{\n \"--radix-popover-content-transform-origin\": \"var(--radix-popper-transform-origin)\",\n \"--radix-popover-content-available-width\": \"var(--radix-popper-available-width)\",\n \"--radix-popover-content-available-height\": \"var(--radix-popper-available-height)\",\n \"--radix-popover-trigger-width\": \"var(--radix-popper-anchor-width)\",\n \"--radix-popover-trigger-height\": \"var(--radix-popper-anchor-height)\"\n }\n }\n }\n )\n }\n )\n }\n );\n }\n);\nvar CLOSE_NAME = \"PopoverClose\";\nvar PopoverClose = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...closeProps } = props;\n const context = usePopoverContext(CLOSE_NAME, __scopePopover);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }\n);\nPopoverClose.displayName = CLOSE_NAME;\nvar ARROW_NAME = \"PopoverArrow\";\nvar PopoverArrow = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...arrowProps } = props;\n const popperScope = usePopperScope(__scopePopover);\n return /* @__PURE__ */ jsx(PopperPrimitive.Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });\n }\n);\nPopoverArrow.displayName = ARROW_NAME;\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nvar Root2 = Popover;\nvar Anchor2 = PopoverAnchor;\nvar Trigger = PopoverTrigger;\nvar Portal = PopoverPortal;\nvar Content2 = PopoverContent;\nvar Close = PopoverClose;\nvar Arrow2 = PopoverArrow;\nexport {\n Anchor2 as Anchor,\n Arrow2 as Arrow,\n Close,\n Content2 as Content,\n Popover,\n PopoverAnchor,\n PopoverArrow,\n PopoverClose,\n PopoverContent,\n PopoverPortal,\n PopoverTrigger,\n Portal,\n Root2 as Root,\n Trigger,\n createPopoverScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as Popover from '@radix-ui/react-popover'\nimport * as React from 'react'\nimport { Await, Link, useLoaderData } from 'react-router'\nimport { Icon } from '#app/components/icons.tsx'\nimport {\n\tOnboardingBadge,\n\tuseOnboardingIndicator,\n} from '#app/components/onboarding-indicator.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.tsx'\nimport { LaunchEditor } from '#app/routes/launch-editor.tsx'\nimport { SetAppToPlayground } from '#app/routes/set-playground.tsx'\nimport { type Route as LayoutRoute } from '../+types/_layout.tsx'\n\nfunction TouchedFiles({\n\tdiffFilesPromise,\n}: {\n\tdiffFilesPromise: LayoutRoute.ComponentProps['loaderData']['diffFiles']\n}) {\n\tconst data = useLoaderData<LayoutRoute.ComponentProps['loaderData']>()\n\tconst [showFilesBadge, dismissFilesBadge] =\n\t\tuseOnboardingIndicator('files-popover')\n\n\tconst [open, setOpen] = React.useState(false)\n\tconst contentRef = React.useRef<HTMLDivElement>(null)\n\n\tfunction handleOpenChange(isOpen: boolean) {\n\t\tsetOpen(isOpen)\n\t\t// Mark as complete when opening the popover for the first time\n\t\tif (isOpen) {\n\t\t\tdismissFilesBadge()\n\t\t}\n\t}\n\n\tfunction handleLaunchUpdate() {\n\t\tsetOpen(false)\n\t}\n\n\tconst appName = data.playground?.appName\n\n\treturn (\n\t\t<>\n\t\t\t<Popover.Root open={open} onOpenChange={handleOpenChange}>\n\t\t\t\t<Popover.Trigger asChild>\n\t\t\t\t\t<button\n\t\t\t\t\t\tclassName=\"relative flex h-full items-center gap-1 border-r px-6 py-3 font-mono text-sm uppercase\"\n\t\t\t\t\t\taria-label=\"Relevant Files\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon name=\"Files\" />\n\t\t\t\t\t\t<span className=\"hidden @min-[640px]:inline\">Files</span>\n\t\t\t\t\t\t{showFilesBadge ? (\n\t\t\t\t\t\t\t<OnboardingBadge tooltip=\"Click to see which files to edit!\" />\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</button>\n\t\t\t\t</Popover.Trigger>\n\t\t\t\t<Popover.Portal>\n\t\t\t\t\t<Popover.Content\n\t\t\t\t\t\tref={contentRef}\n\t\t\t\t\t\tclassName=\"slideRightContent lg:slideUpContent invert-theme bg-background text-foreground z-10 rounded px-9 py-8 select-none\"\n\t\t\t\t\t\talign=\"start\"\n\t\t\t\t\t\tsideOffset={5}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"launch-editor-wrapper\">\n\t\t\t\t\t\t\t<strong className=\"inline-block px-2 pb-2 font-semibold uppercase\">\n\t\t\t\t\t\t\t\tRelevant Files\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground mb-4 max-w-2xs px-2 text-sm\">\n\t\t\t\t\t\t\t\tThese are the files you'll need to modify for this exercise.\n\t\t\t\t\t\t\t\tClick any file to open it directly in your editor at the right\n\t\t\t\t\t\t\t\tlocation.{' '}\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto=\"/guide#file-links\"\n\t\t\t\t\t\t\t\t\tclassName=\"text-highlight underline\"\n\t\t\t\t\t\t\t\t\tonClick={() => setOpen(false)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tLearn more →\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{data.problem &&\n\t\t\t\t\t\t\tdata.playground?.appName !== data.problem.name ? (\n\t\t\t\t\t\t\t\t<div className=\"mb-2 rounded p-1 font-mono font-medium\">\n\t\t\t\t\t\t\t\t\t<SetAppToPlayground appName={data.problem.name} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<div id=\"files\">\n\t\t\t\t\t\t\t\t<React.Suspense\n\t\t\t\t\t\t\t\t\tfallback={\n\t\t\t\t\t\t\t\t\t\t<SimpleTooltip content=\"Loading diff\">\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex justify-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"Refresh\" className=\"h-8 w-8 animate-spin\" />\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Await\n\t\t\t\t\t\t\t\t\t\tresolve={diffFilesPromise}\n\t\t\t\t\t\t\t\t\t\terrorElement={\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-foreground-destructive\">\n\t\t\t\t\t\t\t\t\t\t\t\tSomething went wrong.\n\t\t\t\t\t\t\t\t\t\t\t</div>\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{(diffFiles) => {\n\t\t\t\t\t\t\t\t\t\t\tif (!diffFiles) {\n\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<p className=\"text-foreground-destructive\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tUnable to determine diff\n\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (typeof diffFiles === 'string') {\n\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<p className=\"text-foreground-destructive\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{diffFiles}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (!diffFiles.length) {\n\t\t\t\t\t\t\t\t\t\t\t\treturn <p>No files changed</p>\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\tconst props =\n\t\t\t\t\t\t\t\t\t\t\t\tappName || ENV.EPICSHOP_GITHUB_ROOT\n\t\t\t\t\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"You must 'Set to Playground' before opening a file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName: 'not-allowed',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t<ul {...props}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{diffFiles.length > 1 && !ENV.EPICSHOP_DEPLOYED ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"border-opacity-50 mb-2 border-b border-b-gray-50 pb-2 font-sans\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<LaunchEditor\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tappFile={diffFiles.map(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(file) => `${file.path},${file.line},1`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tappName=\"playground\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonUpdate={handleLaunchUpdate}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p>Open All Files</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</LaunchEditor>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{diffFiles.map((file) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<li key={file.path} data-state={file.status}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<LaunchEditor\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tappFile={`${file.path},${file.line},1`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tappName={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? (data.problem?.name ?? 'playground')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: 'playground'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonUpdate={handleLaunchUpdate}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<code>{file.path}</code>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</LaunchEditor>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t</Await>\n\t\t\t\t\t\t\t\t</React.Suspense>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</Popover.Content>\n\t\t\t\t</Popover.Portal>\n\t\t\t</Popover.Root>\n\t\t</>\n\t)\n}\n\nexport default TouchedFiles\n","import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetAppDisplayName,\n\tgetAppPageRoute,\n\tgetApps,\n\tgetExerciseApp,\n\tgetNextExerciseApp,\n\tgetPrevExerciseApp,\n\tisExerciseStepApp,\n\tisPlaygroundApp,\n\trequireExercise,\n\trequireExerciseApp,\n\ttype App,\n\ttype ExerciseStepApp,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getDiffFiles } from '@epic-web/workshop-utils/diff.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport { useRef, useState } from 'react'\nimport {\n\tLink,\n\tOutlet,\n\tdata,\n\tredirect,\n\ttype HeadersFunction,\n} from 'react-router'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { ProgressToggle } from '#app/routes/progress.tsx'\nimport { SetAppToPlayground } from '#app/routes/set-playground.tsx'\nimport { getExercisePath } from '#app/utils/misc.tsx'\nimport { getRootMatchLoaderData } from '#app/utils/root-loader.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.ts'\nimport {\n\tgetSplitPercentFromRequest,\n\tsetSplitPercentCookie,\n\tstartSplitDrag,\n} from '#app/utils/split-layout.ts'\nimport { getStep404Data } from '../__shared/error-boundary.server.ts'\nimport { Exercise404ErrorBoundary } from '../__shared/error-boundary.tsx'\nimport { type Route } from './+types/_layout.tsx'\nimport { StepMdx } from './__shared/step-mdx.tsx'\nimport TouchedFiles from './__shared/touched-files.tsx'\n\nfunction pageTitle(\n\tdata: Awaited<Route.ComponentProps['loaderData']> | undefined,\n\tworkshopTitle?: string,\n) {\n\tconst exerciseNumber =\n\t\tdata?.exerciseStepApp.exerciseNumber.toString().padStart(2, '0') ?? '00'\n\tconst stepNumber =\n\t\tdata?.exerciseStepApp.stepNumber.toString().padStart(2, '0') ?? '00'\n\tconst emoji = (\n\t\t{\n\t\t\tproblem: '💪',\n\t\t\tsolution: '🏁',\n\t\t} as const\n\t)[data?.type ?? 'problem']\n\tconst title = data?.[data.type]?.title ?? 'N/A'\n\treturn {\n\t\temoji,\n\t\tstepNumber,\n\t\ttitle,\n\t\texerciseNumber,\n\t\texerciseTitle: data?.exerciseTitle ?? 'Unknown exercise',\n\t\tworkshopTitle,\n\t\ttype: data?.type ?? 'problem',\n\t}\n}\n\nexport const meta: Route.MetaFunction = ({ loaderData, matches, params }) => {\n\tconst rootData = getRootMatchLoaderData(matches)\n\tif (!loaderData || !rootData) return [{ title: '🦉 | Error' }]\n\tconst { emoji, stepNumber, title, exerciseNumber, exerciseTitle } =\n\t\tpageTitle(loaderData)\n\n\treturn getSeoMetaTags({\n\t\ttitle: `${emoji} | ${stepNumber}. ${title} | ${exerciseNumber}. ${exerciseTitle} | ${rootData.workshopTitle}`,\n\t\tdescription: `${params.type} step for exercise ${exerciseNumber}. ${exerciseTitle}`,\n\t\togTitle: title,\n\t\togDescription: `${exerciseTitle} step ${Number(stepNumber)} ${params.type}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('exerciseStepTypeLayoutLoader')\n\tconst url = new URL(request.url)\n\tconst { type } = params\n\tconst { title: workshopTitle } = getWorkshopConfig()\n\n\tconst cacheOptions = { request, timings }\n\n\tconst [allAppsFull, problemApp, solutionApp] = await Promise.all([\n\t\tgetApps(cacheOptions),\n\t\tgetExerciseApp({ ...params, type: 'problem' }, cacheOptions),\n\t\tgetExerciseApp({ ...params, type: 'solution' }, cacheOptions),\n\t])\n\n\tconst reqUrl = new URL(request.url)\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\tif (\n\t\t(type === 'problem' && !problemApp) ||\n\t\t(type === 'solution' && !solutionApp)\n\t) {\n\t\tconst errorData = await getStep404Data({\n\t\t\texerciseNumber: params.exerciseNumber,\n\t\t})\n\t\tthrow Response.json(errorData, { status: 404 })\n\t}\n\n\tconst exerciseStepApp = await requireExerciseApp(params, cacheOptions)\n\n\tconst playgroundApp = allAppsFull.find(isPlaygroundApp)\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\tconst exerciseId = getStepId(exerciseStepApp)\n\tconst exerciseIndex = allApps.findIndex((step) => step.stepId === exerciseId)\n\n\t// These depend on exerciseStepApp\n\tconst [exercise, nextApp, prevApp] = await Promise.all([\n\t\trequireExercise(exerciseStepApp.exerciseNumber, cacheOptions),\n\t\tgetNextExerciseApp(exerciseStepApp, cacheOptions),\n\t\tgetPrevExerciseApp(exerciseStepApp, cacheOptions),\n\t])\n\n\tconst exerciseApps = allAppsFull\n\t\t.filter(isExerciseStepApp)\n\t\t.filter((app) => app.exerciseNumber === exerciseStepApp.exerciseNumber)\n\tconst isLastStep =\n\t\texerciseApps[exerciseApps.length - 1]?.name === exerciseStepApp.name\n\tconst isFirstStep = exerciseApps[0]?.name === exerciseStepApp.name\n\n\tconst articleId = `workshop-${slugify(workshopTitle)}-${\n\t\texercise.exerciseNumber\n\t}-${exerciseStepApp.stepNumber}-${exerciseStepApp.type}`\n\n\tconst subroute = url.pathname.split(\n\t\t`/exercise/${params.exerciseNumber}/${params.stepNumber}/${params.type}/`,\n\t)[1]\n\n\t// read persisted split percentage from cookie (10-90, default 50)\n\tconst splitPercent = getSplitPercentFromRequest(request, 50)\n\n\treturn data(\n\t\t{\n\t\t\tarticleId,\n\t\t\ttype: params.type as 'problem' | 'solution',\n\t\t\texerciseStepApp,\n\t\t\texerciseTitle: exercise.title,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(exerciseStepApp.epicVideoEmbeds),\n\t\t\texerciseIndex,\n\t\t\tallApps,\n\t\t\tsplitPercent,\n\t\t\tprevStepLink: isFirstStep\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/exercise/${exerciseStepApp.exerciseNumber\n\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t.padStart(2, '0')}`,\n\t\t\t\t\t}\n\t\t\t\t: prevApp\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tto: getAppPageRoute(prevApp, {\n\t\t\t\t\t\t\t\tsubroute,\n\t\t\t\t\t\t\t\tsearchParams: url.searchParams,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\tnextStepLink: isLastStep\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/exercise/${exerciseStepApp.exerciseNumber\n\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t.padStart(2, '0')}/finished`,\n\t\t\t\t\t}\n\t\t\t\t: nextApp\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tto: getAppPageRoute(nextApp, {\n\t\t\t\t\t\t\t\tsubroute,\n\t\t\t\t\t\t\t\tsearchParams: url.searchParams,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\tplayground: playgroundApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'playground',\n\t\t\t\t\t\tappName: playgroundApp.appName,\n\t\t\t\t\t\tname: playgroundApp.name,\n\t\t\t\t\t\tfullPath: playgroundApp.fullPath,\n\t\t\t\t\t\tdev: playgroundApp.dev,\n\t\t\t\t\t\tisUpToDate: playgroundApp.isUpToDate,\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\ttitle: problemApp.title,\n\t\t\t\t\t\tname: problemApp.name,\n\t\t\t\t\t\tfullPath: problemApp.fullPath,\n\t\t\t\t\t\tdev: problemApp.dev,\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\ttitle: solutionApp.title,\n\t\t\t\t\t\tname: solutionApp.name,\n\t\t\t\t\t\tfullPath: solutionApp.fullPath,\n\t\t\t\t\t\tdev: solutionApp.dev,\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tdiffFiles:\n\t\t\t\tproblemApp && solutionApp\n\t\t\t\t\t? getDiffFiles(problemApp, solutionApp, {\n\t\t\t\t\t\t\t...cacheOptions,\n\t\t\t\t\t\t\tforceFresh: url.searchParams.get('forceFresh') === 'diff',\n\t\t\t\t\t\t}).catch((e) => {\n\t\t\t\t\t\t\tconsole.error(e)\n\t\t\t\t\t\t\treturn 'There was a problem generating the diff (check the terminal output)'\n\t\t\t\t\t\t})\n\t\t\t\t\t: 'No diff available',\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\nexport default function ExercisePartRoute({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tconst inBrowserBrowserRef = useRef<InBrowserBrowserRef>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst leftPaneRef = useRef<HTMLDivElement>(null)\n\tconst [splitPercent, setSplitPercent] = useState<number>(data.splitPercent)\n\n\tconst titleBits = pageTitle(data)\n\n\tuseRevalidationWS({\n\t\twatchPaths: [`${data.exerciseStepApp.relativePath}/README.mdx`],\n\t})\n\n\tconst showPlaygroundIndicator = data.problem\n\t\t? data.playground?.appName !== data.problem.name\n\t\t: false\n\n\treturn (\n\t\t<div className=\"flex max-w-full grow flex-col\">\n\t\t\t<main\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName=\"flex grow flex-col overflow-y-auto sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row lg:overflow-y-hidden\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative flex min-w-0 flex-none basis-auto flex-col sm:col-span-1 sm:row-span-1 lg:h-full lg:basis-(--split-pct)\"\n\t\t\t\t\tstyle={{ ['--split-pct' as any]: `${splitPercent}%` }}\n\t\t\t\t\tref={leftPaneRef}\n\t\t\t\t>\n\t\t\t\t\t<h1 className=\"@container h-14 border-b pr-5 pl-10 text-sm leading-tight font-medium\">\n\t\t\t\t\t\t<div className=\"flex h-14 items-center justify-between gap-x-2 py-2 whitespace-nowrap\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2 uppercase\">\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto={getExercisePath(data.exerciseStepApp.exerciseNumber)}\n\t\t\t\t\t\t\t\t\tclassName=\"hover:underline\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span>{titleBits.exerciseNumber}.</span>\n\t\t\t\t\t\t\t\t\t<span className=\"hidden @min-[500px]:inline\">\n\t\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\t\t{titleBits.exerciseTitle}\n\t\t\t\t\t\t\t\t\t</span>\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<Link to=\".\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t<span>{titleBits.stepNumber}.</span>\n\t\t\t\t\t\t\t\t\t<span className=\"hidden @min-[300px]:inline\">\n\t\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\t\t{titleBits.title}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<span> ({titleBits.emoji}</span>\n\t\t\t\t\t\t\t\t\t<span className=\"hidden @min-[400px]:inline\">\n\t\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\t\t{titleBits.type}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<span>)</span>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{data.problem &&\n\t\t\t\t\t\t\t(data.playground?.appName !== data.problem.name ||\n\t\t\t\t\t\t\t\t!data.playground?.isUpToDate) ? (\n\t\t\t\t\t\t\t\t<SetAppToPlayground\n\t\t\t\t\t\t\t\t\tappName={data.problem.name}\n\t\t\t\t\t\t\t\t\tisOutdated={data.playground?.isUpToDate === false}\n\t\t\t\t\t\t\t\t\thideTextOnNarrow\n\t\t\t\t\t\t\t\t\tshowOnboardingIndicator={showPlaygroundIndicator}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\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\tid={data.articleId}\n\t\t\t\t\t\tkey={data.articleId}\n\t\t\t\t\t\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex w-full max-w-none scroll-pt-6 flex-col justify-between space-y-6 p-2 sm:p-10 sm:pt-8 lg:h-full lg:flex-1 lg:overflow-y-auto\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.exerciseStepApp.instructionsCode ? (\n\t\t\t\t\t\t\t<StepMdx inBrowserBrowserRef={inBrowserBrowserRef} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"flex h-full items-center justify-center text-lg\">\n\t\t\t\t\t\t\t\t<p>No instructions yet...</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"mt-auto flex justify-between\">\n\t\t\t\t\t\t\t{data.prevStepLink ? (\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto={data.prevStepLink.to}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous Step\"\n\t\t\t\t\t\t\t\t\tdata-keyboard-action=\"g+p\"\n\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span aria-hidden>←</span>\n\t\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\"> Previous</span>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<span />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{data.nextStepLink ? (\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto={data.nextStepLink.to}\n\t\t\t\t\t\t\t\t\taria-label=\"Next Step\"\n\t\t\t\t\t\t\t\t\tdata-keyboard-action=\"g+n\"\n\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\">Next </span>\n\t\t\t\t\t\t\t\t\t<span aria-hidden>→</span>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<span />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration\n\t\t\t\t\t\telementQuery={`#${data.articleId}`}\n\t\t\t\t\t\tkey={`scroll-${data.articleId}`}\n\t\t\t\t\t/>\n\t\t\t\t\t{data.type === 'solution' ? (\n\t\t\t\t\t\t<ProgressToggle\n\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t\texerciseNumber={data.exerciseStepApp.exerciseNumber}\n\t\t\t\t\t\t\tstepNumber={data.exerciseStepApp.stepNumber}\n\t\t\t\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"@container flex h-16 justify-between border-t border-b-4 lg:border-b-0\">\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<div className=\"h-full\">\n\t\t\t\t\t\t\t\t<TouchedFiles diffFilesPromise={data.diffFiles} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\t\t\tappName={data.exerciseStepApp.name}\n\t\t\t\t\t\t\trelativePath={`${data.exerciseStepApp.relativePath}/README.mdx`}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<NavChevrons\n\t\t\t\t\t\t\tprev={\n\t\t\t\t\t\t\t\tdata.prevStepLink\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tto: data.prevStepLink.to,\n\t\t\t\t\t\t\t\t\t\t\t'aria-label': 'Previous Step',\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: null\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnext={\n\t\t\t\t\t\t\t\tdata.nextStepLink\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tto: data.nextStepLink.to,\n\t\t\t\t\t\t\t\t\t\t\t'aria-label': 'Next Step',\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: null\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\trole=\"separator\"\n\t\t\t\t\taria-orientation=\"vertical\"\n\t\t\t\t\ttitle=\"Drag to resize\"\n\t\t\t\t\tclassName=\"bg-border hover:bg-accent hidden w-1 cursor-col-resize lg:block\"\n\t\t\t\t\tonMouseDown={(event) =>\n\t\t\t\t\t\tstartSplitDrag({\n\t\t\t\t\t\t\tcontainer: containerRef.current,\n\t\t\t\t\t\t\tinitialClientX: event.clientX,\n\t\t\t\t\t\t\tsetSplitPercent,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tonDoubleClick={() => {\n\t\t\t\t\t\tsetSplitPercent(setSplitPercentCookie(50))\n\t\t\t\t\t}}\n\t\t\t\t\tonTouchStart={(event) => {\n\t\t\t\t\t\tconst firstTouch = event.touches?.[0]\n\t\t\t\t\t\tif (!firstTouch) return\n\t\t\t\t\t\tstartSplitDrag({\n\t\t\t\t\t\t\tcontainer: containerRef.current,\n\t\t\t\t\t\t\tinitialClientX: firstTouch.clientX,\n\t\t\t\t\t\t\tsetSplitPercent,\n\t\t\t\t\t\t})\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<div className=\"flex min-h-[50vh] min-w-0 flex-none lg:min-h-0 lg:flex-1\">\n\t\t\t\t\t<Outlet context={{ inBrowserBrowserRef }} />\n\t\t\t\t</div>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn (\n\t\t<GeneralErrorBoundary\n\t\t\tclassName=\"container flex items-center justify-center\"\n\t\t\tstatusHandlers={{\n\t\t\t\t404: Exercise404ErrorBoundary,\n\t\t\t}}\n\t\t/>\n\t)\n}\n"],"names":["StepContext","React.createContext","useStepContext","context","React.useContext","StepContextProvider","children","inBrowserBrowserRef","stepMdxComponents","DiffLink","PrevDiffLink","NextDiffLink","InlineFile","LinkToApp","StepMdx","data","useLoaderData","jsx","EpicVideoInfoProvider","Mdx","withParam","searchParams","key","value","newSearchParams","app","fullPage","app1","app2","to","getAppName","input","stepIndex","name","stepName","params","app1Name","app2Name","jsxs","pathToDiff","Link","file","type","props","info","iconsSvg","LaunchEditor","SimpleTooltip","getPreviewType","preview","appTo","useSearchParams","requestInfo","useRequestInfo","previewAppUrl","getBaseUrl","href","cn","event","Icon","POPOVER_NAME","createPopoverContext","createContextScope","createPopperScope","usePopperScope","PopoverProvider","usePopoverContext","Popover","__scopePopover","openProp","defaultOpen","onOpenChange","modal","popperScope","triggerRef","React.useRef","hasCustomAnchor","setHasCustomAnchor","React.useState","open","setOpen","useControllableState","PopperPrimitive.Root","useId","React.useCallback","prevOpen","ANCHOR_NAME","PopoverAnchor","React.forwardRef","forwardedRef","anchorProps","onCustomAnchorAdd","onCustomAnchorRemove","React.useEffect","PopperPrimitive.Anchor","TRIGGER_NAME","PopoverTrigger","triggerProps","composedTriggerRef","useComposedRefs","trigger","Primitive","getState","composeEventHandlers","PORTAL_NAME","PortalProvider","usePortalContext","PopoverPortal","forceMount","container","Presence","PortalPrimitive","CONTENT_NAME","PopoverContent","portalContext","contentProps","PopoverContentModal","PopoverContentNonModal","Slot","createSlot","contentRef","composedRefs","isRightClickOutsideRef","content","hideOthers","RemoveScroll","PopoverContentImpl","originalEvent","ctrlLeftClick","isRightClick","hasInteractedOutsideRef","hasPointerDownOutsideRef","target","trapFocus","onOpenAutoFocus","onCloseAutoFocus","disableOutsidePointerEvents","onEscapeKeyDown","onPointerDownOutside","onFocusOutside","onInteractOutside","useFocusGuards","FocusScope","DismissableLayer","PopperPrimitive.Content","CLOSE_NAME","PopoverClose","closeProps","ARROW_NAME","PopoverArrow","arrowProps","PopperPrimitive.Arrow","Root2","Trigger","Portal","Content2","TouchedFiles","diffFilesPromise","showFilesBadge","dismissFilesBadge","useOnboardingIndicator","handleOpenChange","isOpen","handleLaunchUpdate","appName","Popover.Root","Popover.Trigger","OnboardingBadge","Popover.Portal","Popover.Content","SetAppToPlayground","React.Suspense","Await","diffFiles","pageTitle","workshopTitle","exerciseNumber","exerciseStepApp","toString","padStart","stepNumber","emoji","problem","solution","title","exerciseTitle","meta","loaderData","matches","rootData","getRootMatchLoaderData","getSeoMetaTags","description","ogTitle","ogDescription","Number","instructor","_layout","_UNSAFE_withComponentProps","useRef","containerRef","leftPaneRef","splitPercent","setSplitPercent","useState","titleBits","useRevalidationWS","watchPaths","relativePath","showPlaygroundIndicator","playground","className","ref","style","getExercisePath","isUpToDate","isOutdated","hideTextOnNarrow","showOnboardingIndicator","id","articleId","instructionsCode","prevStepLink","prefetch","nextStepLink","ElementScrollRestoration","elementQuery","ProgressToggle","EditFileOnGitHub","NavChevrons","prev","next","role","onMouseDown","startSplitDrag","current","initialClientX","clientX","onDoubleClick","setSplitPercentCookie","onTouchStart","firstTouch","touches","Outlet","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","GeneralErrorBoundary","statusHandlers","Exercise404ErrorBoundary"],"mappings":"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","x_google_ignoreList":[1]}
@@ -1,2 +0,0 @@
1
- import{w as t,b as p}from"./chunk-EPOLDU6W-BCLmut3y.js";import{j as s}from"./jsx-runtime-C5WNSv3b.js";import{r as i}from"./index-CqIc3cxq.js";import{P as m}from"./preview-CiDtuQCc.js";import"./misc-DVYuZMjW.js";import"./button-CIlVtsau.js";import"./loading-CUydCGD3.js";import"./index-BW8stNyh.js";import"./tooltip-Chzzs4KB.js";import"./index-vDCSPjrM.js";import"./root-loader-BOzEMapJ.js";import"./pe-CIZUOJMr.js";import"./schemas-Uj5SZtvt.js";import"./progress-bar-B27isaGl.js";const L=t(function(){const{appInfo:r}=p(),o=i.useRef(null);return s.jsx(m,{appInfo:r,inBrowserBrowserRef:o})});export{L as default};
2
- //# sourceMappingURL=app-TcFAQB2o.js.map
@@ -1,2 +0,0 @@
1
- import{U as a,C as n}from"./mermaid.core-D3y7PO8B.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
2
- //# sourceMappingURL=channel-BLJkdd1O.js.map
@@ -1,2 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-B4BG7PRW-C2qQTBXm.js";import{_ as i}from"./mermaid.core-D3y7PO8B.js";import"./chunk-FMBD7UC4-CyJoWksV.js";import"./chunk-55IACEB6-BOr0rES3.js";import"./chunk-QN33PNHL-BpbvTQdp.js";import"./preload-helper-BXl3LOEh.js";import"./misc-DVYuZMjW.js";import"./jsx-runtime-C5WNSv3b.js";import"./index-CqIc3cxq.js";import"./chunk-EPOLDU6W-BCLmut3y.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};
2
- //# sourceMappingURL=classDiagram-2ON5EDUG-_kfNpv_f.js.map
@@ -1,2 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-B4BG7PRW-C2qQTBXm.js";import{_ as i}from"./mermaid.core-D3y7PO8B.js";import"./chunk-FMBD7UC4-CyJoWksV.js";import"./chunk-55IACEB6-BOr0rES3.js";import"./chunk-QN33PNHL-BpbvTQdp.js";import"./preload-helper-BXl3LOEh.js";import"./misc-DVYuZMjW.js";import"./jsx-runtime-C5WNSv3b.js";import"./index-CqIc3cxq.js";import"./chunk-EPOLDU6W-BCLmut3y.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};
2
- //# sourceMappingURL=classDiagram-v2-WZHVMYZB-_kfNpv_f.js.map
@@ -1,2 +0,0 @@
1
- import{b as r}from"./_baseUniq-BbljtzXr.js";var e=4;function a(o){return r(o,e)}export{a as c};
2
- //# sourceMappingURL=clone-CztDUJhf.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"discord-CuxZiU8E.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,9 +0,0 @@
1
- import{w as c,L as d}from"./chunk-EPOLDU6W-BCLmut3y.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{r as n}from"./index-CqIc3cxq.js";const p={getSitemapEntries:()=>[{route:"/guide"}]},l=[{id:"tutorial",label:"Tutorial"},{id:"logging-in",label:"Logging In"},{id:"workshop-structure",label:"Workshop Structure"},{id:"lesson-page",label:"The Lesson Page"},{id:"file-links",label:"File Links"},{id:"setting-playground",label:"Setting the Playground"},{id:"diff-tab",label:"The Diff Tab"},{id:"tests",label:"Tests"},{id:"keyboard-shortcuts",label:"Keyboard Shortcuts"},{id:"cli-commands",label:"CLI Commands"},{id:"ai-assistant",label:"AI Assistant (MCP)"},{id:"emoji-key",label:"Emoji Key"},{id:"need-help",label:"Need More Help?"}];function h({activeSection:i}){return e.jsxs("nav",{className:"sticky top-4 hidden lg:block",children:[e.jsx("h2",{className:"text-muted-foreground mb-3 text-sm font-semibold tracking-wide uppercase",children:"On this page"}),e.jsx("ul",{className:"space-y-2 text-sm",children:l.map(s=>e.jsx("li",{children:e.jsx("a",{href:`#${s.id}`,className:`block transition-colors ${i===s.id?"text-highlight font-medium":"text-muted-foreground hover:text-foreground"}`,children:s.label})},s.id))})]})}const g=c(function(){const[s,a]=n.useState(null);return n.useEffect(()=>{const r=new IntersectionObserver(o=>{for(const t of o)t.isIntersecting&&a(t.target.id)},{rootMargin:"-20% 0px -60% 0px",threshold:0});for(const o of l){const t=document.getElementById(o.id);t&&r.observe(t)}return()=>r.disconnect()},[]),e.jsx("div",{className:"h-full w-full overflow-y-auto",children:e.jsxs("div",{className:"container mt-12 flex max-w-5xl gap-12 pb-24",children:[e.jsxs("main",{className:"flex w-full max-w-3xl grow flex-col gap-8",children:[e.jsx("h1",{className:"text-h1 mb-4",children:"Workshop App Guide"}),e.jsx("p",{className:"text-lg",children:"This guide will help you get the most out of the Epic Workshop App. Whether you're just getting started or need help troubleshooting, you'll find useful information here."}),e.jsxs("div",{id:"tutorial",className:"bg-accent scroll-mt-8 rounded-lg p-6",children:[e.jsx("h2",{className:"text-h4 mb-2",children:"🎓 New to the Workshop App?"}),e.jsx("p",{className:"mb-4",children:"We highly recommend going through the official tutorial to learn all the features the workshop app has to offer:"}),e.jsx("code",{className:"bg-background block rounded p-3 font-mono text-sm",children:"npx epicshop add epicshop-tutorial"}),e.jsx("p",{className:"text-muted-foreground mt-2 text-sm",children:"This will add the tutorial workshop to your setup so you can learn at your own pace."})]}),e.jsxs("section",{id:"logging-in",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"Logging In"}),e.jsx("p",{className:"mb-4",children:"Logging in unlocks important features that enhance your learning experience:"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Progress tracking"})," – Your progress syncs across devices and persists between sessions"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Video access"})," – Watch premium workshop videos (requires a valid license)"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Discord integration"})," – Connect with the community and instructors"]})]}),e.jsx("h3",{className:"text-h5 mt-6 mb-3",children:"How to Log In"}),e.jsxs("p",{className:"mb-4",children:["Click the ",e.jsx("strong",{children:"Account"})," link in the navigation (top right) and follow the login prompts. You can also log in via the CLI:"]}),e.jsx("code",{className:"bg-muted mb-4 block rounded p-3 font-mono text-sm",children:"epicshop auth login"}),e.jsx("p",{className:"mb-4",children:"This opens a browser window where you can authenticate with your EpicWeb.dev, EpicReact.dev, or EpicAI.pro account."}),e.jsx("p",{className:"text-muted-foreground text-sm",children:"Tip: Log in early to start tracking your progress from the beginning!"})]}),e.jsxs("section",{id:"workshop-structure",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"Workshop Structure"}),e.jsx("p",{className:"mb-4",children:"Each workshop is a standalone project with a consistent structure:"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"exercises/"}),' – Contains the "problem" and "solution" versions of each step. Treat this as a reference for after the workshop.']}),e.jsxs("li",{children:[e.jsx("strong",{children:"playground/"})," – This is where your work takes place. We recommend opening this directory as its own editor instance for efficient file searching."]})]})]}),e.jsxs("section",{id:"lesson-page",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"The Lesson Page"}),e.jsx("p",{className:"mb-4",children:"When you click into a lesson, the app displays the video along with written content, code snippets, and other useful information. To the right is a pane with tabs:"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Playground"})," – Where you'll spend most of your time. You can interact with the app here or open it in a dedicated tab."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Problem"})," – The starting point of the exercise."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Solution"})," – The completed exercise state."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Diff"})," – Compare your current version against the finished state. Use this if you get stuck, but try to avoid it if possible."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Tests"})," – If the exercise includes tests, they'll appear here to verify your work."]})]})]}),e.jsxs("section",{id:"file-links",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"File Links"}),e.jsxs("p",{className:"mb-4",children:["At the bottom of a lesson page, the ",e.jsx("strong",{children:'"Files"'})," ","button opens a list of relevant files for the current exercise. Clicking a file opens it directly in your editor at the right location."]}),e.jsx("p",{className:"mb-4",children:"Key things to know:"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsx("li",{children:"Files are tied to your current Playground – make sure it's set to the lesson you're working on."}),e.jsxs("li",{children:["A ",e.jsx("strong",{children:'"+"'})," icon next to a filename means you need to create that file. Clicking it will create and open the file."]}),e.jsx("li",{children:'If you see a red "Set to Playground" link, click it to sync the playground for the current exercise.'})]}),e.jsx("h3",{id:"file-links-troubleshooting",className:"text-h4 mt-8 mb-4 scroll-mt-8",children:"Troubleshooting"}),e.jsxs("p",{className:"mb-4",children:["If you're unable to open file links from the workshop app, create a ",e.jsx("code",{className:"bg-muted rounded px-1",children:".env"})," file in the root of the workshop project and add:"]}),e.jsx("code",{className:"bg-muted mb-4 block rounded p-3 font-mono text-sm",children:'EPICSHOP_EDITOR="path/to/your/editor"'}),e.jsx("p",{className:"mb-4",children:"Examples:"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"VS Code:"})," ",e.jsx("code",{className:"bg-muted rounded px-1",children:"EPICSHOP_EDITOR=code"})]}),e.jsxs("li",{children:[e.jsx("strong",{children:"VS Code on Windows:"})," ",e.jsx("code",{className:"bg-muted rounded px-1",children:`EPICSHOP_EDITOR='"C:\\Program Files\\Microsoft VS Code\\bin\\code.cmd"'`})]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Cursor:"})," ",e.jsx("code",{className:"bg-muted rounded px-1",children:"EPICSHOP_EDITOR=cursor"})]})]}),e.jsx("p",{className:"text-muted-foreground mt-4 text-sm",children:"Note: If the path includes spaces, wrap it in quotes as shown in the Windows example."}),e.jsx("p",{className:"mt-4",children:`For Cursor/VS Code users, you can also install the 'code' command in your PATH by opening the Command Palette (⌘⇧P on Mac, Ctrl+Shift+P on Windows) and searching for "Install 'code' command in PATH".`})]}),e.jsxs("section",{id:"setting-playground",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"Setting the Playground"}),e.jsxs("p",{className:"mb-4",children:["If you navigate to a different exercise than what's currently loaded, a red ",e.jsx("strong",{children:'"Set to Playground"'})," link will appear. Clicking this syncs the playground for the appropriate exercise."]}),e.jsxs("p",{className:"bg-warning text-warning-foreground rounded-lg p-4",children:[e.jsx("strong",{children:"Important:"})," Always have your Playground set to the lesson you're working on! This is not automated because you might want to refer back to previous exercises without losing your current work."]})]}),e.jsxs("section",{id:"diff-tab",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"The Diff Tab"}),e.jsx("p",{className:"mb-4",children:"The diff tab helps you get unstuck when you're totally stuck. It shows the difference between your playground and the solution. This is especially useful for catching typos or small mistakes."}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("span",{className:"text-success font-mono",children:"+"})," lines (green) show code that needs to be added"]}),e.jsxs("li",{children:[e.jsx("span",{className:"text-foreground-destructive font-mono",children:"-"})," ","lines (red) show code that needs to be removed"]}),e.jsx("li",{children:"Unchanged lines provide context around the changes"})]}),e.jsx("p",{className:"text-muted-foreground mt-4 text-sm",children:"Tip: Try to avoid using the diff tab until you've made a solid attempt at the exercise. The learning happens in the struggle!"})]}),e.jsxs("section",{id:"tests",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"Tests"}),e.jsx("p",{className:"mb-4",children:"Some exercises include tests to verify your work. If available, they appear in the Tests tab. Tests can run in two ways:"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Script-based:"})," A button runs the test script and streams the output"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Browser-based:"})," Test files are compiled and run directly in the browser"]})]}),e.jsxs("p",{className:"mt-4",children:["Look for 🚨 ",e.jsx("strong",{children:"Alfred the Alert"})," in test failures for helpful explanations about what went wrong."]})]}),e.jsxs("section",{id:"keyboard-shortcuts",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"Keyboard Shortcuts"}),e.jsx("p",{className:"mb-4",children:"When the workshop server is running in your terminal, you can use these keyboard shortcuts:"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("kbd",{className:"bg-muted rounded px-2 py-1 font-mono text-sm",children:"u"})," ","– Check for and apply updates to the workshop"]}),e.jsxs("li",{children:[e.jsx("kbd",{className:"bg-muted rounded px-2 py-1 font-mono text-sm",children:"d"})," ","– Dismiss update notifications"]})]}),e.jsx("p",{className:"text-muted-foreground mt-4 text-sm",children:"The server automatically restarts after updates are applied."})]}),e.jsxs("section",{id:"cli-commands",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"CLI Commands"}),e.jsxs("p",{className:"mb-4",children:["The ",e.jsx("code",{className:"bg-muted rounded px-1",children:"epicshop"})," CLI provides useful commands for managing your workshop:"]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("code",{className:"bg-muted block rounded p-3 font-mono text-sm",children:"epicshop start"}),e.jsxs("p",{className:"text-muted-foreground mt-1 text-sm",children:["Start the workshop (or just run"," ",e.jsx("code",{className:"bg-muted rounded px-1",children:"npm start"}),")"]})]}),e.jsxs("div",{children:[e.jsx("code",{className:"bg-muted block rounded p-3 font-mono text-sm",children:"epicshop playground set"}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm",children:"Set the playground to the next incomplete step"})]}),e.jsxs("div",{children:[e.jsx("code",{className:"bg-muted block rounded p-3 font-mono text-sm",children:"epicshop diff"}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm",children:"Show the diff between your playground and the solution in the terminal"})]}),e.jsxs("div",{children:[e.jsx("code",{className:"bg-muted block rounded p-3 font-mono text-sm",children:"epicshop progress"}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm",children:"View your progress through the workshop"})]}),e.jsxs("div",{children:[e.jsx("code",{className:"bg-muted block rounded p-3 font-mono text-sm",children:"epicshop exercises"}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm",children:"List all exercises with completion status"})]})]}),e.jsxs("p",{className:"mt-4",children:["Run ",e.jsx("code",{className:"bg-muted rounded px-1",children:"epicshop --help"})," ","to see all available commands."]})]}),e.jsxs("section",{id:"ai-assistant",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"AI Assistant (MCP)"}),e.jsxs("p",{className:"mb-4",children:["If you use an AI assistant that supports"," ",e.jsx("a",{href:"https://modelcontextprotocol.io/",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"MCP (Model Context Protocol)"}),", you can install the Epic Workshop MCP server to enhance your learning experience."]}),e.jsx("h3",{className:"text-h5 mt-6 mb-3",children:"What it provides"}),e.jsxs("ul",{className:"list-disc space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Exercise context:"})," Your AI can understand what you're working on and provide relevant help"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Progress tracking:"})," Mark lessons complete directly through your AI"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Diff viewing:"})," Ask your AI to show you what changes are needed"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"File opening:"})," Have your AI open the relevant files in your editor"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Quiz mode:"})," Ask your AI to quiz you on workshop topics"]})]}),e.jsx("h3",{className:"text-h5 mt-6 mb-3",children:"Installation"}),e.jsx("p",{className:"mb-4",children:"Add the following to your AI assistant's MCP configuration (e.g., Claude Desktop):"}),e.jsx("pre",{className:"bg-muted overflow-x-auto rounded p-4 font-mono text-sm",children:`{
2
- "mcpServers": {
3
- "epicshop": {
4
- "command": "npx",
5
- "args": ["-y", "@epic-web/workshop-mcp"]
6
- }
7
- }
8
- }`}),e.jsx("p",{className:"text-muted-foreground mt-4 text-sm",children:"Make sure to run your AI assistant from within the workshop directory so the MCP server can find the right files."})]}),e.jsxs("section",{id:"emoji-key",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"Emoji Key"}),e.jsx("p",{className:"mb-4",children:"Each exercise has comments with helpful emoji characters:"}),e.jsxs("ul",{className:"space-y-2 pl-6",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"👨‍💼 Peter the Product Manager"})," – Helps you know what users want"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"🧝‍♀️ Kellie the Co-worker"})," – Your co-worker who sometimes does work ahead of your exercises"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"🐨 Kody the Koala"})," – Tells you when there's something specific to do"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"🦺 Lily the Life Jacket"})," – Helps with TypeScript-specific parts"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"💰 Marty the Money Bag"})," – Gives specific tips and sometimes code"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"📝 Nancy the Notepad"})," – Encourages you to take notes"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"🦉 Olivia the Owl"})," – Gives useful tidbits and best practices"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"📜 Dominic the Document"})," – Links to useful documentation"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"💣 Barry the Bomb"})," – Indicates code to delete"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"💪 Matthew the Muscle"})," – Indicates you're working with an exercise"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"🏁 Chuck the Checkered Flag"})," – Indicates a final step"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"🚨 Alfred the Alert"})," – Shows up in test failures with explanations"]})]})]}),e.jsxs("section",{id:"need-help",className:"scroll-mt-8",children:[e.jsx("h2",{className:"text-h3 mb-4",children:"Need More Help?"}),e.jsxs("p",{children:["Visit our"," ",e.jsx(d,{to:"/support",className:"underline",children:"Support page"})," ","for additional help options, including Discord access and how to report issues."]})]})]}),e.jsx("aside",{className:"hidden w-48 shrink-0 lg:block",children:e.jsx(h,{activeSection:s})})]})})});export{g as default,p as handle};
9
- //# sourceMappingURL=guide-B4wAqzq_.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guide-B4wAqzq_.js","sources":["../../../app/routes/_app+/guide.tsx"],"sourcesContent":["import { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport * as React from 'react'\nimport { Link } from 'react-router'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => [{ route: '/guide' }],\n}\n\nconst sections = [\n\t{ id: 'tutorial', label: 'Tutorial' },\n\t{ id: 'logging-in', label: 'Logging In' },\n\t{ id: 'workshop-structure', label: 'Workshop Structure' },\n\t{ id: 'lesson-page', label: 'The Lesson Page' },\n\t{ id: 'file-links', label: 'File Links' },\n\t{ id: 'setting-playground', label: 'Setting the Playground' },\n\t{ id: 'diff-tab', label: 'The Diff Tab' },\n\t{ id: 'tests', label: 'Tests' },\n\t{ id: 'keyboard-shortcuts', label: 'Keyboard Shortcuts' },\n\t{ id: 'cli-commands', label: 'CLI Commands' },\n\t{ id: 'ai-assistant', label: 'AI Assistant (MCP)' },\n\t{ id: 'emoji-key', label: 'Emoji Key' },\n\t{ id: 'need-help', label: 'Need More Help?' },\n] as const\n\nfunction TableOfContents({ activeSection }: { activeSection: string | null }) {\n\treturn (\n\t\t<nav className=\"sticky top-4 hidden lg:block\">\n\t\t\t<h2 className=\"text-muted-foreground mb-3 text-sm font-semibold tracking-wide uppercase\">\n\t\t\t\tOn this page\n\t\t\t</h2>\n\t\t\t<ul className=\"space-y-2 text-sm\">\n\t\t\t\t{sections.map((section) => (\n\t\t\t\t\t<li key={section.id}>\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref={`#${section.id}`}\n\t\t\t\t\t\t\tclassName={`block transition-colors ${\n\t\t\t\t\t\t\t\tactiveSection === section.id\n\t\t\t\t\t\t\t\t\t? 'text-highlight font-medium'\n\t\t\t\t\t\t\t\t\t: 'text-muted-foreground hover:text-foreground'\n\t\t\t\t\t\t\t}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{section.label}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\t\t</nav>\n\t)\n}\n\nexport default function Guide() {\n\tconst [activeSection, setActiveSection] = React.useState<string | null>(null)\n\n\tReact.useEffect(() => {\n\t\tconst observer = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tif (entry.isIntersecting) {\n\t\t\t\t\t\tsetActiveSection(entry.target.id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\trootMargin: '-20% 0px -60% 0px',\n\t\t\t\tthreshold: 0,\n\t\t\t},\n\t\t)\n\n\t\tfor (const section of sections) {\n\t\t\tconst element = document.getElementById(section.id)\n\t\t\tif (element) {\n\t\t\t\tobserver.observe(element)\n\t\t\t}\n\t\t}\n\n\t\treturn () => observer.disconnect()\n\t}, [])\n\n\treturn (\n\t\t<div className=\"h-full w-full overflow-y-auto\">\n\t\t\t<div className=\"container mt-12 flex max-w-5xl gap-12 pb-24\">\n\t\t\t\t<main className=\"flex w-full max-w-3xl grow flex-col gap-8\">\n\t\t\t\t\t<h1 className=\"text-h1 mb-4\">Workshop App Guide</h1>\n\n\t\t\t\t\t<p className=\"text-lg\">\n\t\t\t\t\t\tThis guide will help you get the most out of the Epic Workshop App.\n\t\t\t\t\t\tWhether you're just getting started or need help troubleshooting,\n\t\t\t\t\t\tyou'll find useful information here.\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<div id=\"tutorial\" className=\"bg-accent scroll-mt-8 rounded-lg p-6\">\n\t\t\t\t\t\t<h2 className=\"text-h4 mb-2\">🎓 New to the Workshop App?</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tWe highly recommend going through the official tutorial to learn\n\t\t\t\t\t\t\tall the features the workshop app has to offer:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<code className=\"bg-background block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\tnpx epicshop add epicshop-tutorial\n\t\t\t\t\t\t</code>\n\t\t\t\t\t\t<p className=\"text-muted-foreground mt-2 text-sm\">\n\t\t\t\t\t\t\tThis will add the tutorial workshop to your setup so you can learn\n\t\t\t\t\t\t\tat your own pace.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<section id=\"logging-in\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">Logging In</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tLogging in unlocks important features that enhance your learning\n\t\t\t\t\t\t\texperience:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Progress tracking</strong> – Your progress syncs across\n\t\t\t\t\t\t\t\tdevices and persists between sessions\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Video access</strong> – Watch premium workshop videos\n\t\t\t\t\t\t\t\t(requires a valid license)\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Discord integration</strong> – Connect with the\n\t\t\t\t\t\t\t\tcommunity and instructors\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\n\t\t\t\t\t\t<h3 className=\"text-h5 mt-6 mb-3\">How to Log In</h3>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tClick the <strong>Account</strong> link in the navigation (top\n\t\t\t\t\t\t\tright) and follow the login prompts. You can also log in via the\n\t\t\t\t\t\t\tCLI:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<code className=\"bg-muted mb-4 block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\tepicshop auth login\n\t\t\t\t\t\t</code>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tThis opens a browser window where you can authenticate with your\n\t\t\t\t\t\t\tEpicWeb.dev, EpicReact.dev, or EpicAI.pro account.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p className=\"text-muted-foreground text-sm\">\n\t\t\t\t\t\t\tTip: Log in early to start tracking your progress from the\n\t\t\t\t\t\t\tbeginning!\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"workshop-structure\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">Workshop Structure</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tEach workshop is a standalone project with a consistent structure:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>exercises/</strong> – Contains the \"problem\" and\n\t\t\t\t\t\t\t\t\"solution\" versions of each step. Treat this as a reference for\n\t\t\t\t\t\t\t\tafter the workshop.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>playground/</strong> – This is where your work takes\n\t\t\t\t\t\t\t\tplace. We recommend opening this directory as its own editor\n\t\t\t\t\t\t\t\tinstance for efficient file searching.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"lesson-page\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">The Lesson Page</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tWhen you click into a lesson, the app displays the video along\n\t\t\t\t\t\t\twith written content, code snippets, and other useful information.\n\t\t\t\t\t\t\tTo the right is a pane with tabs:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Playground</strong> – Where you'll spend most of your\n\t\t\t\t\t\t\t\ttime. You can interact with the app here or open it in a\n\t\t\t\t\t\t\t\tdedicated tab.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Problem</strong> – The starting point of the exercise.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Solution</strong> – The completed exercise state.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Diff</strong> – Compare your current version against the\n\t\t\t\t\t\t\t\tfinished state. Use this if you get stuck, but try to avoid it\n\t\t\t\t\t\t\t\tif possible.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Tests</strong> – If the exercise includes tests, they'll\n\t\t\t\t\t\t\t\tappear here to verify your work.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"file-links\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">File Links</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tAt the bottom of a lesson page, the <strong>\"Files\"</strong>{' '}\n\t\t\t\t\t\t\tbutton opens a list of relevant files for the current exercise.\n\t\t\t\t\t\t\tClicking a file opens it directly in your editor at the right\n\t\t\t\t\t\t\tlocation.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p className=\"mb-4\">Key things to know:</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\tFiles are tied to your current Playground – make sure it's set\n\t\t\t\t\t\t\t\tto the lesson you're working on.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\tA <strong>\"+\"</strong> icon next to a filename means you need to\n\t\t\t\t\t\t\t\tcreate that file. Clicking it will create and open the file.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\tIf you see a red \"Set to Playground\" link, click it to sync the\n\t\t\t\t\t\t\t\tplayground for the current exercise.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\n\t\t\t\t\t\t<h3\n\t\t\t\t\t\t\tid=\"file-links-troubleshooting\"\n\t\t\t\t\t\t\tclassName=\"text-h4 mt-8 mb-4 scroll-mt-8\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tTroubleshooting\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tIf you're unable to open file links from the workshop app, create\n\t\t\t\t\t\t\ta <code className=\"bg-muted rounded px-1\">.env</code> file in the\n\t\t\t\t\t\t\troot of the workshop project and add:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<code className=\"bg-muted mb-4 block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\tEPICSHOP_EDITOR=\"path/to/your/editor\"\n\t\t\t\t\t\t</code>\n\t\t\t\t\t\t<p className=\"mb-4\">Examples:</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>VS Code:</strong>{' '}\n\t\t\t\t\t\t\t\t<code className=\"bg-muted rounded px-1\">\n\t\t\t\t\t\t\t\t\tEPICSHOP_EDITOR=code\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>VS Code on Windows:</strong>{' '}\n\t\t\t\t\t\t\t\t<code className=\"bg-muted rounded px-1\">\n\t\t\t\t\t\t\t\t\tEPICSHOP_EDITOR='\"C:\\Program Files\\Microsoft VS\n\t\t\t\t\t\t\t\t\tCode\\bin\\code.cmd\"'\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Cursor:</strong>{' '}\n\t\t\t\t\t\t\t\t<code className=\"bg-muted rounded px-1\">\n\t\t\t\t\t\t\t\t\tEPICSHOP_EDITOR=cursor\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t<p className=\"text-muted-foreground mt-4 text-sm\">\n\t\t\t\t\t\t\tNote: If the path includes spaces, wrap it in quotes as shown in\n\t\t\t\t\t\t\tthe Windows example.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p className=\"mt-4\">\n\t\t\t\t\t\t\tFor Cursor/VS Code users, you can also install the 'code' command\n\t\t\t\t\t\t\tin your PATH by opening the Command Palette (⌘⇧P on Mac,\n\t\t\t\t\t\t\tCtrl+Shift+P on Windows) and searching for \"Install 'code' command\n\t\t\t\t\t\t\tin PATH\".\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"setting-playground\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">Setting the Playground</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tIf you navigate to a different exercise than what's currently\n\t\t\t\t\t\t\tloaded, a red <strong>\"Set to Playground\"</strong> link will\n\t\t\t\t\t\t\tappear. Clicking this syncs the playground for the appropriate\n\t\t\t\t\t\t\texercise.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p className=\"bg-warning text-warning-foreground rounded-lg p-4\">\n\t\t\t\t\t\t\t<strong>Important:</strong> Always have your Playground set to the\n\t\t\t\t\t\t\tlesson you're working on! This is not automated because you might\n\t\t\t\t\t\t\twant to refer back to previous exercises without losing your\n\t\t\t\t\t\t\tcurrent work.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"diff-tab\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">The Diff Tab</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tThe diff tab helps you get unstuck when you're totally stuck. It\n\t\t\t\t\t\t\tshows the difference between your playground and the solution.\n\t\t\t\t\t\t\tThis is especially useful for catching typos or small mistakes.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<span className=\"text-success font-mono\">+</span> lines (green)\n\t\t\t\t\t\t\t\tshow code that needs to be added\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<span className=\"text-foreground-destructive font-mono\">-</span>{' '}\n\t\t\t\t\t\t\t\tlines (red) show code that needs to be removed\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>Unchanged lines provide context around the changes</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t<p className=\"text-muted-foreground mt-4 text-sm\">\n\t\t\t\t\t\t\tTip: Try to avoid using the diff tab until you've made a solid\n\t\t\t\t\t\t\tattempt at the exercise. The learning happens in the struggle!\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"tests\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">Tests</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tSome exercises include tests to verify your work. If available,\n\t\t\t\t\t\t\tthey appear in the Tests tab. Tests can run in two ways:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Script-based:</strong> A button runs the test script and\n\t\t\t\t\t\t\t\tstreams the output\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Browser-based:</strong> Test files are compiled and run\n\t\t\t\t\t\t\t\tdirectly in the browser\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t<p className=\"mt-4\">\n\t\t\t\t\t\t\tLook for 🚨 <strong>Alfred the Alert</strong> in test failures for\n\t\t\t\t\t\t\thelpful explanations about what went wrong.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"keyboard-shortcuts\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">Keyboard Shortcuts</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tWhen the workshop server is running in your terminal, you can use\n\t\t\t\t\t\t\tthese keyboard shortcuts:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<kbd className=\"bg-muted rounded px-2 py-1 font-mono text-sm\">\n\t\t\t\t\t\t\t\t\tu\n\t\t\t\t\t\t\t\t</kbd>{' '}\n\t\t\t\t\t\t\t\t– Check for and apply updates to the workshop\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<kbd className=\"bg-muted rounded px-2 py-1 font-mono text-sm\">\n\t\t\t\t\t\t\t\t\td\n\t\t\t\t\t\t\t\t</kbd>{' '}\n\t\t\t\t\t\t\t\t– Dismiss update notifications\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t<p className=\"text-muted-foreground mt-4 text-sm\">\n\t\t\t\t\t\t\tThe server automatically restarts after updates are applied.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"cli-commands\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">CLI Commands</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tThe <code className=\"bg-muted rounded px-1\">epicshop</code> CLI\n\t\t\t\t\t\t\tprovides useful commands for managing your workshop:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<div className=\"space-y-4\">\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<code className=\"bg-muted block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\t\t\tepicshop start\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground mt-1 text-sm\">\n\t\t\t\t\t\t\t\t\tStart the workshop (or just run{' '}\n\t\t\t\t\t\t\t\t\t<code className=\"bg-muted rounded px-1\">npm start</code>)\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<code className=\"bg-muted block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\t\t\tepicshop playground set\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground mt-1 text-sm\">\n\t\t\t\t\t\t\t\t\tSet the playground to the next incomplete step\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<code className=\"bg-muted block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\t\t\tepicshop diff\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground mt-1 text-sm\">\n\t\t\t\t\t\t\t\t\tShow the diff between your playground and the solution in the\n\t\t\t\t\t\t\t\t\tterminal\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<code className=\"bg-muted block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\t\t\tepicshop progress\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground mt-1 text-sm\">\n\t\t\t\t\t\t\t\t\tView your progress through the workshop\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<code className=\"bg-muted block rounded p-3 font-mono text-sm\">\n\t\t\t\t\t\t\t\t\tepicshop exercises\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground mt-1 text-sm\">\n\t\t\t\t\t\t\t\t\tList all exercises with completion status\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<p className=\"mt-4\">\n\t\t\t\t\t\t\tRun <code className=\"bg-muted rounded px-1\">epicshop --help</code>{' '}\n\t\t\t\t\t\t\tto see all available commands.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"ai-assistant\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">AI Assistant (MCP)</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tIf you use an AI assistant that supports{' '}\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref=\"https://modelcontextprotocol.io/\"\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tMCP (Model Context Protocol)\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t, you can install the Epic Workshop MCP server to enhance your\n\t\t\t\t\t\t\tlearning experience.\n\t\t\t\t\t\t</p>\n\n\t\t\t\t\t\t<h3 className=\"text-h5 mt-6 mb-3\">What it provides</h3>\n\t\t\t\t\t\t<ul className=\"list-disc space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Exercise context:</strong> Your AI can understand what\n\t\t\t\t\t\t\t\tyou're working on and provide relevant help\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Progress tracking:</strong> Mark lessons complete\n\t\t\t\t\t\t\t\tdirectly through your AI\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Diff viewing:</strong> Ask your AI to show you what\n\t\t\t\t\t\t\t\tchanges are needed\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>File opening:</strong> Have your AI open the relevant\n\t\t\t\t\t\t\t\tfiles in your editor\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>Quiz mode:</strong> Ask your AI to quiz you on workshop\n\t\t\t\t\t\t\t\ttopics\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\n\t\t\t\t\t\t<h3 className=\"text-h5 mt-6 mb-3\">Installation</h3>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tAdd the following to your AI assistant's MCP configuration (e.g.,\n\t\t\t\t\t\t\tClaude Desktop):\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<pre className=\"bg-muted overflow-x-auto rounded p-4 font-mono text-sm\">\n\t\t\t\t\t\t\t{`{\n \"mcpServers\": {\n \"epicshop\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@epic-web/workshop-mcp\"]\n }\n }\n}`}\n\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t<p className=\"text-muted-foreground mt-4 text-sm\">\n\t\t\t\t\t\t\tMake sure to run your AI assistant from within the workshop\n\t\t\t\t\t\t\tdirectory so the MCP server can find the right files.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"emoji-key\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">Emoji Key</h2>\n\t\t\t\t\t\t<p className=\"mb-4\">\n\t\t\t\t\t\t\tEach exercise has comments with helpful emoji characters:\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<ul className=\"space-y-2 pl-6\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>👨‍💼 Peter the Product Manager</strong> – Helps you know\n\t\t\t\t\t\t\t\twhat users want\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>🧝‍♀️ Kellie the Co-worker</strong> – Your co-worker who\n\t\t\t\t\t\t\t\tsometimes does work ahead of your exercises\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>🐨 Kody the Koala</strong> – Tells you when there's\n\t\t\t\t\t\t\t\tsomething specific to do\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>🦺 Lily the Life Jacket</strong> – Helps with\n\t\t\t\t\t\t\t\tTypeScript-specific parts\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>💰 Marty the Money Bag</strong> – Gives specific tips\n\t\t\t\t\t\t\t\tand sometimes code\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>📝 Nancy the Notepad</strong> – Encourages you to take\n\t\t\t\t\t\t\t\tnotes\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>🦉 Olivia the Owl</strong> – Gives useful tidbits and\n\t\t\t\t\t\t\t\tbest practices\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>📜 Dominic the Document</strong> – Links to useful\n\t\t\t\t\t\t\t\tdocumentation\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>💣 Barry the Bomb</strong> – Indicates code to delete\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>💪 Matthew the Muscle</strong> – Indicates you're\n\t\t\t\t\t\t\t\tworking with an exercise\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>🏁 Chuck the Checkered Flag</strong> – Indicates a final\n\t\t\t\t\t\t\t\tstep\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<strong>🚨 Alfred the Alert</strong> – Shows up in test failures\n\t\t\t\t\t\t\t\twith explanations\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</section>\n\n\t\t\t\t\t<section id=\"need-help\" className=\"scroll-mt-8\">\n\t\t\t\t\t\t<h2 className=\"text-h3 mb-4\">Need More Help?</h2>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\tVisit our{' '}\n\t\t\t\t\t\t\t<Link to=\"/support\" className=\"underline\">\n\t\t\t\t\t\t\t\tSupport page\n\t\t\t\t\t\t\t</Link>{' '}\n\t\t\t\t\t\t\tfor additional help options, including Discord access and how to\n\t\t\t\t\t\t\treport issues.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</section>\n\t\t\t\t</main>\n\t\t\t\t<aside className=\"hidden w-48 shrink-0 lg:block\">\n\t\t\t\t\t<TableOfContents activeSection={activeSection} />\n\t\t\t\t</aside>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n"],"names":["handle","getSitemapEntries","route","sections","id","label","TableOfContents","activeSection","jsxs","className","children","jsx","map","section","href","guide","_UNSAFE_withComponentProps","setActiveSection","React","observer","IntersectionObserver","entries","entry","isIntersecting","target","rootMargin","threshold","element","document","getElementById","observe","disconnect","rel","Link","to"],"mappings":"8IAIO,MAAMA,EAAoB,CAChCC,kBAAmBA,IAAM,CAAC,CAAEC,MAAO,SAAU,CAC9C,EAEMC,EAAW,CAChB,CAAEC,GAAI,WAAYC,MAAO,UAAW,EACpC,CAAED,GAAI,aAAcC,MAAO,YAAa,EACxC,CAAED,GAAI,qBAAsBC,MAAO,oBAAqB,EACxD,CAAED,GAAI,cAAeC,MAAO,iBAAkB,EAC9C,CAAED,GAAI,aAAcC,MAAO,YAAa,EACxC,CAAED,GAAI,qBAAsBC,MAAO,wBAAyB,EAC5D,CAAED,GAAI,WAAYC,MAAO,cAAe,EACxC,CAAED,GAAI,QAASC,MAAO,OAAQ,EAC9B,CAAED,GAAI,qBAAsBC,MAAO,oBAAqB,EACxD,CAAED,GAAI,eAAgBC,MAAO,cAAe,EAC5C,CAAED,GAAI,eAAgBC,MAAO,oBAAqB,EAClD,CAAED,GAAI,YAAaC,MAAO,WAAY,EACtC,CAAED,GAAI,YAAaC,MAAO,iBAAkB,CAAA,EAG7C,SAASC,EAAgB,CAAEC,cAAAA,CAAc,EAAqC,CAC7E,OACCC,EAAAA,KAAC,MAAA,CAAIC,UAAU,+BACdC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,2EAA2EC,SAAA,cAAA,CAEzF,EACAC,EAAAA,IAAC,MAAGF,UAAU,oBACZC,WAASE,IAAKC,GACdF,EAAAA,IAAC,KAAA,CACAD,SAAAC,EAAAA,IAAC,IAAA,CACAG,KAAM,IAAID,EAAQT,EAAE,GACpBK,UAAW,2BACVF,IAAkBM,EAAQT,GACvB,6BACA,6CACJ,GAECM,SAAAG,EAAQR,MACV,CAAA,EAVQQ,EAAQT,EAWjB,CACA,CAAA,CACF,CAAA,CAAA,CACD,CAEF,CAEA,MAAAW,EAAAC,EAAA,UAAgC,CAC/B,KAAM,CAACT,EAAeU,CAAgB,EAAIC,EAAAA,SAA8B,IAAI,EAE5EA,OAAAA,EAAAA,UAAgB,IAAM,CACrB,MAAMC,EAAW,IAAIC,qBACnBC,GAAY,CACZ,UAAWC,KAASD,EACfC,EAAMC,gBACTN,EAAiBK,EAAME,OAAOpB,EAAE,CAGnC,EACA,CACCqB,WAAY,oBACZC,UAAW,CACZ,CACD,EAEA,UAAWb,KAAWV,EAAU,CAC/B,MAAMwB,EAAUC,SAASC,eAAehB,EAAQT,EAAE,EAC9CuB,GACHR,EAASW,QAAQH,CAAO,CAE1B,CAEA,MAAO,IAAMR,EAASY,WAAA,CACvB,EAAG,CAAA,CAAE,QAGH,MAAA,CAAItB,UAAU,gCACdC,SAAAF,EAAAA,KAAC,MAAA,CAAIC,UAAU,8CACdC,SAAA,CAAAF,EAAAA,KAAC,OAAA,CAAKC,UAAU,4CACfC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,oBAAA,CAAkB,EAE/CC,EAAAA,IAAC,IAAA,CAAEF,UAAU,UAAUC,SAAA,4KAAA,CAIvB,EAEAF,EAAAA,KAAC,MAAA,CAAIJ,GAAG,WAAWK,UAAU,uCAC5BC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,6BAAA,CAA2B,EACxDC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,kHAAA,CAGpB,EACAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,oDAAoDC,SAAA,oCAAA,CAEpE,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,sFAAA,CAGlD,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,aAAaK,UAAU,cAClCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,YAAA,CAAU,EACvCC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,8EAAA,CAGpB,EACAF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,oBAAiB,EAAS,qEAAA,CAAA,CAEnC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,eAAY,EAAS,6DAAA,CAAA,CAE9B,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,sBAAmB,EAAS,+CAAA,CAAA,CAErC,CAAA,CAAA,CACD,EAEAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,oBAAoBC,SAAA,eAAA,CAAa,EAC/CF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,aACTC,EAAAA,IAAC,UAAOD,SAAA,UAAO,EAAS,oGAAA,CAAA,CAGnC,EACAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,oDAAoDC,SAAA,qBAAA,CAEpE,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,qHAAA,CAGpB,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,gCAAgCC,SAAA,uEAAA,CAG7C,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,qBAAqBK,UAAU,cAC1CC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,oBAAA,CAAkB,EAC/CC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,oEAAA,CAEpB,EACAF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,aAAU,EAAS,mHAAA,CAAA,CAG5B,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,cAAW,EAAS,sIAAA,CAAA,CAG7B,CAAA,CAAA,CACD,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,cAAcK,UAAU,cACnCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,iBAAA,CAAe,EAC5CC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,qKAAA,CAIpB,EACAF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,aAAU,EAAS,4GAAA,CAAA,CAG5B,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,UAAO,EAAS,wCAAA,CAAA,CACzB,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,WAAQ,EAAS,kCAAA,CAAA,CAC1B,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,OAAI,EAAS,yHAAA,CAAA,CAGtB,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,QAAK,EAAS,6EAAA,CAAA,CAEvB,CAAA,CAAA,CACD,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,aAAaK,UAAU,cAClCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,YAAA,CAAU,EACvCF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,uCACiBC,EAAAA,IAAC,UAAOD,SAAA,SAAA,CAAO,EAAU,IAAI,yIAAA,CAAA,CAIlE,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,qBAAA,CAAmB,EACvCF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAC,EAAAA,IAAC,MAAGD,SAAA,iGAAA,CAGJ,SACC,KAAA,CAAGA,SAAA,CAAA,KACDC,EAAAA,IAAC,UAAOD,SAAA,MAAG,EAAS,yGAAA,CAAA,CAEvB,EACAC,EAAAA,IAAC,MAAGD,SAAA,sGAAA,CAGJ,CAAA,CAAA,CACD,EAEAC,EAAAA,IAAC,KAAA,CACAP,GAAG,6BACHK,UAAU,gCACVC,SAAA,iBAAA,CAED,EACAF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,uEAEjBC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wBAAwBC,SAAA,OAAI,EAAO,oDAAA,CAAA,CAEtD,EACAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,oDAAoDC,SAAA,uCAAA,CAEpE,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,WAAA,CAAS,EAC7BF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,WAAQ,EAAU,IAC1BC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wBAAwBC,SAAA,sBAAA,CAExC,CAAA,CAAA,CACD,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,sBAAmB,EAAU,IACrCC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wBAAwBC,SAAA,yEAAA,CAGxC,CAAA,CAAA,CACD,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,UAAO,EAAU,IACzBC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wBAAwBC,SAAA,wBAAA,CAExC,CAAA,CAAA,CACD,CAAA,CAAA,CACD,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,uFAAA,CAGlD,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,yMAAA,CAKpB,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,qBAAqBK,UAAU,cAC1CC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,wBAAA,CAAsB,EACnDF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,+EAELC,EAAAA,IAAC,UAAOD,SAAA,sBAAmB,EAAS,qFAAA,CAAA,CAGnD,EACAF,EAAAA,KAAC,IAAA,CAAEC,UAAU,oDACZC,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,aAAU,EAAS,sLAAA,CAAA,CAI5B,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,WAAWK,UAAU,cAChCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,cAAA,CAAY,EACzCC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,iMAAA,CAIpB,EACAF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,yBAAyBC,SAAA,IAAC,EAAO,iDAAA,CAAA,CAElD,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wCAAwCC,SAAA,GAAA,CAAC,EAAQ,IAAI,gDAAA,CAAA,CAEtE,EACAC,EAAAA,IAAC,MAAGD,SAAA,oDAAA,CAAkD,CAAA,CAAA,CACvD,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,+HAAA,CAGlD,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,QAAQK,UAAU,cAC7BC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,OAAA,CAAK,EAClCC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,0HAAA,CAGpB,EACAF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,gBAAa,EAAS,uDAAA,CAAA,CAE/B,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,iBAAc,EAAS,0DAAA,CAAA,CAEhC,CAAA,CAAA,CACD,EACAF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,eACPC,EAAAA,IAAC,UAAOD,SAAA,mBAAgB,EAAS,mEAAA,CAAA,CAE9C,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,qBAAqBK,UAAU,cAC1CC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,oBAAA,CAAkB,EAC/CC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,6FAAA,CAGpB,EACAF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,MAAA,CAAIF,UAAU,+CAA+CC,SAAA,GAAA,CAE9D,EAAO,IAAI,+CAAA,CAAA,CAEZ,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,MAAA,CAAIF,UAAU,+CAA+CC,SAAA,GAAA,CAE9D,EAAO,IAAI,gCAAA,CAAA,CAEZ,CAAA,CAAA,CACD,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,8DAAA,CAElD,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,eAAeK,UAAU,cACpCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,cAAA,CAAY,EACzCF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,OACfC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wBAAwBC,SAAA,WAAQ,EAAO,2DAAA,CAAA,CAE5D,EACAF,EAAAA,KAAC,MAAA,CAAIC,UAAU,YACdC,SAAA,CAAAF,EAAAA,KAAC,MAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,+CAA+CC,SAAA,gBAAA,CAE/D,EACAF,EAAAA,KAAC,IAAA,CAAEC,UAAU,qCAAqCC,SAAA,CAAA,kCACjB,IAChCC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wBAAwBC,SAAA,YAAS,EAAO,GAAA,CAAA,CACzD,CAAA,CAAA,CACD,SACC,MAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,+CAA+CC,SAAA,yBAAA,CAE/D,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,gDAAA,CAElD,CAAA,CAAA,CACD,SACC,MAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,+CAA+CC,SAAA,eAAA,CAE/D,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,wEAAA,CAGlD,CAAA,CAAA,CACD,SACC,MAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,+CAA+CC,SAAA,mBAAA,CAE/D,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,yCAAA,CAElD,CAAA,CAAA,CACD,SACC,MAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAKF,UAAU,+CAA+CC,SAAA,oBAAA,CAE/D,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,2CAAA,CAElD,CAAA,CAAA,CACD,CAAA,CAAA,CACD,EACAF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,OACfC,EAAAA,IAAC,OAAA,CAAKF,UAAU,wBAAwBC,SAAA,iBAAA,CAAe,EAAQ,IAAI,gCAAA,CAAA,CAExE,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,eAAeK,UAAU,cACpCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,oBAAA,CAAkB,EAC/CF,EAAAA,KAAC,IAAA,CAAEC,UAAU,OAAOC,SAAA,CAAA,2CACsB,IACzCC,EAAAA,IAAC,IAAA,CACAG,KAAK,mCACLU,OAAO,SACPQ,IAAI,sBACJvB,UAAU,YACVC,SAAA,+BAED,EAAI,qFAAA,CAAA,CAGL,EAEAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,oBAAoBC,SAAA,kBAAA,CAAgB,EAClDF,EAAAA,KAAC,KAAA,CAAGC,UAAU,2BACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,oBAAiB,EAAS,0EAAA,CAAA,CAEnC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,qBAAkB,EAAS,iDAAA,CAAA,CAEpC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,gBAAa,EAAS,kDAAA,CAAA,CAE/B,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,gBAAa,EAAS,sDAAA,CAAA,CAE/B,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,aAAU,EAAS,6CAAA,CAAA,CAE5B,CAAA,CAAA,CACD,EAEAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,oBAAoBC,SAAA,cAAA,CAAY,EAC9CC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,oFAAA,CAGpB,EACAC,EAAAA,IAAC,MAAA,CAAIF,UAAU,yDACbC,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAQF,EACAC,EAAAA,IAAC,IAAA,CAAEF,UAAU,qCAAqCC,SAAA,mHAAA,CAGlD,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,YAAYK,UAAU,cACjCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,WAAA,CAAS,EACtCC,EAAAA,IAAC,IAAA,CAAEF,UAAU,OAAOC,SAAA,2DAAA,CAEpB,EACAF,EAAAA,KAAC,KAAA,CAAGC,UAAU,iBACbC,SAAA,CAAAF,EAAAA,KAAC,KAAA,CACAE,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,kCAA+B,EAAS,mCAAA,CAAA,CAEjD,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,6BAA0B,EAAS,mEAAA,CAAA,CAE5C,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,oBAAiB,EAAS,oDAAA,CAAA,CAEnC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,0BAAuB,EAAS,yCAAA,CAAA,CAEzC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,yBAAsB,EAAS,2CAAA,CAAA,CAExC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,uBAAoB,EAAS,iCAAA,CAAA,CAEtC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,oBAAiB,EAAS,4CAAA,CAAA,CAEnC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,0BAAuB,EAAS,kCAAA,CAAA,CAEzC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,oBAAiB,EAAS,6BAAA,CAAA,CACnC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,wBAAqB,EAAS,8CAAA,CAAA,CAEvC,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,8BAA2B,EAAS,2BAAA,CAAA,CAE7C,SACC,KAAA,CACAA,SAAA,CAAAC,EAAAA,IAAC,UAAOD,SAAA,sBAAmB,EAAS,gDAAA,CAAA,CAErC,CAAA,CAAA,CACD,CAAA,CAAA,CACD,EAEAF,EAAAA,KAAC,UAAA,CAAQJ,GAAG,YAAYK,UAAU,cACjCC,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAGF,UAAU,eAAeC,SAAA,iBAAA,CAAe,SAC3C,IAAA,CAAEA,SAAA,CAAA,YACQ,UACTuB,EAAA,CAAKC,GAAG,WAAWzB,UAAU,YAAYC,SAAA,cAAA,CAE1C,EAAQ,IAAI,iFAAA,CAAA,CAGb,CAAA,CAAA,CACD,CAAA,CAAA,CACD,QACC,QAAA,CAAMD,UAAU,gCAChBC,SAAAC,EAAAA,IAACL,EAAA,CAAgBC,cAAAA,EAA8B,CAAA,CAChD,CAAA,EACD,CAAA,CACD,CAEF,CAAA"}
@@ -1,2 +0,0 @@
1
- import{w as C,k as S,L as N,F as h}from"./chunk-EPOLDU6W-BCLmut3y.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{a as g,I as o,c as j,e as P}from"./misc-DVYuZMjW.js";import{S as y}from"./tooltip-Chzzs4KB.js";import{a as A}from"./progress-fKsNxmmt.js";import{g as T}from"./root-loader-BOzEMapJ.js";import"./index-CqIc3cxq.js";import"./index-vDCSPjrM.js";import"./pe-CIZUOJMr.js";const H={getSitemapEntries:()=>null},U=({matches:s})=>[{title:`👷 | ${T(s)?.workshopTitle}`}];function D(s,t){return s.type==="unknown"&&t.type==="unknown"?0:s.type==="unknown"?-1:t.type==="unknown"?1:0}function L(s){switch(s.type){case"workshop-instructions":return"/";case"workshop-finished":return"/finished";case"instructions":return`/${s.exerciseNumber.toString().padStart(2,"0")}`;case"step":return`/${s.exerciseNumber.toString().padStart(2,"0")}/${s.stepNumber.toString().padStart(2,"0")}`;case"finished":return`/${s.exerciseNumber.toString().padStart(2,"0")}/finished`;default:return""}}const q=C(function({loaderData:t}){const i=S(),a=A(),p=i.formData?.get("intent")==="inspect",w=i.formData?.get("intent")==="stop-inspect",k={completed:"bg-success",incomplete:"bg-warning"};return e.jsxs("div",{className:"flex flex-col gap-6 p-6",children:[e.jsxs("div",{className:"mb-2",children:[e.jsx("h1",{className:"text-foreground text-2xl font-bold",children:"Admin Panel"}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm",children:"Manage workshop settings and monitor processes"})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2",children:[e.jsxs(c,{children:[e.jsxs(d,{children:[e.jsx(m,{children:"Progress"}),e.jsx(u,{children:"EpicWeb.dev lesson progress"})]}),e.jsx(x,{children:a?e.jsx("ul",{className:"scrollbar-thin scrollbar-thumb-scrollbar flex max-h-72 flex-col gap-2 overflow-y-auto",children:a.sort(D).map(n=>{const r=n.epicCompletedAt?"completed":"incomplete",b=[n.epicLessonSlug,n.epicCompletedAt?`(${n.epicCompletedAt})`:null].filter(Boolean).join(" ");return e.jsxs("li",{className:"hover:bg-muted/50 flex items-center gap-3 rounded-md p-2",children:[e.jsx("span",{className:g("h-3 w-3 shrink-0 rounded-full",k[r]),title:r}),n.type==="unknown"?e.jsxs("span",{className:"flex flex-1 items-center gap-2 truncate text-sm",children:[e.jsx("span",{className:"truncate",children:b}),e.jsx(y,{content:"This video is in the workshop on EpicWeb.dev, but not in the local workshop.",children:e.jsx(o,{name:"Close",className:"text-destructive h-4 w-4 shrink-0"})})]}):e.jsx(N,{to:L(n),className:"text-foreground flex-1 truncate text-sm hover:underline",children:b}),e.jsx(N,{to:n.epicLessonUrl,className:"text-muted-foreground hover:text-foreground shrink-0",children:e.jsx(o,{name:"ExternalLink",className:"h-4 w-4"})})]},n.epicLessonSlug)})}):e.jsx("p",{className:"text-muted-foreground text-sm",children:"No progress data"})})]}),e.jsxs(c,{children:[e.jsxs(d,{children:[e.jsx(m,{children:"Commands"}),e.jsx(u,{children:"Workshop management actions"})]}),e.jsx(x,{children:e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx(h,{method:"POST",children:e.jsxs(v,{name:"intent",value:"clear-caches",children:[e.jsx(o,{name:"Clear",className:"h-4 w-4"}),"Clear local caches"]})}),e.jsx(h,{method:"POST",children:e.jsxs(v,{name:"intent",value:"clear-data",className:"border-destructive bg-destructive/80 text-destructive-foreground hover:bg-destructive hover:text-destructive-foreground",doubleCheckClassName:"border-destructive bg-destructive text-destructive-foreground",children:[e.jsx(o,{name:"TriangleAlert",className:"h-4 w-4"}),"Clear all local data (including auth data)"]})}),t.inspectorRunning?e.jsx(h,{method:"POST",children:e.jsxs(f,{name:"intent",value:"stop-inspect",children:[e.jsx(o,{name:"Stop",className:"h-4 w-4"}),w?"Stopping inspector...":"Stop inspector"]})}):e.jsx(h,{method:"POST",children:e.jsx(f,{name:"intent",value:"inspect",children:p?"Starting inspector...":"Start inspector"})})]})})]}),e.jsxs(c,{children:[e.jsxs(d,{children:[e.jsx(m,{children:"Apps"}),e.jsx(u,{children:"Available workshop apps"})]}),e.jsx(x,{children:e.jsx("ul",{className:"scrollbar-thin scrollbar-thumb-scrollbar flex max-h-48 flex-col gap-2 overflow-y-auto",children:t.apps.length>0?t.apps.map(n=>e.jsxs("li",{className:"hover:bg-muted/50 flex items-center gap-3 rounded-md p-2",children:[t.processes[n.name]?e.jsx(l,{status:"running"}):e.jsx(l,{status:"stopped"}),e.jsx("span",{className:"font-mono text-sm",children:n.name})]},n.name)):e.jsx("p",{className:"text-muted-foreground text-sm",children:"No apps available"})})})]}),e.jsxs(c,{children:[e.jsxs(d,{children:[e.jsx(m,{children:"Processes"}),e.jsx(u,{children:"Running development processes"})]}),e.jsx(x,{children:e.jsx("ul",{className:"scrollbar-thin scrollbar-thumb-scrollbar flex max-h-48 flex-col gap-2 overflow-y-auto",children:Object.entries(t.processes).length>0?Object.entries(t.processes).map(([n,r])=>e.jsxs("li",{className:"border-border bg-muted/30 rounded-md border p-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(l,{status:"running"}),e.jsx("span",{className:"font-mono text-sm font-semibold",children:n})]}),e.jsxs("div",{className:"text-muted-foreground mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs",children:[e.jsxs("span",{children:[e.jsx("span",{className:"font-medium",children:"Port:"})," ",r.port]}),r.pid&&e.jsxs("span",{children:[e.jsx("span",{className:"font-medium",children:"PID:"})," ",r.pid]}),e.jsxs("span",{children:[e.jsx("span",{className:"font-medium",children:"Color:"})," ",e.jsx("span",{className:"inline-block h-3 w-3 rounded-full",style:{backgroundColor:r.color}})]})]})]},n)):e.jsx("p",{className:"text-muted-foreground text-sm",children:"No processes running"})})})]}),Object.entries(t.testProcesses).length>0&&e.jsxs(c,{className:"md:col-span-2",children:[e.jsxs(d,{children:[e.jsx(m,{children:"Test Processes"}),e.jsx(u,{children:"Test execution processes"})]}),e.jsx(x,{children:e.jsx("ul",{className:"scrollbar-thin scrollbar-thumb-scrollbar flex flex-col gap-2 overflow-y-auto",children:Object.entries(t.testProcesses).map(([n,r])=>e.jsxs("li",{className:"border-border bg-muted/30 rounded-md border p-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[r.exitCode===null||r.exitCode===void 0?e.jsx(l,{status:"running"}):r.exitCode===0?e.jsx(l,{status:"stopped"}):e.jsx(l,{status:"taken"}),e.jsx("span",{className:"font-mono text-sm font-semibold",children:n})]}),e.jsxs("div",{className:"text-muted-foreground mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs",children:[r.pid&&e.jsxs("span",{children:[e.jsx("span",{className:"font-medium",children:"PID:"})," ",r.pid]}),e.jsxs("span",{children:[e.jsx("span",{className:"font-medium",children:"Exit code:"})," ",r.exitCode===null||r.exitCode===void 0?"Running":r.exitCode]})]})]},n))})})]})]})]})});function c({children:s,className:t}){return e.jsx("div",{className:j("border-border bg-card rounded-lg border p-6 shadow-sm",t),children:s})}function d({children:s}){return e.jsx("div",{className:"mb-4",children:s})}function m({children:s}){return e.jsx("h2",{className:"text-foreground text-lg font-semibold",children:s})}function u({children:s}){return e.jsx("p",{className:"text-muted-foreground mt-1 text-sm",children:s})}function x({children:s}){return e.jsx("div",{children:s})}function f({children:s,...t}){return e.jsx("button",{...t,className:j("border-border bg-background text-foreground hover:bg-muted hover:text-foreground focus:ring-ring inline-flex w-full items-center justify-center gap-2 rounded-md border px-4 py-2 text-sm font-medium transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none disabled:opacity-50",t.className),children:s})}function v({children:s,doubleCheckClassName:t,...i}){const{doubleCheck:a,getButtonProps:p}=P();return e.jsx(f,{...p(i),className:j(i.className,a?t??"border-destructive bg-destructive text-destructive-foreground":null),children:a?e.jsxs(e.Fragment,{children:[e.jsx(o,{name:"TriangleAlert",className:"h-4 w-4"}),"Are you sure?"]}):s})}function l({status:s}){const t={running:{pinger:"bg-success/60",circle:"bg-success"},starting:{pinger:"bg-info/60",circle:"bg-info"},stopped:{circle:"bg-muted-foreground"},taken:{pinger:"bg-destructive/60",circle:"bg-destructive"}}[s];return e.jsxs("span",{className:"relative flex h-3 w-3 shrink-0",children:[t.pinger?e.jsx("span",{className:g("absolute inline-flex h-full w-full animate-ping rounded-full opacity-75",t.pinger)}):null,e.jsx("span",{className:g("relative inline-flex h-3 w-3 rounded-full",t.circle)})]})}export{q as default,H as handle,U as meta};
2
- //# sourceMappingURL=index-C6vQqVxz.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-C6vQqVxz.js","sources":["../../../app/routes/admin+/index.tsx"],"sourcesContent":["import { getApps } from '@epic-web/workshop-utils/apps.server'\nimport { getProcesses } from '@epic-web/workshop-utils/process-manager.server'\nimport {\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport { clsx } from 'clsx'\nimport { data, Form, Link, useNavigation } from 'react-router'\nimport { Icon } from '#app/components/icons.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.tsx'\nimport {\n\tuseEpicProgress,\n\ttype SerializedProgress,\n} from '#app/routes/progress.tsx'\nimport { cn, ensureUndeployed, useDoubleCheck } from '#app/utils/misc.tsx'\nimport { getRootMatchLoaderData } from '#app/utils/root-loader.ts'\nimport { type Route } from './+types/index.tsx'\nimport {\n\tclearCaches,\n\tclearData,\n\tisInspectorRunning,\n\tstartInspector,\n\tstopInspector,\n} from './admin-utils.server.tsx'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => null,\n}\n\nexport const meta: Route.MetaFunction = ({ matches }) => {\n\tconst rootData = getRootMatchLoaderData(matches)\n\treturn [{ title: `👷 | ${rootData?.workshopTitle}` }]\n}\n\nexport async function loader({ request }: Route.LoaderArgs) {\n\tensureUndeployed()\n\tconst timings = makeTimings('adminLoader')\n\tconst apps = (await getApps({ request, timings })).filter(\n\t\t(a, i, ar) => ar.findIndex((b) => a.name === b.name) === i,\n\t)\n\tconst processes: Record<\n\t\tstring,\n\t\t{ port: number; pid?: number; color: string }\n\t> = {}\n\tconst testProcesses: Record<\n\t\tstring,\n\t\t{ pid?: number; exitCode?: number | null }\n\t> = {}\n\tfor (const [\n\t\tname,\n\t\t{ port, process, color },\n\t] of getProcesses().devProcesses.entries()) {\n\t\tprocesses[name] = { port, pid: process.pid, color }\n\t}\n\n\tfor (const [\n\t\tname,\n\t\t{ process, exitCode },\n\t] of getProcesses().testProcesses.entries()) {\n\t\ttestProcesses[name] = { pid: process?.pid, exitCode }\n\t}\n\treturn data(\n\t\t{\n\t\t\tapps,\n\t\t\tprocesses,\n\t\t\ttestProcesses,\n\t\t\tinspectorRunning: isInspectorRunning(),\n\t\t},\n\t\t{\n\t\t\theaders: {\n\t\t\t\t'Server-Timing': getServerTimeHeader(timings),\n\t\t\t},\n\t\t},\n\t)\n}\n\nexport async function action({ request }: Route.ActionArgs) {\n\tensureUndeployed()\n\tconst formData = await request.formData()\n\tconst intent = formData.get('intent')\n\tswitch (intent) {\n\t\tcase 'clear-data': {\n\t\t\tawait clearData()\n\t\t\treturn { success: true }\n\t\t}\n\t\tcase 'clear-caches': {\n\t\t\tawait clearCaches()\n\t\t\treturn { success: true }\n\t\t}\n\t\tcase 'inspect': {\n\t\t\tawait startInspector()\n\t\t\treturn { success: true }\n\t\t}\n\t\tcase 'stop-inspect': {\n\t\t\tawait stopInspector()\n\t\t\treturn { success: true }\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(`Unknown intent: ${intent}`)\n\t\t}\n\t}\n}\n\nfunction sortProgress(a: SerializedProgress, b: SerializedProgress) {\n\treturn a.type === 'unknown' && b.type === 'unknown'\n\t\t? 0\n\t\t: a.type === 'unknown'\n\t\t\t? -1\n\t\t\t: b.type === 'unknown'\n\t\t\t\t? 1\n\t\t\t\t: 0\n}\n\nfunction linkProgress(progress: SerializedProgress) {\n\tswitch (progress.type) {\n\t\tcase 'workshop-instructions':\n\t\t\treturn '/'\n\t\tcase 'workshop-finished':\n\t\t\treturn '/finished'\n\t\tcase 'instructions':\n\t\t\treturn `/${progress.exerciseNumber.toString().padStart(2, '0')}`\n\t\tcase 'step':\n\t\t\treturn `/${progress.exerciseNumber\n\t\t\t\t.toString()\n\t\t\t\t.padStart(2, '0')}/${progress.stepNumber.toString().padStart(2, '0')}`\n\t\tcase 'finished':\n\t\t\treturn `/${progress.exerciseNumber.toString().padStart(2, '0')}/finished`\n\t\tdefault:\n\t\t\treturn ''\n\t}\n}\n\nexport default function AdminLayout({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tconst navigation = useNavigation()\n\tconst epicProgress = useEpicProgress()\n\n\tconst isStartingInspector = navigation.formData?.get('intent') === 'inspect'\n\tconst isStoppingInspector =\n\t\tnavigation.formData?.get('intent') === 'stop-inspect'\n\n\tconst progressStatus = {\n\t\tcompleted: 'bg-success',\n\t\tincomplete: 'bg-warning',\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-6 p-6\">\n\t\t\t<div className=\"mb-2\">\n\t\t\t\t<h1 className=\"text-foreground text-2xl font-bold\">Admin Panel</h1>\n\t\t\t\t<p className=\"text-muted-foreground mt-1 text-sm\">\n\t\t\t\t\tManage workshop settings and monitor processes\n\t\t\t\t</p>\n\t\t\t</div>\n\n\t\t\t<div className=\"grid gap-6 md:grid-cols-2\">\n\t\t\t\t<Card>\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t<CardTitle>Progress</CardTitle>\n\t\t\t\t\t\t<CardDescription>EpicWeb.dev lesson progress</CardDescription>\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent>\n\t\t\t\t\t\t{epicProgress ? (\n\t\t\t\t\t\t\t<ul className=\"scrollbar-thin scrollbar-thumb-scrollbar flex max-h-72 flex-col gap-2 overflow-y-auto\">\n\t\t\t\t\t\t\t\t{epicProgress.sort(sortProgress).map((progress) => {\n\t\t\t\t\t\t\t\t\tconst status = progress.epicCompletedAt\n\t\t\t\t\t\t\t\t\t\t? 'completed'\n\t\t\t\t\t\t\t\t\t\t: 'incomplete'\n\t\t\t\t\t\t\t\t\tconst label = [\n\t\t\t\t\t\t\t\t\t\tprogress.epicLessonSlug,\n\t\t\t\t\t\t\t\t\t\tprogress.epicCompletedAt\n\t\t\t\t\t\t\t\t\t\t\t? `(${progress.epicCompletedAt})`\n\t\t\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t\t.join(' ')\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\t\tkey={progress.epicLessonSlug}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"hover:bg-muted/50 flex items-center gap-3 rounded-md p-2\"\n\t\t\t\t\t\t\t\t\t\t>\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\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'h-3 w-3 shrink-0 rounded-full',\n\t\t\t\t\t\t\t\t\t\t\t\t\tprogressStatus[status],\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={status}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t{progress.type === 'unknown' ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"flex flex-1 items-center gap-2 truncate text-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{label}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SimpleTooltip content=\"This video is in the workshop on EpicWeb.dev, but not in the local workshop.\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname=\"Close\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-destructive h-4 w-4 shrink-0\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\tto={linkProgress(progress)}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-foreground flex-1 truncate text-sm hover:underline\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\tto={progress.epicLessonUrl}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground hover:text-foreground shrink-0\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"ExternalLink\" className=\"h-4 w-4\" />\n\t\t\t\t\t\t\t\t\t\t\t</Link>\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})}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-sm\">No progress data</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\n\t\t\t\t<Card>\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t<CardTitle>Commands</CardTitle>\n\t\t\t\t\t\t<CardDescription>Workshop management actions</CardDescription>\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent>\n\t\t\t\t\t\t<div className=\"flex flex-col gap-3\">\n\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t<DoubleCheckAdminButton name=\"intent\" value=\"clear-caches\">\n\t\t\t\t\t\t\t\t\t<Icon name=\"Clear\" className=\"h-4 w-4\" />\n\t\t\t\t\t\t\t\t\tClear local caches\n\t\t\t\t\t\t\t\t</DoubleCheckAdminButton>\n\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t<DoubleCheckAdminButton\n\t\t\t\t\t\t\t\t\tname=\"intent\"\n\t\t\t\t\t\t\t\t\tvalue=\"clear-data\"\n\t\t\t\t\t\t\t\t\tclassName=\"border-destructive bg-destructive/80 text-destructive-foreground hover:bg-destructive hover:text-destructive-foreground\"\n\t\t\t\t\t\t\t\t\tdoubleCheckClassName=\"border-destructive bg-destructive text-destructive-foreground\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon name=\"TriangleAlert\" className=\"h-4 w-4\" />\n\t\t\t\t\t\t\t\t\tClear all local data (including auth data)\n\t\t\t\t\t\t\t\t</DoubleCheckAdminButton>\n\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t{data.inspectorRunning ? (\n\t\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t\t<AdminButton name=\"intent\" value=\"stop-inspect\">\n\t\t\t\t\t\t\t\t\t\t<Icon name=\"Stop\" className=\"h-4 w-4\" />\n\t\t\t\t\t\t\t\t\t\t{isStoppingInspector\n\t\t\t\t\t\t\t\t\t\t\t? 'Stopping inspector...'\n\t\t\t\t\t\t\t\t\t\t\t: 'Stop inspector'}\n\t\t\t\t\t\t\t\t\t</AdminButton>\n\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t\t<AdminButton name=\"intent\" value=\"inspect\">\n\t\t\t\t\t\t\t\t\t\t{isStartingInspector\n\t\t\t\t\t\t\t\t\t\t\t? 'Starting inspector...'\n\t\t\t\t\t\t\t\t\t\t\t: 'Start inspector'}\n\t\t\t\t\t\t\t\t\t</AdminButton>\n\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\n\t\t\t\t<Card>\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t<CardTitle>Apps</CardTitle>\n\t\t\t\t\t\t<CardDescription>Available workshop apps</CardDescription>\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent>\n\t\t\t\t\t\t<ul className=\"scrollbar-thin scrollbar-thumb-scrollbar flex max-h-48 flex-col gap-2 overflow-y-auto\">\n\t\t\t\t\t\t\t{data.apps.length > 0 ? (\n\t\t\t\t\t\t\t\tdata.apps.map((app) => (\n\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\tkey={app.name}\n\t\t\t\t\t\t\t\t\t\tclassName=\"hover:bg-muted/50 flex items-center gap-3 rounded-md p-2\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{data.processes[app.name] ? (\n\t\t\t\t\t\t\t\t\t\t\t<Pinger status=\"running\" />\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<Pinger status=\"stopped\" />\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t<span className=\"font-mono text-sm\">{app.name}</span>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-sm\">\n\t\t\t\t\t\t\t\t\tNo apps available\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\n\t\t\t\t<Card>\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t<CardTitle>Processes</CardTitle>\n\t\t\t\t\t\t<CardDescription>Running development processes</CardDescription>\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent>\n\t\t\t\t\t\t<ul className=\"scrollbar-thin scrollbar-thumb-scrollbar flex max-h-48 flex-col gap-2 overflow-y-auto\">\n\t\t\t\t\t\t\t{Object.entries(data.processes).length > 0 ? (\n\t\t\t\t\t\t\t\tObject.entries(data.processes).map(([key, process]) => (\n\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\t\t\t\t\tclassName=\"border-border bg-muted/30 rounded-md border p-3\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t<Pinger status=\"running\" />\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-mono text-sm font-semibold\">\n\t\t\t\t\t\t\t\t\t\t\t\t{key}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"text-muted-foreground mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs\">\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\t<span className=\"font-medium\">Port:</span>{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t{process.port}\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{process.pid && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">PID:</span>{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{process.pid}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t)}\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\t<span className=\"font-medium\">Color:</span>{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"inline-block h-3 w-3 rounded-full\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{ backgroundColor: process.color }}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-sm\">\n\t\t\t\t\t\t\t\t\tNo processes running\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\n\t\t\t\t{Object.entries(data.testProcesses).length > 0 && (\n\t\t\t\t\t<Card className=\"md:col-span-2\">\n\t\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t\t<CardTitle>Test Processes</CardTitle>\n\t\t\t\t\t\t\t<CardDescription>Test execution processes</CardDescription>\n\t\t\t\t\t\t</CardHeader>\n\t\t\t\t\t\t<CardContent>\n\t\t\t\t\t\t\t<ul className=\"scrollbar-thin scrollbar-thumb-scrollbar flex flex-col gap-2 overflow-y-auto\">\n\t\t\t\t\t\t\t\t{Object.entries(data.testProcesses).map(([key, process]) => (\n\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\t\t\t\t\tclassName=\"border-border bg-muted/30 rounded-md border p-3\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t{process.exitCode === null ||\n\t\t\t\t\t\t\t\t\t\t\tprocess.exitCode === undefined ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<Pinger status=\"running\" />\n\t\t\t\t\t\t\t\t\t\t\t) : process.exitCode === 0 ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<Pinger status=\"stopped\" />\n\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<Pinger status=\"taken\" />\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-mono text-sm font-semibold\">\n\t\t\t\t\t\t\t\t\t\t\t\t{key}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"text-muted-foreground mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs\">\n\t\t\t\t\t\t\t\t\t\t\t{process.pid && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">PID:</span>{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{process.pid}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t)}\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\t<span className=\"font-medium\">Exit code:</span>{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t{process.exitCode === null ||\n\t\t\t\t\t\t\t\t\t\t\t\tprocess.exitCode === undefined\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'Running'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: process.exitCode}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</CardContent>\n\t\t\t\t\t</Card>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction Card({\n\tchildren,\n\tclassName,\n}: {\n\tchildren: React.ReactNode\n\tclassName?: string\n}) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'border-border bg-card rounded-lg border p-6 shadow-sm',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t{children}\n\t\t</div>\n\t)\n}\n\nfunction CardHeader({ children }: { children: React.ReactNode }) {\n\treturn <div className=\"mb-4\">{children}</div>\n}\n\nfunction CardTitle({ children }: { children: React.ReactNode }) {\n\treturn <h2 className=\"text-foreground text-lg font-semibold\">{children}</h2>\n}\n\nfunction CardDescription({ children }: { children: React.ReactNode }) {\n\treturn <p className=\"text-muted-foreground mt-1 text-sm\">{children}</p>\n}\n\nfunction CardContent({ children }: { children: React.ReactNode }) {\n\treturn <div>{children}</div>\n}\n\nfunction AdminButton({\n\tchildren,\n\t...props\n}: React.ComponentPropsWithoutRef<'button'>) {\n\treturn (\n\t\t<button\n\t\t\t{...props}\n\t\t\tclassName={cn(\n\t\t\t\t'border-border bg-background text-foreground hover:bg-muted hover:text-foreground focus:ring-ring inline-flex w-full items-center justify-center gap-2 rounded-md border px-4 py-2 text-sm font-medium transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none disabled:opacity-50',\n\t\t\t\tprops.className,\n\t\t\t)}\n\t\t>\n\t\t\t{children}\n\t\t</button>\n\t)\n}\n\nfunction DoubleCheckAdminButton({\n\tchildren,\n\tdoubleCheckClassName,\n\t...props\n}: React.ComponentPropsWithoutRef<'button'> & {\n\tdoubleCheckClassName?: string\n}) {\n\tconst { doubleCheck, getButtonProps } = useDoubleCheck()\n\n\treturn (\n\t\t<AdminButton\n\t\t\t{...getButtonProps(props)}\n\t\t\tclassName={cn(\n\t\t\t\tprops.className,\n\t\t\t\tdoubleCheck\n\t\t\t\t\t? (doubleCheckClassName ??\n\t\t\t\t\t\t\t'border-destructive bg-destructive text-destructive-foreground')\n\t\t\t\t\t: null,\n\t\t\t)}\n\t\t>\n\t\t\t{doubleCheck ? (\n\t\t\t\t<>\n\t\t\t\t\t<Icon name=\"TriangleAlert\" className=\"h-4 w-4\" />\n\t\t\t\t\tAre you sure?\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\tchildren\n\t\t\t)}\n\t\t</AdminButton>\n\t)\n}\n\nfunction Pinger({\n\tstatus,\n}: {\n\tstatus: 'running' | 'starting' | 'stopped' | 'taken'\n}) {\n\tconst colors = {\n\t\trunning: {\n\t\t\tpinger: 'bg-success/60',\n\t\t\tcircle: 'bg-success',\n\t\t},\n\t\tstarting: {\n\t\t\tpinger: 'bg-info/60',\n\t\t\tcircle: 'bg-info',\n\t\t},\n\t\tstopped: {\n\t\t\tcircle: 'bg-muted-foreground',\n\t\t},\n\t\ttaken: {\n\t\t\tpinger: 'bg-destructive/60',\n\t\t\tcircle: 'bg-destructive',\n\t\t},\n\t}[status]\n\treturn (\n\t\t<span className=\"relative flex h-3 w-3 shrink-0\">\n\t\t\t{colors.pinger ? (\n\t\t\t\t<span\n\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t'absolute inline-flex h-full w-full animate-ping rounded-full opacity-75',\n\t\t\t\t\t\tcolors.pinger,\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tclassName={clsx(\n\t\t\t\t\t'relative inline-flex h-3 w-3 rounded-full',\n\t\t\t\t\tcolors.circle,\n\t\t\t\t)}\n\t\t\t/>\n\t\t</span>\n\t)\n}\n"],"names":["handle","getSitemapEntries","meta","matches","title","getRootMatchLoaderData","workshopTitle","sortProgress","a","b","type","linkProgress","progress","exerciseNumber","toString","padStart","stepNumber","index","_UNSAFE_withComponentProps","loaderData","data","navigation","useNavigation","epicProgress","useEpicProgress","isStartingInspector","formData","get","isStoppingInspector","progressStatus","completed","incomplete","jsxs","className","children","jsx","Card","CardHeader","CardTitle","CardDescription","CardContent","sort","map","status","epicCompletedAt","label","epicLessonSlug","filter","Boolean","join","clsx","SimpleTooltip","content","Icon","name","Link","to","epicLessonUrl","Form","method","DoubleCheckAdminButton","value","doubleCheckClassName","inspectorRunning","AdminButton","apps","length","app","processes","Pinger","Object","entries","key","process","port","pid","style","backgroundColor","color","testProcesses","exitCode","cn","props","doubleCheck","getButtonProps","useDoubleCheck","Fragment","colors","running","pinger","circle","starting","stopped","taken"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{w as j,a as E,c as A,d as C,e as N}from"./chunk-EPOLDU6W-BCLmut3y.js";import{j as r}from"./jsx-runtime-C5WNSv3b.js";import{g as T,R as H,P as U,C as t,a as b,D as B}from"./playground-C_aP_pE8.js";import{U as I}from"./diff-CxEbhF8Q.js";import{G as R}from"./error-boundary-DFBd6s0g.js";import{u as S}from"./workshop-config-Zfc8zU0x.js";import{u as O}from"./misc-DVYuZMjW.js";import{P as a}from"./preview-CiDtuQCc.js";import{T as k}from"./tests-xD9PppmM.js";import"./index-CqIc3cxq.js";import"./loading-CUydCGD3.js";import"./index-BW8stNyh.js";import"./tooltip-Chzzs4KB.js";import"./index-vDCSPjrM.js";import"./root-loader-BOzEMapJ.js";import"./pe-CIZUOJMr.js";import"./schemas-Uj5SZtvt.js";import"./discord-DlU9y5Iz.js";import"./user-BsPobzjB.js";import"./online-DiNLkgTC.js";import"./index-BOhw3wcM.js";import"./index-C_KjwKVt.js";import"./index-DzdDahau.js";import"./set-playground-DeMY9i7p.js";import"./button-CIlVtsau.js";import"./onboarding-indicator-CVwXz3Cn.js";import"./progress-bar-B27isaGl.js";import"./dialog-DnpUg3VT.js";import"./playground-window-D9a7P7rH.js";import"./accordion-CzXT3k43.js";import"./mdx-vrch0szL.js";import"./epic-video-BVcJzJzi.js";import"./use-event-source-BuD4_2SF.js";import"./preload-helper-BXl3LOEh.js";import"./launch-editor-B2dmpkaO.js";import"./revalidation-ws-BJWJviUX.js";const p=["playground","problem","solution","tests","diff","chat"],L=n=>!!(n&&p.includes(n)),vs=j(function({loaderData:e}){const{inBrowserBrowserRef:l}=A(),d=S(),[u]=C(),f=u.get("preview"),h=O(),x=N();function m(s){if(s==="tests")return ENV.EPICSHOP_DEPLOYED||!e.playground||e.playground.test.type==="none";if(s==="problem"||s==="solution"){if(e[s]?.dev.type==="none")return!0;if(ENV.EPICSHOP_DEPLOYED){const i=e[s]?.dev.type;return i!=="browser"&&i!=="export"&&!e[s]?.stackBlitzUrl}}return s==="playground"&&ENV.EPICSHOP_DEPLOYED?!0:s==="chat"?!d.product.discordChannelId:!1}function w(s){if(s==="tests"){if(!e.playground)return null;const{isTestRunning:i,testExitCode:o}=e.playground;return i?"running":o===0?"passed":o!==null&&o!==0?"failed":null}return(s==="problem"||s==="solution"||s==="playground")&&(s==="playground"?e.playground:e[s])?.isRunning?"running":null}const y=L(f)?f:p.find(s=>!m(s)),c=`/diff?${new URLSearchParams({app1:e.problem?.name??"",app2:e.solution?.name??""})}`;function g(s){s.altKey&&!s.ctrlKey&&!s.shiftKey&&!s.metaKey&&(s.preventDefault(),x(c))}const v=p.map(s=>{const i=m(s),o=w(s),P=s==="diff"&&h?c:`?${T(u,s,"playground")}`;return{id:s,label:s,hidden:i,status:o,to:P,onClick:s==="diff"?g:void 0}});return r.jsxs(H,{className:"relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden sm:col-span-1 sm:row-span-1",value:y,children:[r.jsx(U,{tabs:v}),r.jsxs("div",{className:"relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden",children:[r.jsx(t,{value:"playground",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:r.jsx(b,{appInfo:e.playground,problemAppName:e.problem?.name,inBrowserBrowserRef:l,allApps:e.allApps,isUpToDate:e.playground?.isUpToDate??!1})}),r.jsx(t,{value:"problem",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:r.jsx(a,{appInfo:e.problem,inBrowserBrowserRef:l})}),r.jsx(t,{value:"solution",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:r.jsx(a,{appInfo:e.solution,inBrowserBrowserRef:l})}),r.jsx(t,{value:"tests",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start overflow-hidden",children:r.jsx(k,{appInfo:e.playground,problemAppName:e.problem?.name,allApps:e.allApps,isUpToDate:e.playground?.isUpToDate??!1,userHasAccessPromise:e.userHasAccessPromise})}),r.jsx(t,{value:"diff",className:"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start",children:r.jsx(I,{diff:e.diff,allApps:e.allApps,userHasAccessPromise:e.userHasAccessPromise})}),r.jsx(t,{value:"chat",className:"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start",children:r.jsx(B,{discordPostsPromise:e.discordPostsPromise})})]})]})}),Ps=E(function(){return r.jsx(R,{statusHandlers:{404:()=>r.jsx("p",{children:"Sorry, we couldn't find an app here."})}})});export{Ps as ErrorBoundary,vs as default};
2
- //# sourceMappingURL=index-EdNV8gTk.js.map