@epic-web/workshop-app 6.47.10 → 6.47.12

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.
@@ -0,0 +1,27 @@
1
+ import{j as a}from"./jsx-runtime-C5WNSv3b.js";import{r as l}from"./index-Az39ZADK.js";import{u as Re,e as ke,f as L,g as W,P,h as T,i as A,j as Ie,D as Le,n as Me}from"./tooltip-C2AQeNhD.js";import{P as je,h as We,R as Ae,u as Ue,F as Fe}from"./index-Cod-PQ6D.js";import{c as D,I as He}from"./misc-BapXpylh.js";import{o as g,s as m,as as q,aJ as te,l as w,a as R,a1 as B,a2 as z}from"./types-Cl2NuNg4.js";import{e as $e}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{u as Ge}from"./online-Dw7HU4wM.js";import{u as N,a as qe}from"./root-loader-C5P2c7MU.js";var I="Dialog",[se]=ke(I),[Be,f]=se(I),oe=e=>{const{__scopeDialog:t,children:s,open:o,defaultOpen:r,onOpenChange:n,modal:d=!0}=e,i=l.useRef(null),c=l.useRef(null),[h,p]=Re({prop:o,defaultProp:r??!1,onChange:n,caller:I});return a.jsx(Be,{scope:t,triggerRef:i,contentRef:c,contentId:L(),titleId:L(),descriptionId:L(),open:h,onOpenChange:p,onOpenToggle:l.useCallback(()=>p(u=>!u),[p]),modal:d,children:s})};oe.displayName=I;var re="DialogTrigger",ne=l.forwardRef((e,t)=>{const{__scopeDialog:s,...o}=e,r=f(re,s),n=W(t,r.triggerRef);return a.jsx(P.button,{type:"button","aria-haspopup":"dialog","aria-expanded":r.open,"aria-controls":r.contentId,"data-state":H(r.open),...o,ref:n,onClick:T(e.onClick,r.onOpenToggle)})});ne.displayName=re;var U="DialogPortal",[ze,ie]=se(U,{forceMount:void 0}),ae=e=>{const{__scopeDialog:t,forceMount:s,children:o,container:r}=e,n=f(U,t);return a.jsx(ze,{scope:t,forceMount:s,children:l.Children.map(o,d=>a.jsx(A,{present:s||n.open,children:a.jsx(je,{asChild:!0,container:r,children:d})}))})};ae.displayName=U;var k="DialogOverlay",ce=l.forwardRef((e,t)=>{const s=ie(k,e.__scopeDialog),{forceMount:o=s.forceMount,...r}=e,n=f(k,e.__scopeDialog);return n.modal?a.jsx(A,{present:o||n.open,children:a.jsx(Ve,{...r,ref:t})}):null});ce.displayName=k;var Qe=Ie("DialogOverlay.RemoveScroll"),Ve=l.forwardRef((e,t)=>{const{__scopeDialog:s,...o}=e,r=f(k,s);return a.jsx(Ae,{as:Qe,allowPinchZoom:!0,shards:[r.contentRef],children:a.jsx(P.div,{"data-state":H(r.open),...o,ref:t,style:{pointerEvents:"auto",...o.style}})})}),E="DialogContent",le=l.forwardRef((e,t)=>{const s=ie(E,e.__scopeDialog),{forceMount:o=s.forceMount,...r}=e,n=f(E,e.__scopeDialog);return a.jsx(A,{present:o||n.open,children:n.modal?a.jsx(Je,{...r,ref:t}):a.jsx(Ye,{...r,ref:t})})});le.displayName=E;var Je=l.forwardRef((e,t)=>{const s=f(E,e.__scopeDialog),o=l.useRef(null),r=W(t,s.contentRef,o);return l.useEffect(()=>{const n=o.current;if(n)return We(n)},[]),a.jsx(ue,{...e,ref:r,trapFocus:s.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:T(e.onCloseAutoFocus,n=>{n.preventDefault(),s.triggerRef.current?.focus()}),onPointerDownOutside:T(e.onPointerDownOutside,n=>{const d=n.detail.originalEvent,i=d.button===0&&d.ctrlKey===!0;(d.button===2||i)&&n.preventDefault()}),onFocusOutside:T(e.onFocusOutside,n=>n.preventDefault())})}),Ye=l.forwardRef((e,t)=>{const s=f(E,e.__scopeDialog),o=l.useRef(!1),r=l.useRef(!1);return a.jsx(ue,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:n=>{e.onCloseAutoFocus?.(n),n.defaultPrevented||(o.current||s.triggerRef.current?.focus(),n.preventDefault()),o.current=!1,r.current=!1},onInteractOutside:n=>{e.onInteractOutside?.(n),n.defaultPrevented||(o.current=!0,n.detail.originalEvent.type==="pointerdown"&&(r.current=!0));const d=n.target;s.triggerRef.current?.contains(d)&&n.preventDefault(),n.detail.originalEvent.type==="focusin"&&r.current&&n.preventDefault()}})}),ue=l.forwardRef((e,t)=>{const{__scopeDialog:s,trapFocus:o,onOpenAutoFocus:r,onCloseAutoFocus:n,...d}=e,i=f(E,s),c=l.useRef(null),h=W(t,c);return Ue(),a.jsxs(a.Fragment,{children:[a.jsx(Fe,{asChild:!0,loop:!0,trapped:o,onMountAutoFocus:r,onUnmountAutoFocus:n,children:a.jsx(Le,{role:"dialog",id:i.contentId,"aria-describedby":i.descriptionId,"aria-labelledby":i.titleId,"data-state":H(i.open),...d,ref:h,onDismiss:()=>i.onOpenChange(!1)})}),a.jsxs(a.Fragment,{children:[a.jsx(Ke,{titleId:i.titleId}),a.jsx(Xe,{contentRef:c,descriptionId:i.descriptionId})]})]})}),F="DialogTitle",de=l.forwardRef((e,t)=>{const{__scopeDialog:s,...o}=e,r=f(F,s);return a.jsx(P.h2,{id:r.titleId,...o,ref:t})});de.displayName=F;var he="DialogDescription",pe=l.forwardRef((e,t)=>{const{__scopeDialog:s,...o}=e,r=f(he,s);return a.jsx(P.p,{id:r.descriptionId,...o,ref:t})});pe.displayName=he;var fe="DialogClose",me=l.forwardRef((e,t)=>{const{__scopeDialog:s,...o}=e,r=f(fe,s);return a.jsx(P.button,{type:"button",...o,ref:t,onClick:T(e.onClick,()=>r.onOpenChange(!1))})});me.displayName=fe;function H(e){return e?"open":"closed"}var ge="DialogTitleWarning",[$t,_e]=Me(ge,{contentName:E,titleName:F,docsSlug:"dialog"}),Ke=({titleId:e})=>{const t=_e(ge),s=`\`${t.contentName}\` requires a \`${t.titleName}\` for the component to be accessible for screen reader users.
2
+
3
+ If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component.
4
+
5
+ For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return l.useEffect(()=>{e&&(document.getElementById(e)||console.error(s))},[s,e]),null},Ze="DialogDescriptionWarning",Xe=({contentRef:e,descriptionId:t})=>{const o=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${_e(Ze).contentName}}.`;return l.useEffect(()=>{const r=e.current?.getAttribute("aria-describedby");t&&r&&(document.getElementById(t)||console.warn(o))},[o,e,t]),null},et=oe,tt=ne,st=ae,ye=ce,xe=le,ve=de,be=pe,ot=me;const Gt=et,qt=tt,rt=st;function we({className:e,ref:t,...s}){return a.jsx(ye,{ref:t,className:D("bg-background/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 backdrop-blur-sm",e),...s})}we.displayName=ye.displayName;function nt({className:e,children:t,ref:s,...o}){return a.jsxs(rt,{children:[a.jsx(we,{}),a.jsxs(xe,{ref:s,className:D("bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg md:w-full",e),...o,children:[t,a.jsxs(ot,{className:"ring-offset-background data-[state=open]:bg-accent data-[state=open]:text-muted-foreground focus:ring-ring absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none",children:[a.jsx(He,{name:"Close"}),a.jsx("span",{className:"sr-only",children:"Close"})]})]})]})}nt.displayName=xe.displayName;function it({className:e,...t}){return a.jsx("div",{className:D("flex flex-col space-y-1.5 text-center sm:text-left",e),...t})}it.displayName="DialogHeader";function at({className:e,ref:t,...s}){return a.jsx(ve,{ref:t,className:D("text-lg leading-none font-semibold tracking-tight",e),...s})}at.displayName=ve.displayName;function ct({className:e,ref:t,...s}){return a.jsx(be,{ref:t,className:D("text-muted-foreground text-sm",e),...s})}ct.displayName=be.displayName;const Ee="epic-web-presence",lt=`https://epic-web-presence.kentcdodds.partykit.dev/parties/main/${Ee}`,Q=g({workshopTitle:m().nullable().optional(),origin:m().nullable().optional(),productHost:m().nullable().optional(),exercise:g({type:te([w("problem"),w("solution")]).nullable().optional(),exerciseNumber:q().nullable().optional(),stepNumber:q().nullable().optional()}).nullable().optional()}),j=g({id:m(),hasAccess:B().nullable().optional(),avatarUrl:m().nullable().optional(),imageUrlSmall:m().nullable().optional(),imageUrlLarge:m().nullable().optional(),name:m().nullable().optional(),optOut:B().nullable().optional(),loggedInProductHosts:R(m()).nullable().optional(),location:Q.nullable().optional(),locations:R(Q).nullable().optional()}),ut=g({type:w("remove-user"),payload:g({id:m()})}).or(g({type:w("add-user"),payload:j})).or(g({type:w("presence"),payload:g({users:R(j)})}));g({users:R(j)});const dt={"www.epicreact.dev":"🚀","www.epicai.pro":"⚡","www.epicweb.dev":"🌌"};function Bt(e){return e?dt[e]??null:null}(!globalThis.EventTarget||!globalThis.Event)&&console.error(`
6
+ PartySocket requires a global 'EventTarget' class to be available!
7
+ You can polyfill this global by adding this to your code before any partysocket imports:
8
+
9
+ \`\`\`
10
+ import 'partysocket/event-target-polyfill';
11
+ \`\`\`
12
+ Please file an issue at https://github.com/partykit/partykit if you're still having trouble.
13
+ `);var Ce=class extends Event{message;error;constructor(e,t){super("error",t),this.message=e.message,this.error=e}},Ne=class extends Event{code;reason;wasClean=!0;constructor(e=1e3,t="",s){super("close",s),this.code=e,this.reason=t}},M={Event,ErrorEvent:Ce,CloseEvent:Ne};function ht(e,t){if(!e)throw new Error(t)}function pt(e){return new e.constructor(e.type,e)}function ft(e){return"data"in e?new MessageEvent(e.type,e):"code"in e||"reason"in e?new Ne(e.code||1999,e.reason||"unknown reason",e):"error"in e?new Ce(e.error,e):new Event(e.type,e)}var V,mt=typeof process<"u"&&typeof((V=process.versions)==null?void 0:V.node)<"u"&&typeof document>"u",O=mt?ft:pt,v={maxReconnectionDelay:1e4,minReconnectionDelay:1e3+Math.random()*4e3,minUptime:5e3,reconnectionDelayGrowFactor:1.3,connectionTimeout:4e3,maxRetries:Number.POSITIVE_INFINITY,maxEnqueuedMessages:Number.POSITIVE_INFINITY},J=!1,gt=class b extends EventTarget{_ws;_retryCount=-1;_uptimeTimeout;_connectTimeout;_shouldReconnect=!0;_connectLock=!1;_binaryType="blob";_closeCalled=!1;_messageQueue=[];_debugLogger=console.log.bind(console);_url;_protocols;_options;constructor(t,s,o={}){super(),this._url=t,this._protocols=s,this._options=o,this._options.startClosed&&(this._shouldReconnect=!1),this._options.debugLogger&&(this._debugLogger=this._options.debugLogger),this._connect()}static get CONNECTING(){return 0}static get OPEN(){return 1}static get CLOSING(){return 2}static get CLOSED(){return 3}get CONNECTING(){return b.CONNECTING}get OPEN(){return b.OPEN}get CLOSING(){return b.CLOSING}get CLOSED(){return b.CLOSED}get binaryType(){return this._ws?this._ws.binaryType:this._binaryType}set binaryType(t){this._binaryType=t,this._ws&&(this._ws.binaryType=t)}get retryCount(){return Math.max(this._retryCount,0)}get bufferedAmount(){return this._messageQueue.reduce((s,o)=>(typeof o=="string"?s+=o.length:o instanceof Blob?s+=o.size:s+=o.byteLength,s),0)+(this._ws?this._ws.bufferedAmount:0)}get extensions(){return this._ws?this._ws.extensions:""}get protocol(){return this._ws?this._ws.protocol:""}get readyState(){return this._ws?this._ws.readyState:this._options.startClosed?b.CLOSED:b.CONNECTING}get url(){return this._ws?this._ws.url:""}get shouldReconnect(){return this._shouldReconnect}onclose=null;onerror=null;onmessage=null;onopen=null;close(t=1e3,s){if(this._closeCalled=!0,this._shouldReconnect=!1,this._clearTimeouts(),!this._ws){this._debug("close enqueued: no ws instance");return}if(this._ws.readyState===this.CLOSED){this._debug("close: already closed");return}this._ws.close(t,s)}reconnect(t,s){this._shouldReconnect=!0,this._closeCalled=!1,this._retryCount=-1,!this._ws||this._ws.readyState===this.CLOSED?this._connect():(this._disconnect(t,s),this._connect())}send(t){if(this._ws&&this._ws.readyState===this.OPEN)this._debug("send",t),this._ws.send(t);else{const{maxEnqueuedMessages:s=v.maxEnqueuedMessages}=this._options;this._messageQueue.length<s&&(this._debug("enqueue",t),this._messageQueue.push(t))}}_debug(...t){this._options.debug&&this._debugLogger("RWS>",...t)}_getNextDelay(){const{reconnectionDelayGrowFactor:t=v.reconnectionDelayGrowFactor,minReconnectionDelay:s=v.minReconnectionDelay,maxReconnectionDelay:o=v.maxReconnectionDelay}=this._options;let r=0;return this._retryCount>0&&(r=s*t**(this._retryCount-1),r>o&&(r=o)),this._debug("next delay",r),r}_wait(){return new Promise(t=>{setTimeout(t,this._getNextDelay())})}_getNextProtocols(t){if(!t)return Promise.resolve(null);if(typeof t=="string"||Array.isArray(t))return Promise.resolve(t);if(typeof t=="function"){const s=t();if(!s)return Promise.resolve(null);if(typeof s=="string"||Array.isArray(s))return Promise.resolve(s);if(s.then)return s}throw Error("Invalid protocols")}_getNextUrl(t){if(typeof t=="string")return Promise.resolve(t);if(typeof t=="function"){const s=t();if(typeof s=="string")return Promise.resolve(s);if(s.then)return s}throw Error("Invalid URL")}_connect(){if(this._connectLock||!this._shouldReconnect)return;this._connectLock=!0;const{maxRetries:t=v.maxRetries,connectionTimeout:s=v.connectionTimeout}=this._options;if(this._retryCount>=t){this._debug("max retries reached",this._retryCount,">=",t);return}this._retryCount++,this._debug("connect",this._retryCount),this._removeListeners(),this._wait().then(()=>Promise.all([this._getNextUrl(this._url),this._getNextProtocols(this._protocols||null)])).then(([o,r])=>{if(this._closeCalled){this._connectLock=!1;return}!this._options.WebSocket&&typeof WebSocket>"u"&&!J&&(console.error(`‼️ No WebSocket implementation available. You should define options.WebSocket.
14
+
15
+ For example, if you're using node.js, run \`npm install ws\`, and then in your code:
16
+
17
+ import PartySocket from 'partysocket';
18
+ import WS from 'ws';
19
+
20
+ const partysocket = new PartySocket({
21
+ host: "127.0.0.1:1999",
22
+ room: "test-room",
23
+ WebSocket: WS
24
+ });
25
+
26
+ `),J=!0);const n=this._options.WebSocket||WebSocket;this._debug("connect",{url:o,protocols:r}),this._ws=r?new n(o,r):new n(o),this._ws.binaryType=this._binaryType,this._connectLock=!1,this._addListeners(),this._connectTimeout=setTimeout(()=>this._handleTimeout(),s)}).catch(o=>{this._connectLock=!1,this._handleError(new M.ErrorEvent(Error(o.message),this))})}_handleTimeout(){this._debug("timeout event"),this._handleError(new M.ErrorEvent(Error("TIMEOUT"),this))}_disconnect(t=1e3,s){if(this._clearTimeouts(),!!this._ws){this._removeListeners();try{(this._ws.readyState===this.OPEN||this._ws.readyState===this.CONNECTING)&&this._ws.close(t,s),this._handleClose(new M.CloseEvent(t,s,this))}catch{}}}_acceptOpen(){this._debug("accept open"),this._retryCount=0}_handleOpen=t=>{this._debug("open event");const{minUptime:s=v.minUptime}=this._options;clearTimeout(this._connectTimeout),this._uptimeTimeout=setTimeout(()=>this._acceptOpen(),s),ht(this._ws,"WebSocket is not defined"),this._ws.binaryType=this._binaryType,this._messageQueue.forEach(o=>{var r;(r=this._ws)==null||r.send(o)}),this._messageQueue=[],this.onopen&&this.onopen(t),this.dispatchEvent(O(t))};_handleMessage=t=>{this._debug("message event"),this.onmessage&&this.onmessage(t),this.dispatchEvent(O(t))};_handleError=t=>{this._debug("error event",t.message),this._disconnect(void 0,t.message==="TIMEOUT"?"timeout":void 0),this.onerror&&this.onerror(t),this._debug("exec error listeners"),this.dispatchEvent(O(t)),this._connect()};_handleClose=t=>{this._debug("close event"),this._clearTimeouts(),this._shouldReconnect&&this._connect(),this.onclose&&this.onclose(t),this.dispatchEvent(O(t))};_removeListeners(){this._ws&&(this._debug("removeListeners"),this._ws.removeEventListener("open",this._handleOpen),this._ws.removeEventListener("close",this._handleClose),this._ws.removeEventListener("message",this._handleMessage),this._ws.removeEventListener("error",this._handleError))}_addListeners(){this._ws&&(this._debug("addListeners"),this._ws.addEventListener("open",this._handleOpen),this._ws.addEventListener("close",this._handleClose),this._ws.addEventListener("message",this._handleMessage),this._ws.addEventListener("error",this._handleError))}_clearTimeouts(){clearTimeout(this._connectTimeout),clearTimeout(this._uptimeTimeout)}};var _t=e=>e[1]!==null&&e[1]!==void 0;function yt(){if(crypto!=null&&crypto.randomUUID)return crypto.randomUUID();let e=Date.now(),t=performance?.now&&performance.now()*1e3||0;return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(s){let o=Math.random()*16;return e>0?(o=(e+o)%16|0,e=Math.floor(e/16)):(o=(t+o)%16|0,t=Math.floor(t/16)),(s==="x"?o:o&3|8).toString(16)})}function Te(e,t,s={}){const{host:o,path:r,protocol:n,room:d,party:i,basePath:c,prefix:h,query:p}=e;let u=o.replace(/^(http|https|ws|wss):\/\//,"");if(u.endsWith("/")&&(u=u.slice(0,-1)),r?.startsWith("/"))throw new Error("path must not start with a slash");const _=i??"main",C=r?`/${r}`:"",x=n||(u.startsWith("localhost:")||u.startsWith("127.0.0.1:")||u.startsWith("192.168.")||u.startsWith("10.")||u.startsWith("172.")&&u.split(".")[1]>="16"&&u.split(".")[1]<="31"||u.startsWith("[::ffff:7f00:1]:")?t:`${t}s`),y=`${x}://${u}/${c||`${h||"parties"}/${_}/${d}`}${C}`,G=(Oe={})=>`${y}?${new URLSearchParams([...Object.entries(s),...Object.entries(Oe).filter(_t)])}`,Se=typeof p=="function"?async()=>G(await p()):G(p);return{host:u,path:C,room:d,name:_,protocol:x,partyUrl:y,urlProvider:Se}}var xt=class extends gt{constructor(e){var t,s;const o=Y(e);super(o.urlProvider,o.protocols,o.socketOptions),this.partySocketOptions=e,this.setWSProperties(o),e.disableNameValidation||((t=e.party)!=null&&t.includes("/")&&console.warn(`PartySocket: party name "${e.party}" contains forward slash which may cause routing issues. Consider using a name without forward slashes or set disableNameValidation: true to bypass this warning.`),(s=e.room)!=null&&s.includes("/")&&console.warn(`PartySocket: room name "${e.room}" contains forward slash which may cause routing issues. Consider using a name without forward slashes or set disableNameValidation: true to bypass this warning.`))}_pk;_pkurl;name;room;host;path;updateProperties(e){const t=Y({...this.partySocketOptions,...e,host:e.host??this.host,room:e.room??this.room,path:e.path??this.path});this._url=t.urlProvider,this._protocols=t.protocols,this._options=t.socketOptions,this.setWSProperties(t)}setWSProperties(e){const{_pk:t,_pkurl:s,name:o,room:r,host:n,path:d}=e;this._pk=t,this._pkurl=s,this.name=o,this.room=r,this.host=n,this.path=d}reconnect(e,t){if(!this.room||!this.host)throw new Error("The room and host must be set before connecting, use `updateProperties` method to set them or pass them to the constructor.");super.reconnect(e,t)}get id(){return this._pk}get roomUrl(){return this._pkurl}static async fetch(e,t){const s=Te(e,"http"),o=typeof s.urlProvider=="string"?s.urlProvider:await s.urlProvider();return(e.fetch??fetch)(o,t)}};function Y(e){const{id:t,host:s,path:o,party:r,room:n,protocol:d,query:i,protocols:c,...h}=e,p=t||yt(),u=Te(e,"ws",{_pk:p});return{_pk:p,_pkurl:u.partyUrl,name:u.name,room:u.room,host:u.host,path:u.path,protocols:c,socketOptions:h,urlProvider:u.urlProvider}}var vt=(e,t)=>{const s=l.useRef(t);s.current=t,l.useEffect(()=>{const o=i=>{var c,h;return(h=(c=s.current)==null?void 0:c.onOpen)==null?void 0:h.call(c,i)},r=i=>{var c,h;return(h=(c=s.current)==null?void 0:c.onMessage)==null?void 0:h.call(c,i)},n=i=>{var c,h;return(h=(c=s.current)==null?void 0:c.onClose)==null?void 0:h.call(c,i)},d=i=>{var c,h;return(h=(c=s.current)==null?void 0:c.onError)==null?void 0:h.call(c,i)};return e.addEventListener("open",o),e.addEventListener("close",n),e.addEventListener("error",d),e.addEventListener("message",r),()=>{e.removeEventListener("open",o),e.removeEventListener("close",n),e.removeEventListener("error",d),e.removeEventListener("message",r)}},[e])},bt=e=>[e.startClosed,e.minUptime,e.maxRetries,e.connectionTimeout,e.maxEnqueuedMessages,e.maxReconnectionDelay,e.minReconnectionDelay,e.reconnectionDelayGrowFactor,e.debug];function wt({options:e,createSocket:t,createSocketMemoKey:s}){const o=s(e),r=l.useMemo(()=>e,[o]),[n,d]=l.useState(()=>t({...r,startClosed:!0})),i=l.useRef(null),c=l.useRef(t);return c.current=t,l.useEffect(()=>{if(i.current===n){const h=c.current({...r,startClosed:!1});d(h)}else return!i.current&&r.startClosed!==!0&&n.reconnect(),i.current=n,()=>{n.close()}},[n,r]),n}function Et(e){const{host:t,...s}=e,o=wt({options:{host:t||(typeof window<"u"?window.location.host:"dummy-domain.com"),...s},createSocket:r=>new xt(r),createSocketMemoKey:r=>JSON.stringify([r.query,r.id,r.host,r.room,r.party,r.path,r.protocol,r.protocols,r.basePath,r.prefix,...bt(r)])});return vt(o,e),o}const $=l.createContext(null);function Ct(){return N()?.preferences?.presence??null}function Nt(){return N()?.workshopTitle??null}const Tt=g({type:te([w("problem"),w("solution")]).optional(),exerciseNumber:z.number().finite(),stepNumber:z.number().finite().optional()});function Pt(e,t){const[s]=l.useState(()=>new Promise(i=>setTimeout(i,t))),o=l.useRef(!0),r=l.useRef(null),n=l.useRef(e);return l.useEffect(()=>{n.current=e},[e]),l.useCallback((...i)=>{const c=Symbol();r.current=c,s.then(()=>{o.current&&r.current===c&&n.current(...i)})},[s])}function Dt(){return N()?.workshopConfig?.product?.host??null}function St(){return N()?.loggedInProductHosts??[]}function Pe(){const e=Nt(),t=qe(),s=Dt(),o=$e(),r=Tt.safeParse(o),n=r.success?r.data:null;return{workshopTitle:e,origin:t.origin,productHost:s,...n?{exercise:{type:n.type,exerciseNumber:n.exerciseNumber,stepNumber:n.stepNumber}}:null}}function Ot(e){const t=Ct(),{userHasAccess:s=!1,userId:o,presence:r}=N()??{},[n,d]=l.useState(r?.users??[]),i=Pe(),c=St(),h=Pt(x=>{const y=ut.safeParse(JSON.parse(String(x.data)));y.success&&y.data.type==="presence"&&d(y.data.payload.users)},2e3),p=Et({host:new URL(lt).host,room:Ee,onMessage:h});let u=null;e?t?.optOut?u={type:"add-user",payload:{id:e.id,optOut:!0,loggedInProductHosts:c}}:u={type:"add-user",payload:{id:e.id,name:e.name,hasAccess:s,imageUrlSmall:e.imageUrlSmall,imageUrlLarge:e.imageUrlLarge,location:i,loggedInProductHosts:c}}:o?.id&&(u={type:"add-user",payload:{id:o.id,location:i,loggedInProductHosts:c}});const _=u?JSON.stringify(u):null;return l.useEffect(()=>{_&&p.send(_)},[_,p]),{users:De({id:o?.id,location:i},n)}}function S(e){return e.locations&&e.locations.length>0?e.locations.filter(Boolean):e.location?[e.location]:[]}function De(e,t){const{location:s}=e;return t.map(r=>{let n=0;if(r.optOut)return{user:r,score:0};const d=S(r);for(const i of d)s?.workshopTitle&&s.workshopTitle===i.workshopTitle?(n=Math.max(n,.4),s.exercise?.exerciseNumber!=null&&s.exercise.exerciseNumber===i.exercise?.exerciseNumber&&(n=Math.max(n,.6),s.exercise.stepNumber!=null&&s.exercise.stepNumber===i.exercise?.stepNumber&&(n=Math.max(n,.8),s.exercise.type&&s.exercise.type===i.exercise?.type&&(n=1)))):s?.productHost&&s.productHost===i.productHost&&(n=Math.max(n,.2));return{user:r,score:n}}).sort((r,n)=>{if(r.user.id===e.id)return-1;if(n.user.id===e.id||r.user.optOut&&!n.user.optOut)return 1;if(!r.user.optOut&&n.user.optOut)return-1;const d=K(s,r.user),i=K(s,n.user);if(d&&!i)return-1;if(!d&&i)return 1;const c=Z(s,r.user),h=Z(s,n.user);if(c&&!h)return-1;if(!c&&h)return 1;const p=X(s,r.user),u=X(s,n.user);if(p&&!u)return-1;if(!p&&u)return 1;const _=ee(s,r.user),C=ee(s,n.user);if(_&&!C)return-1;if(!_&&C)return 1;const x=r.user.loggedInProductHosts?.length??0,y=n.user.loggedInProductHosts?.length??0;return x!==y?y-x:0})}function K(e,t){return e?.exercise?S(t).some(o=>o.workshopTitle===e.workshopTitle&&o.exercise?.exerciseNumber===e.exercise?.exerciseNumber&&o.exercise?.stepNumber===e.exercise?.stepNumber&&o.exercise?.type===e.exercise?.type):!1}function Z(e,t){return e?.exercise?.exerciseNumber?S(t).some(o=>o.workshopTitle===e.workshopTitle&&o.exercise?.exerciseNumber===e.exercise?.exerciseNumber):!1}function X(e,t){return e?.workshopTitle?S(t).some(o=>o.workshopTitle===e.workshopTitle):!1}function ee(e,t){return e?.productHost?S(t).some(o=>o.productHost===e.productHost):!1}function Rt({user:e,children:t}){return a.jsx($.Provider,{value:Ot(e),children:t})}function kt({user:e,children:t}){const s=Pe(),{presence:o}=N()??{};return a.jsx($.Provider,{value:{users:De({id:e?.id,location:s},o?.users??[])},children:t})}function zt({user:e,children:t}){return Ge()?a.jsx(Rt,{user:e,children:t}):a.jsx(kt,{user:e,children:t})}function Qt(){const e=l.useContext($);if(!e)throw new Error("usePresence must be used within a PresenceProvider");return e}export{Gt as D,zt as P,qt as a,nt as b,it as c,ct as d,at as e,Bt as g,dt as p,Qt as u};
27
+ //# sourceMappingURL=presence-D6KivDVU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence-D6KivDVU.js","sources":["../../../../../node_modules/@radix-ui/react-dialog/dist/index.mjs","../../../app/components/ui/dialog.tsx","../../../../workshop-presence/src/presence.ts","../../../../../node_modules/partysocket/dist/chunk-V6LO7DXK.mjs","../../../../../node_modules/partysocket/dist/chunk-7TNWDF55.mjs","../../../../../node_modules/partysocket/dist/chunk-PTE3YP23.mjs","../../../../../node_modules/partysocket/dist/react.mjs","../../../app/utils/presence.tsx"],"sourcesContent":["\"use client\";\n\n// src/dialog.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContext, createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { DismissableLayer } from \"@radix-ui/react-dismissable-layer\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { hideOthers } from \"aria-hidden\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nvar DIALOG_NAME = \"Dialog\";\nvar [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);\nvar [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);\nvar Dialog = (props) => {\n const {\n __scopeDialog,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true\n } = props;\n const triggerRef = React.useRef(null);\n const contentRef = React.useRef(null);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: DIALOG_NAME\n });\n return /* @__PURE__ */ jsx(\n DialogProvider,\n {\n scope: __scopeDialog,\n triggerRef,\n contentRef,\n contentId: useId(),\n titleId: useId(),\n descriptionId: useId(),\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n modal,\n children\n }\n );\n};\nDialog.displayName = DIALOG_NAME;\nvar TRIGGER_NAME = \"DialogTrigger\";\nvar DialogTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...triggerProps } = props;\n const context = useDialogContext(TRIGGER_NAME, __scopeDialog);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.contentId,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }\n);\nDialogTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"DialogPortal\";\nvar [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar DialogPortal = (props) => {\n const { __scopeDialog, forceMount, children, container } = props;\n const context = useDialogContext(PORTAL_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) });\n};\nDialogPortal.displayName = PORTAL_NAME;\nvar OVERLAY_NAME = \"DialogOverlay\";\nvar DialogOverlay = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);\n return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;\n }\n);\nDialogOverlay.displayName = OVERLAY_NAME;\nvar Slot = createSlot(\"DialogOverlay.RemoveScroll\");\nvar DialogOverlayImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, __scopeDialog);\n return (\n // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`\n // ie. when `Overlay` and `Content` are siblings\n /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n ...overlayProps,\n ref: forwardedRef,\n style: { pointerEvents: \"auto\", ...overlayProps.style }\n }\n ) })\n );\n }\n);\nvar CONTENT_NAME = \"DialogContent\";\nvar DialogContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }\n);\nDialogContent.displayName = CONTENT_NAME;\nvar DialogContentModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: true,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n if (isRightClick) event.preventDefault();\n }),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault()\n )\n }\n );\n }\n);\nvar DialogContentNonModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }\n);\nvar DialogContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, __scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, contentRef);\n useFocusGuards();\n return /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n role: \"dialog\",\n id: context.contentId,\n \"aria-describedby\": context.descriptionId,\n \"aria-labelledby\": context.titleId,\n \"data-state\": getState(context.open),\n ...contentProps,\n ref: composedRefs,\n onDismiss: () => context.onOpenChange(false)\n }\n )\n }\n ),\n /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(TitleWarning, { titleId: context.titleId }),\n /* @__PURE__ */ jsx(DescriptionWarning, { contentRef, descriptionId: context.descriptionId })\n ] })\n ] });\n }\n);\nvar TITLE_NAME = \"DialogTitle\";\nvar DialogTitle = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...titleProps } = props;\n const context = useDialogContext(TITLE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });\n }\n);\nDialogTitle.displayName = TITLE_NAME;\nvar DESCRIPTION_NAME = \"DialogDescription\";\nvar DialogDescription = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...descriptionProps } = props;\n const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });\n }\n);\nDialogDescription.displayName = DESCRIPTION_NAME;\nvar CLOSE_NAME = \"DialogClose\";\nvar DialogClose = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...closeProps } = props;\n const context = useDialogContext(CLOSE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }\n);\nDialogClose.displayName = CLOSE_NAME;\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nvar TITLE_WARNING_NAME = \"DialogTitleWarning\";\nvar [WarningProvider, useWarningContext] = createContext(TITLE_WARNING_NAME, {\n contentName: CONTENT_NAME,\n titleName: TITLE_NAME,\n docsSlug: \"dialog\"\n});\nvar TitleWarning = ({ titleId }) => {\n const titleWarningContext = useWarningContext(TITLE_WARNING_NAME);\n const MESSAGE = `\\`${titleWarningContext.contentName}\\` requires a \\`${titleWarningContext.titleName}\\` for the component to be accessible for screen reader users.\n\nIf you want to hide the \\`${titleWarningContext.titleName}\\`, you can wrap it with our VisuallyHidden component.\n\nFor more information, see https://radix-ui.com/primitives/docs/components/${titleWarningContext.docsSlug}`;\n React.useEffect(() => {\n if (titleId) {\n const hasTitle = document.getElementById(titleId);\n if (!hasTitle) console.error(MESSAGE);\n }\n }, [MESSAGE, titleId]);\n return null;\n};\nvar DESCRIPTION_WARNING_NAME = \"DialogDescriptionWarning\";\nvar DescriptionWarning = ({ contentRef, descriptionId }) => {\n const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME);\n const MESSAGE = `Warning: Missing \\`Description\\` or \\`aria-describedby={undefined}\\` for {${descriptionWarningContext.contentName}}.`;\n React.useEffect(() => {\n const describedById = contentRef.current?.getAttribute(\"aria-describedby\");\n if (descriptionId && describedById) {\n const hasDescription = document.getElementById(descriptionId);\n if (!hasDescription) console.warn(MESSAGE);\n }\n }, [MESSAGE, contentRef, descriptionId]);\n return null;\n};\nvar Root = Dialog;\nvar Trigger = DialogTrigger;\nvar Portal = DialogPortal;\nvar Overlay = DialogOverlay;\nvar Content = DialogContent;\nvar Title = DialogTitle;\nvar Description = DialogDescription;\nvar Close = DialogClose;\nexport {\n Close,\n Content,\n Description,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n Overlay,\n Portal,\n Root,\n Title,\n Trigger,\n WarningProvider,\n createDialogScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as DialogPrimitive from '@radix-ui/react-dialog'\nimport * as React from 'react'\nimport { cn } from '#app/utils/misc.tsx'\nimport { Icon } from '../icons'\n\nconst Dialog = DialogPrimitive.Root\n\nconst DialogTrigger = DialogPrimitive.Trigger\n\nconst DialogPortal = DialogPrimitive.Portal\n\nconst DialogClose = DialogPrimitive.Close\n\nfunction DialogOverlay({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n\treturn (\n\t\t<DialogPrimitive.Overlay\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t'bg-background/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 backdrop-blur-sm',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\nfunction DialogContent({\n\tclassName,\n\tchildren,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Content>) {\n\treturn (\n\t\t<DialogPortal>\n\t\t\t<DialogOverlay />\n\t\t\t<DialogPrimitive.Content\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t<DialogPrimitive.Close className=\"ring-offset-background data-[state=open]:bg-accent data-[state=open]:text-muted-foreground focus:ring-ring absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none\">\n\t\t\t\t\t<Icon name=\"Close\" />\n\t\t\t\t\t<span className=\"sr-only\">Close</span>\n\t\t\t\t</DialogPrimitive.Close>\n\t\t\t</DialogPrimitive.Content>\n\t\t</DialogPortal>\n\t)\n}\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\nfunction DialogHeader({\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex flex-col space-y-1.5 text-center sm:text-left',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogHeader.displayName = 'DialogHeader'\n\nfunction DialogFooter({\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogFooter.displayName = 'DialogFooter'\n\nfunction DialogTitle({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n\treturn (\n\t\t<DialogPrimitive.Title\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t'text-lg leading-none font-semibold tracking-tight',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nfunction DialogDescription({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n\treturn (\n\t\t<DialogPrimitive.Description\n\t\t\tref={ref}\n\t\t\tclassName={cn('text-muted-foreground text-sm', className)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport {\n\tDialog,\n\tDialogClose,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogOverlay,\n\tDialogPortal,\n\tDialogTitle,\n\tDialogTrigger,\n}\n","import { z } from 'zod'\n\nexport const partykitRoom = 'epic-web-presence'\n// export const partykitBaseUrl = `http://127.0.0.1:1999/parties/main/${partykitRoom}`\nexport const partykitBaseUrl = `https://epic-web-presence.kentcdodds.partykit.dev/parties/main/${partykitRoom}`\n\nexport const LocationSchema = z.object({\n\tworkshopTitle: z.string().nullable().optional(),\n\torigin: z.string().nullable().optional(),\n\tproductHost: z.string().nullable().optional(),\n\texercise: z\n\t\t.object({\n\t\t\ttype: z\n\t\t\t\t.union([z.literal('problem'), z.literal('solution')])\n\t\t\t\t.nullable()\n\t\t\t\t.optional(),\n\t\t\texerciseNumber: z.number().nullable().optional(),\n\t\t\tstepNumber: z.number().nullable().optional(),\n\t\t})\n\t\t.nullable()\n\t\t.optional(),\n})\n\nexport type Location = z.infer<typeof LocationSchema>\n\nexport const UserSchema = z.object({\n\tid: z.string(),\n\thasAccess: z.boolean().nullable().optional(),\n\t// TODO: remove the avatarUrl field once people have updated their workshops\n\tavatarUrl: z.string().nullable().optional(),\n\timageUrlSmall: z.string().nullable().optional(),\n\timageUrlLarge: z.string().nullable().optional(),\n\tname: z.string().nullable().optional(),\n\toptOut: z.boolean().nullable().optional(),\n\tloggedInProductHosts: z.array(z.string()).nullable().optional(),\n\t// Single location (for backward compat and single-connection case)\n\tlocation: LocationSchema.nullable().optional(),\n\t// Multiple locations when user is connected from multiple workshops\n\tlocations: z.array(LocationSchema).nullable().optional(),\n})\n\nexport const MessageSchema = z\n\t.object({\n\t\ttype: z.literal('remove-user'),\n\t\tpayload: z.object({ id: z.string() }),\n\t})\n\t.or(z.object({ type: z.literal('add-user'), payload: UserSchema }))\n\t.or(\n\t\tz.object({\n\t\t\ttype: z.literal('presence'),\n\t\t\tpayload: z.object({ users: z.array(UserSchema) }),\n\t\t}),\n\t)\n\nexport type Message = z.infer<typeof MessageSchema>\n\nexport type User = z.infer<typeof UserSchema>\n\nexport const PresenceSchema = z.object({ users: z.array(UserSchema) })\n\n// Product host to emoji mapping for FacePile badges\nexport const productHostEmojis: Record<string, string> = {\n\t'www.epicreact.dev': '🚀',\n\t'www.epicai.pro': '⚡',\n\t'www.epicweb.dev': '🌌',\n}\n\nexport function getProductHostEmoji(\n\thost: string | null | undefined,\n): string | null {\n\tif (!host) return null\n\treturn productHostEmojis[host] ?? null\n}\n","// src/ws.ts\nif (!globalThis.EventTarget || !globalThis.Event) {\n console.error(`\n PartySocket requires a global 'EventTarget' class to be available!\n You can polyfill this global by adding this to your code before any partysocket imports: \n \n \\`\\`\\`\n import 'partysocket/event-target-polyfill';\n \\`\\`\\`\n Please file an issue at https://github.com/partykit/partykit if you're still having trouble.\n`);\n}\nvar ErrorEvent = class extends Event {\n message;\n error;\n // biome-ignore lint/suspicious/noExplicitAny: vibes\n constructor(error, target) {\n super(\"error\", target);\n this.message = error.message;\n this.error = error;\n }\n};\nvar CloseEvent = class extends Event {\n code;\n reason;\n wasClean = true;\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n constructor(code = 1e3, reason = \"\", target) {\n super(\"close\", target);\n this.code = code;\n this.reason = reason;\n }\n};\nvar Events = {\n Event,\n ErrorEvent,\n CloseEvent\n};\nfunction assert(condition, msg) {\n if (!condition) {\n throw new Error(msg);\n }\n}\nfunction cloneEventBrowser(e) {\n return new e.constructor(e.type, e);\n}\nfunction cloneEventNode(e) {\n if (\"data\" in e) {\n const evt2 = new MessageEvent(e.type, e);\n return evt2;\n }\n if (\"code\" in e || \"reason\" in e) {\n const evt2 = new CloseEvent(\n // @ts-expect-error we need to fix event/listener types\n e.code || 1999,\n // @ts-expect-error we need to fix event/listener types\n e.reason || \"unknown reason\",\n e\n );\n return evt2;\n }\n if (\"error\" in e) {\n const evt2 = new ErrorEvent(e.error, e);\n return evt2;\n }\n const evt = new Event(e.type, e);\n return evt;\n}\nvar _a;\nvar isNode =\n typeof process !== \"undefined\" &&\n typeof ((_a = process.versions) == null ? void 0 : _a.node) !== \"undefined\" &&\n typeof document === \"undefined\";\nvar cloneEvent = isNode ? cloneEventNode : cloneEventBrowser;\nvar DEFAULT = {\n maxReconnectionDelay: 1e4,\n minReconnectionDelay: 1e3 + Math.random() * 4e3,\n minUptime: 5e3,\n reconnectionDelayGrowFactor: 1.3,\n connectionTimeout: 4e3,\n maxRetries: Number.POSITIVE_INFINITY,\n maxEnqueuedMessages: Number.POSITIVE_INFINITY,\n startClosed: false,\n debug: false\n};\nvar didWarnAboutMissingWebSocket = false;\nvar ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget {\n _ws;\n _retryCount = -1;\n _uptimeTimeout;\n _connectTimeout;\n _shouldReconnect = true;\n _connectLock = false;\n _binaryType = \"blob\";\n _closeCalled = false;\n _messageQueue = [];\n _debugLogger = console.log.bind(console);\n _url;\n _protocols;\n _options;\n constructor(url, protocols, options = {}) {\n super();\n this._url = url;\n this._protocols = protocols;\n this._options = options;\n if (this._options.startClosed) {\n this._shouldReconnect = false;\n }\n if (this._options.debugLogger) {\n this._debugLogger = this._options.debugLogger;\n }\n this._connect();\n }\n static get CONNECTING() {\n return 0;\n }\n static get OPEN() {\n return 1;\n }\n static get CLOSING() {\n return 2;\n }\n static get CLOSED() {\n return 3;\n }\n get CONNECTING() {\n return _ReconnectingWebSocket.CONNECTING;\n }\n get OPEN() {\n return _ReconnectingWebSocket.OPEN;\n }\n get CLOSING() {\n return _ReconnectingWebSocket.CLOSING;\n }\n get CLOSED() {\n return _ReconnectingWebSocket.CLOSED;\n }\n get binaryType() {\n return this._ws ? this._ws.binaryType : this._binaryType;\n }\n set binaryType(value) {\n this._binaryType = value;\n if (this._ws) {\n this._ws.binaryType = value;\n }\n }\n /**\n * Returns the number or connection retries\n */\n get retryCount() {\n return Math.max(this._retryCount, 0);\n }\n /**\n * The number of bytes of data that have been queued using calls to send() but not yet\n * transmitted to the network. This value resets to zero once all queued data has been sent.\n * This value does not reset to zero when the connection is closed; if you keep calling send(),\n * this will continue to climb. Read only\n */\n get bufferedAmount() {\n const bytes = this._messageQueue.reduce((acc, message) => {\n if (typeof message === \"string\") {\n acc += message.length;\n } else if (message instanceof Blob) {\n acc += message.size;\n } else {\n acc += message.byteLength;\n }\n return acc;\n }, 0);\n return bytes + (this._ws ? this._ws.bufferedAmount : 0);\n }\n /**\n * The extensions selected by the server. This is currently only the empty string or a list of\n * extensions as negotiated by the connection\n */\n get extensions() {\n return this._ws ? this._ws.extensions : \"\";\n }\n /**\n * A string indicating the name of the sub-protocol the server selected;\n * this will be one of the strings specified in the protocols parameter when creating the\n * WebSocket object\n */\n get protocol() {\n return this._ws ? this._ws.protocol : \"\";\n }\n /**\n * The current state of the connection; this is one of the Ready state constants\n */\n get readyState() {\n if (this._ws) {\n return this._ws.readyState;\n }\n return this._options.startClosed\n ? _ReconnectingWebSocket.CLOSED\n : _ReconnectingWebSocket.CONNECTING;\n }\n /**\n * The URL as resolved by the constructor\n */\n get url() {\n return this._ws ? this._ws.url : \"\";\n }\n /**\n * Whether the websocket object is now in reconnectable state\n */\n get shouldReconnect() {\n return this._shouldReconnect;\n }\n /**\n * An event listener to be called when the WebSocket connection's readyState changes to CLOSED\n */\n onclose = null;\n /**\n * An event listener to be called when an error occurs\n */\n onerror = null;\n /**\n * An event listener to be called when a message is received from the server\n */\n onmessage = null;\n /**\n * An event listener to be called when the WebSocket connection's readyState changes to OPEN;\n * this indicates that the connection is ready to send and receive data\n */\n onopen = null;\n /**\n * Closes the WebSocket connection or connection attempt, if any. If the connection is already\n * CLOSED, this method does nothing\n */\n close(code = 1e3, reason) {\n this._closeCalled = true;\n this._shouldReconnect = false;\n this._clearTimeouts();\n if (!this._ws) {\n this._debug(\"close enqueued: no ws instance\");\n return;\n }\n if (this._ws.readyState === this.CLOSED) {\n this._debug(\"close: already closed\");\n return;\n }\n this._ws.close(code, reason);\n }\n /**\n * Closes the WebSocket connection or connection attempt and connects again.\n * Resets retry counter;\n */\n reconnect(code, reason) {\n this._shouldReconnect = true;\n this._closeCalled = false;\n this._retryCount = -1;\n if (!this._ws || this._ws.readyState === this.CLOSED) {\n this._connect();\n } else {\n this._disconnect(code, reason);\n this._connect();\n }\n }\n /**\n * Enqueue specified data to be transmitted to the server over the WebSocket connection\n */\n send(data) {\n if (this._ws && this._ws.readyState === this.OPEN) {\n this._debug(\"send\", data);\n this._ws.send(data);\n } else {\n const { maxEnqueuedMessages = DEFAULT.maxEnqueuedMessages } =\n this._options;\n if (this._messageQueue.length < maxEnqueuedMessages) {\n this._debug(\"enqueue\", data);\n this._messageQueue.push(data);\n }\n }\n }\n _debug(...args) {\n if (this._options.debug) {\n this._debugLogger(\"RWS>\", ...args);\n }\n }\n _getNextDelay() {\n const {\n reconnectionDelayGrowFactor = DEFAULT.reconnectionDelayGrowFactor,\n minReconnectionDelay = DEFAULT.minReconnectionDelay,\n maxReconnectionDelay = DEFAULT.maxReconnectionDelay\n } = this._options;\n let delay = 0;\n if (this._retryCount > 0) {\n delay =\n minReconnectionDelay *\n reconnectionDelayGrowFactor ** (this._retryCount - 1);\n if (delay > maxReconnectionDelay) {\n delay = maxReconnectionDelay;\n }\n }\n this._debug(\"next delay\", delay);\n return delay;\n }\n _wait() {\n return new Promise((resolve) => {\n setTimeout(resolve, this._getNextDelay());\n });\n }\n _getNextProtocols(protocolsProvider) {\n if (!protocolsProvider) return Promise.resolve(null);\n if (\n typeof protocolsProvider === \"string\" ||\n Array.isArray(protocolsProvider)\n ) {\n return Promise.resolve(protocolsProvider);\n }\n if (typeof protocolsProvider === \"function\") {\n const protocols = protocolsProvider();\n if (!protocols) return Promise.resolve(null);\n if (typeof protocols === \"string\" || Array.isArray(protocols)) {\n return Promise.resolve(protocols);\n }\n if (protocols.then) {\n return protocols;\n }\n }\n throw Error(\"Invalid protocols\");\n }\n _getNextUrl(urlProvider) {\n if (typeof urlProvider === \"string\") {\n return Promise.resolve(urlProvider);\n }\n if (typeof urlProvider === \"function\") {\n const url = urlProvider();\n if (typeof url === \"string\") {\n return Promise.resolve(url);\n }\n if (url.then) {\n return url;\n }\n }\n throw Error(\"Invalid URL\");\n }\n _connect() {\n if (this._connectLock || !this._shouldReconnect) {\n return;\n }\n this._connectLock = true;\n const {\n maxRetries = DEFAULT.maxRetries,\n connectionTimeout = DEFAULT.connectionTimeout\n } = this._options;\n if (this._retryCount >= maxRetries) {\n this._debug(\"max retries reached\", this._retryCount, \">=\", maxRetries);\n return;\n }\n this._retryCount++;\n this._debug(\"connect\", this._retryCount);\n this._removeListeners();\n this._wait()\n .then(() =>\n Promise.all([\n this._getNextUrl(this._url),\n this._getNextProtocols(this._protocols || null)\n ])\n )\n .then(([url, protocols]) => {\n if (this._closeCalled) {\n this._connectLock = false;\n return;\n }\n if (\n !this._options.WebSocket &&\n typeof WebSocket === \"undefined\" &&\n !didWarnAboutMissingWebSocket\n ) {\n console.error(`\\u203C\\uFE0F No WebSocket implementation available. You should define options.WebSocket. \n\nFor example, if you're using node.js, run \\`npm install ws\\`, and then in your code:\n\nimport PartySocket from 'partysocket';\nimport WS from 'ws';\n\nconst partysocket = new PartySocket({\n host: \"127.0.0.1:1999\",\n room: \"test-room\",\n WebSocket: WS\n});\n\n`);\n didWarnAboutMissingWebSocket = true;\n }\n const WS = this._options.WebSocket || WebSocket;\n this._debug(\"connect\", { url, protocols });\n this._ws = protocols ? new WS(url, protocols) : new WS(url);\n this._ws.binaryType = this._binaryType;\n this._connectLock = false;\n this._addListeners();\n this._connectTimeout = setTimeout(\n () => this._handleTimeout(),\n connectionTimeout\n );\n })\n .catch((err) => {\n this._connectLock = false;\n this._handleError(new Events.ErrorEvent(Error(err.message), this));\n });\n }\n _handleTimeout() {\n this._debug(\"timeout event\");\n this._handleError(new Events.ErrorEvent(Error(\"TIMEOUT\"), this));\n }\n _disconnect(code = 1e3, reason) {\n this._clearTimeouts();\n if (!this._ws) {\n return;\n }\n this._removeListeners();\n try {\n if (\n this._ws.readyState === this.OPEN ||\n this._ws.readyState === this.CONNECTING\n ) {\n this._ws.close(code, reason);\n }\n this._handleClose(new Events.CloseEvent(code, reason, this));\n } catch (_error) {}\n }\n _acceptOpen() {\n this._debug(\"accept open\");\n this._retryCount = 0;\n }\n _handleOpen = (event) => {\n this._debug(\"open event\");\n const { minUptime = DEFAULT.minUptime } = this._options;\n clearTimeout(this._connectTimeout);\n this._uptimeTimeout = setTimeout(() => this._acceptOpen(), minUptime);\n assert(this._ws, \"WebSocket is not defined\");\n this._ws.binaryType = this._binaryType;\n this._messageQueue.forEach((message) => {\n var _a2;\n (_a2 = this._ws) == null ? void 0 : _a2.send(message);\n });\n this._messageQueue = [];\n if (this.onopen) {\n this.onopen(event);\n }\n this.dispatchEvent(cloneEvent(event));\n };\n _handleMessage = (event) => {\n this._debug(\"message event\");\n if (this.onmessage) {\n this.onmessage(event);\n }\n this.dispatchEvent(cloneEvent(event));\n };\n _handleError = (event) => {\n this._debug(\"error event\", event.message);\n this._disconnect(void 0, event.message === \"TIMEOUT\" ? \"timeout\" : void 0);\n if (this.onerror) {\n this.onerror(event);\n }\n this._debug(\"exec error listeners\");\n this.dispatchEvent(cloneEvent(event));\n this._connect();\n };\n _handleClose = (event) => {\n this._debug(\"close event\");\n this._clearTimeouts();\n if (this._shouldReconnect) {\n this._connect();\n }\n if (this.onclose) {\n this.onclose(event);\n }\n this.dispatchEvent(cloneEvent(event));\n };\n _removeListeners() {\n if (!this._ws) {\n return;\n }\n this._debug(\"removeListeners\");\n this._ws.removeEventListener(\"open\", this._handleOpen);\n this._ws.removeEventListener(\"close\", this._handleClose);\n this._ws.removeEventListener(\"message\", this._handleMessage);\n this._ws.removeEventListener(\"error\", this._handleError);\n }\n _addListeners() {\n if (!this._ws) {\n return;\n }\n this._debug(\"addListeners\");\n this._ws.addEventListener(\"open\", this._handleOpen);\n this._ws.addEventListener(\"close\", this._handleClose);\n this._ws.addEventListener(\"message\", this._handleMessage);\n this._ws.addEventListener(\"error\", this._handleError);\n }\n _clearTimeouts() {\n clearTimeout(this._connectTimeout);\n clearTimeout(this._uptimeTimeout);\n }\n};\n\nexport { ErrorEvent, CloseEvent, ReconnectingWebSocket };\n/*!\n * Reconnecting WebSocket\n * by Pedro Ladaria <pedro.ladaria@gmail.com>\n * https://github.com/pladaria/reconnecting-websocket\n * License MIT\n */\n//# sourceMappingURL=chunk-V6LO7DXK.mjs.map\n","import { ReconnectingWebSocket } from \"./chunk-V6LO7DXK.mjs\";\n\n// src/index.ts\nvar valueIsNotNil = (keyValuePair) =>\n keyValuePair[1] !== null && keyValuePair[1] !== void 0;\nfunction generateUUID() {\n if (crypto == null ? void 0 : crypto.randomUUID) {\n return crypto.randomUUID();\n }\n let d = Date.now();\n let d2 =\n ((performance == null ? void 0 : performance.now) &&\n performance.now() * 1e3) ||\n 0;\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function (c) {\n let r = Math.random() * 16;\n if (d > 0) {\n r = (d + r) % 16 | 0;\n d = Math.floor(d / 16);\n } else {\n r = (d2 + r) % 16 | 0;\n d2 = Math.floor(d2 / 16);\n }\n return (c === \"x\" ? r : (r & 3) | 8).toString(16);\n });\n}\nfunction getPartyInfo(partySocketOptions, defaultProtocol, defaultParams = {}) {\n const {\n host: rawHost,\n path: rawPath,\n protocol: rawProtocol,\n room,\n party,\n basePath,\n prefix,\n query\n } = partySocketOptions;\n let host = rawHost.replace(/^(http|https|ws|wss):\\/\\//, \"\");\n if (host.endsWith(\"/\")) {\n host = host.slice(0, -1);\n }\n if (rawPath == null ? void 0 : rawPath.startsWith(\"/\")) {\n throw new Error(\"path must not start with a slash\");\n }\n const name = party ?? \"main\";\n const path = rawPath ? `/${rawPath}` : \"\";\n const protocol =\n rawProtocol ||\n (host.startsWith(\"localhost:\") ||\n host.startsWith(\"127.0.0.1:\") ||\n host.startsWith(\"192.168.\") ||\n host.startsWith(\"10.\") ||\n (host.startsWith(\"172.\") &&\n host.split(\".\")[1] >= \"16\" &&\n host.split(\".\")[1] <= \"31\") ||\n host.startsWith(\"[::ffff:7f00:1]:\")\n ? // http / ws\n defaultProtocol\n : // https / wss\n `${defaultProtocol}s`);\n const baseUrl = `${protocol}://${host}/${basePath || `${prefix || \"parties\"}/${name}/${room}`}${path}`;\n const makeUrl = (query2 = {}) =>\n `${baseUrl}?${new URLSearchParams([\n ...Object.entries(defaultParams),\n ...Object.entries(query2).filter(valueIsNotNil)\n ])}`;\n const urlProvider =\n typeof query === \"function\"\n ? async () => makeUrl(await query())\n : makeUrl(query);\n return {\n host,\n path,\n room,\n name,\n protocol,\n partyUrl: baseUrl,\n urlProvider\n };\n}\nvar PartySocket = class extends ReconnectingWebSocket {\n constructor(partySocketOptions) {\n var _a, _b;\n const wsOptions = getWSOptions(partySocketOptions);\n super(wsOptions.urlProvider, wsOptions.protocols, wsOptions.socketOptions);\n this.partySocketOptions = partySocketOptions;\n this.setWSProperties(wsOptions);\n if (!partySocketOptions.disableNameValidation) {\n if ((_a = partySocketOptions.party) == null ? void 0 : _a.includes(\"/\")) {\n console.warn(\n `PartySocket: party name \"${partySocketOptions.party}\" contains forward slash which may cause routing issues. Consider using a name without forward slashes or set disableNameValidation: true to bypass this warning.`\n );\n }\n if ((_b = partySocketOptions.room) == null ? void 0 : _b.includes(\"/\")) {\n console.warn(\n `PartySocket: room name \"${partySocketOptions.room}\" contains forward slash which may cause routing issues. Consider using a name without forward slashes or set disableNameValidation: true to bypass this warning.`\n );\n }\n }\n }\n _pk;\n _pkurl;\n name;\n room;\n host;\n path;\n updateProperties(partySocketOptions) {\n const wsOptions = getWSOptions({\n ...this.partySocketOptions,\n ...partySocketOptions,\n host: partySocketOptions.host ?? this.host,\n room: partySocketOptions.room ?? this.room,\n path: partySocketOptions.path ?? this.path\n });\n this._url = wsOptions.urlProvider;\n this._protocols = wsOptions.protocols;\n this._options = wsOptions.socketOptions;\n this.setWSProperties(wsOptions);\n }\n setWSProperties(wsOptions) {\n const { _pk, _pkurl, name, room, host, path } = wsOptions;\n this._pk = _pk;\n this._pkurl = _pkurl;\n this.name = name;\n this.room = room;\n this.host = host;\n this.path = path;\n }\n reconnect(code, reason) {\n if (!this.room || !this.host) {\n throw new Error(\n \"The room and host must be set before connecting, use `updateProperties` method to set them or pass them to the constructor.\"\n );\n }\n super.reconnect(code, reason);\n }\n get id() {\n return this._pk;\n }\n /**\n * Exposes the static PartyKit room URL without applying query parameters.\n * To access the currently connected WebSocket url, use PartySocket#url.\n */\n get roomUrl() {\n return this._pkurl;\n }\n // a `fetch` method that uses (almost) the same options as `PartySocket`\n static async fetch(options, init) {\n const party = getPartyInfo(options, \"http\");\n const url =\n typeof party.urlProvider === \"string\"\n ? party.urlProvider\n : await party.urlProvider();\n const doFetch = options.fetch ?? fetch;\n return doFetch(url, init);\n }\n};\nfunction getWSOptions(partySocketOptions) {\n const {\n id,\n host: _host,\n path: _path,\n party: _party,\n room: _room,\n protocol: _protocol,\n query: _query,\n protocols,\n ...socketOptions\n } = partySocketOptions;\n const _pk = id || generateUUID();\n const party = getPartyInfo(partySocketOptions, \"ws\", { _pk });\n return {\n _pk,\n _pkurl: party.partyUrl,\n name: party.name,\n room: party.room,\n host: party.host,\n path: party.path,\n protocols,\n socketOptions,\n urlProvider: party.urlProvider\n };\n}\n\nexport { PartySocket };\n//# sourceMappingURL=chunk-7TNWDF55.mjs.map\n","import { ReconnectingWebSocket } from \"./chunk-V6LO7DXK.mjs\";\n\n// src/use-handlers.ts\nimport { useEffect, useRef } from \"react\";\nvar useAttachWebSocketEventHandlers = (socket, options) => {\n const handlersRef = useRef(options);\n handlersRef.current = options;\n useEffect(() => {\n const onOpen = (event) => {\n var _a, _b;\n return (_b = (_a = handlersRef.current) == null ? void 0 : _a.onOpen) ==\n null\n ? void 0\n : _b.call(_a, event);\n };\n const onMessage = (event) => {\n var _a, _b;\n return (_b =\n (_a = handlersRef.current) == null ? void 0 : _a.onMessage) == null\n ? void 0\n : _b.call(_a, event);\n };\n const onClose = (event) => {\n var _a, _b;\n return (_b = (_a = handlersRef.current) == null ? void 0 : _a.onClose) ==\n null\n ? void 0\n : _b.call(_a, event);\n };\n const onError = (event) => {\n var _a, _b;\n return (_b = (_a = handlersRef.current) == null ? void 0 : _a.onError) ==\n null\n ? void 0\n : _b.call(_a, event);\n };\n socket.addEventListener(\"open\", onOpen);\n socket.addEventListener(\"close\", onClose);\n socket.addEventListener(\"error\", onError);\n socket.addEventListener(\"message\", onMessage);\n return () => {\n socket.removeEventListener(\"open\", onOpen);\n socket.removeEventListener(\"close\", onClose);\n socket.removeEventListener(\"error\", onError);\n socket.removeEventListener(\"message\", onMessage);\n };\n }, [socket]);\n};\n\n// src/use-socket.ts\nimport {\n useEffect as useEffect2,\n useMemo,\n useRef as useRef2,\n useState\n} from \"react\";\nvar getOptionsThatShouldCauseRestartWhenChanged = (options) => [\n options.startClosed,\n options.minUptime,\n options.maxRetries,\n options.connectionTimeout,\n options.maxEnqueuedMessages,\n options.maxReconnectionDelay,\n options.minReconnectionDelay,\n options.reconnectionDelayGrowFactor,\n options.debug\n];\nfunction useStableSocket({\n options,\n createSocket,\n createSocketMemoKey: createOptionsMemoKey\n}) {\n const shouldReconnect = createOptionsMemoKey(options);\n const socketOptions = useMemo(() => {\n return options;\n }, [shouldReconnect]);\n const [socket, setSocket] = useState(() =>\n // only connect on first mount\n createSocket({ ...socketOptions, startClosed: true })\n );\n const socketInitializedRef = useRef2(null);\n const createSocketRef = useRef2(createSocket);\n createSocketRef.current = createSocket;\n useEffect2(() => {\n if (socketInitializedRef.current === socket) {\n const newSocket = createSocketRef.current({\n ...socketOptions,\n // when reconnecting because of options change, we always reconnect\n // (startClosed only applies to initial mount)\n startClosed: false\n });\n setSocket(newSocket);\n } else {\n if (!socketInitializedRef.current && socketOptions.startClosed !== true) {\n socket.reconnect();\n }\n socketInitializedRef.current = socket;\n return () => {\n socket.close();\n };\n }\n }, [socket, socketOptions]);\n return socket;\n}\n\n// src/use-ws.ts\nfunction useWebSocket(url, protocols, options = {}) {\n const socket = useStableSocket({\n options,\n createSocket: (options2) =>\n new ReconnectingWebSocket(url, protocols, options2),\n createSocketMemoKey: (options2) =>\n JSON.stringify([\n // will reconnect if url or protocols are specified as a string.\n // if they are functions, the WebSocket will handle reconnection\n url,\n protocols,\n ...getOptionsThatShouldCauseRestartWhenChanged(options2)\n ])\n });\n useAttachWebSocketEventHandlers(socket, options);\n return socket;\n}\n\nexport {\n useAttachWebSocketEventHandlers,\n getOptionsThatShouldCauseRestartWhenChanged,\n useStableSocket,\n useWebSocket\n};\n//# sourceMappingURL=chunk-PTE3YP23.mjs.map\n","import { PartySocket } from \"./chunk-7TNWDF55.mjs\";\nimport {\n getOptionsThatShouldCauseRestartWhenChanged,\n useAttachWebSocketEventHandlers,\n useStableSocket,\n useWebSocket\n} from \"./chunk-PTE3YP23.mjs\";\nimport \"./chunk-V6LO7DXK.mjs\";\n\n// src/react.ts\nfunction usePartySocket(options) {\n const { host, ...otherOptions } = options;\n const socket = useStableSocket({\n options: {\n host:\n host ||\n (typeof window !== \"undefined\"\n ? window.location.host\n : \"dummy-domain.com\"),\n ...otherOptions\n },\n createSocket: (options2) => new PartySocket(options2),\n createSocketMemoKey: (options2) =>\n JSON.stringify([\n // NOTE: if query is defined as a function, the socket\n // won't reconnect when you change the function identity\n options2.query,\n options2.id,\n options2.host,\n options2.room,\n options2.party,\n options2.path,\n options2.protocol,\n options2.protocols,\n options2.basePath,\n options2.prefix,\n ...getOptionsThatShouldCauseRestartWhenChanged(options2)\n ])\n });\n useAttachWebSocketEventHandlers(socket, options);\n return socket;\n}\nexport { usePartySocket as default, usePartySocket, useWebSocket };\n//# sourceMappingURL=react.mjs.map\n","import {\n\tMessageSchema,\n\tpartykitBaseUrl,\n\tpartykitRoom,\n\ttype Message,\n\ttype User,\n} from '@epic-web/workshop-presence/presence'\nimport { usePartySocket } from 'partysocket/react'\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport { useParams } from 'react-router'\nimport { z } from 'zod'\nimport { useIsOnline } from './online.ts'\nimport { useRequestInfo, useRootLoaderData } from './root-loader.ts'\n\nexport * from '@epic-web/workshop-presence/presence'\n\nconst PresenceContext = createContext<ReturnType<\n\ttypeof usePresenceSocket\n> | null>(null)\n\nexport function usePresencePreferences() {\n\tconst data = useRootLoaderData()\n\treturn data?.preferences?.presence ?? null\n}\n\nexport function useOptionalWorkshopTitle() {\n\tconst data = useRootLoaderData()\n\treturn data?.workshopTitle ?? null\n}\n\nconst ExerciseAppParamsSchema = z.object({\n\ttype: z.union([z.literal('problem'), z.literal('solution')]).optional(),\n\texerciseNumber: z.coerce.number().finite(),\n\tstepNumber: z.coerce.number().finite().optional(),\n})\n\n/**\n * useFirstCallDelayedCallback\n *\n * This hook creates a callback that is delayed on its first call.\n * It's useful for scenarios where you want to delay the execution of a function\n * for a certain amount of time, but only on the initial call.\n *\n * If it's called again before the delay expires, then the prior call is ignored\n * and when the delay expires, the latest call is executed.\n *\n * The motivation here is that the server may get one set of presence and by the\n * time it shows up on the client it's stale. This delays the re-rendering of\n * the UI to avoid a flicker as soon as you land on the page.\n *\n * @param cb The callback function to be delayed\n * @param delay The delay in milliseconds before the callback is executed\n * @returns A new function that wraps the original callback with the delay logic\n */\nfunction useFirstCallDelayedCallback<Args extends unknown[]>(\n\tcb: (...args: Args) => void,\n\tdelay: number,\n) {\n\tconst [timedPromise] = useState(\n\t\t() => new Promise((resolve) => setTimeout(resolve, delay)),\n\t)\n\tconst mounted = useRef(true)\n\tconst currentCallRef = useRef<symbol | null>(null)\n\tconst lastCbRef = useRef(cb)\n\n\tuseEffect(() => {\n\t\tlastCbRef.current = cb\n\t}, [cb])\n\n\tconst delayedCb = useCallback(\n\t\t(...args: Args) => {\n\t\t\tconst thisOne = Symbol()\n\t\t\tcurrentCallRef.current = thisOne\n\t\t\tvoid timedPromise.then(() => {\n\t\t\t\tif (!mounted.current) return\n\t\t\t\tif (currentCallRef.current !== thisOne) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tlastCbRef.current(...args)\n\t\t\t})\n\t\t},\n\t\t[timedPromise],\n\t)\n\n\treturn delayedCb\n}\n\nfunction useProductHost() {\n\tconst data = useRootLoaderData()\n\treturn data?.workshopConfig?.product?.host ?? null\n}\n\nfunction useLoggedInProductHosts() {\n\tconst data = useRootLoaderData()\n\treturn data?.loggedInProductHosts ?? []\n}\n\nfunction useUsersLocation() {\n\tconst workshopTitle = useOptionalWorkshopTitle()\n\tconst requestInfo = useRequestInfo()\n\tconst productHost = useProductHost()\n\tconst rawParams = useParams()\n\tconst paramsResult = ExerciseAppParamsSchema.safeParse(rawParams)\n\tconst params = paramsResult.success ? paramsResult.data : null\n\n\treturn {\n\t\tworkshopTitle,\n\t\torigin: requestInfo.origin,\n\t\tproductHost,\n\t\t...(params\n\t\t\t? {\n\t\t\t\t\texercise: {\n\t\t\t\t\t\ttype: params.type,\n\t\t\t\t\t\texerciseNumber: params.exerciseNumber,\n\t\t\t\t\t\tstepNumber: params.stepNumber,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: null),\n\t} satisfies User['location']\n}\n\nfunction usePresenceSocket(user?: User | null) {\n\tconst prefs = usePresencePreferences()\n\tconst { userHasAccess = false, userId, presence } = useRootLoaderData() ?? {}\n\tconst [users, setUsers] = useState(presence?.users ?? [])\n\tconst usersLocation = useUsersLocation()\n\tconst loggedInProductHosts = useLoggedInProductHosts()\n\n\tconst handleMessage = useFirstCallDelayedCallback((evt: MessageEvent) => {\n\t\tconst messageResult = MessageSchema.safeParse(JSON.parse(String(evt.data)))\n\t\tif (!messageResult.success) return\n\t\tif (messageResult.data.type === 'presence') {\n\t\t\tsetUsers(messageResult.data.payload.users)\n\t\t}\n\t}, 2000)\n\n\tconst socket = usePartySocket({\n\t\thost: new URL(partykitBaseUrl).host,\n\t\troom: partykitRoom,\n\t\tonMessage: handleMessage,\n\t})\n\n\tlet message: Message | null = null\n\tif (user) {\n\t\tif (prefs?.optOut) {\n\t\t\t// Send opt-out user with minimal info instead of removing entirely\n\t\t\tmessage = {\n\t\t\t\ttype: 'add-user',\n\t\t\t\tpayload: {\n\t\t\t\t\tid: user.id,\n\t\t\t\t\toptOut: true,\n\t\t\t\t\tloggedInProductHosts,\n\t\t\t\t},\n\t\t\t}\n\t\t} else {\n\t\t\tmessage = {\n\t\t\t\ttype: 'add-user',\n\t\t\t\tpayload: {\n\t\t\t\t\tid: user.id,\n\t\t\t\t\tname: user.name,\n\t\t\t\t\thasAccess: userHasAccess,\n\t\t\t\t\timageUrlSmall: user.imageUrlSmall,\n\t\t\t\t\timageUrlLarge: user.imageUrlLarge,\n\t\t\t\t\tlocation: usersLocation,\n\t\t\t\t\tloggedInProductHosts,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t} else if (userId?.id) {\n\t\tmessage = {\n\t\t\ttype: 'add-user',\n\t\t\tpayload: { id: userId.id, location: usersLocation, loggedInProductHosts },\n\t\t}\n\t}\n\n\tconst messageJson = message ? JSON.stringify(message) : null\n\tuseEffect(() => {\n\t\tif (messageJson) socket.send(messageJson)\n\t}, [messageJson, socket])\n\n\tconst scoredUsers = scoreUsers(\n\t\t{ id: userId?.id, location: usersLocation },\n\t\tusers,\n\t)\n\n\treturn { users: scoredUsers }\n}\n\n/**\n * Get all locations for a user (from locations array or falling back to location)\n */\nfunction getUserLocations(user: User): Array<NonNullable<User['location']>> {\n\tif (user.locations && user.locations.length > 0) {\n\t\treturn user.locations.filter(Boolean) as Array<\n\t\t\tNonNullable<User['location']>\n\t\t>\n\t}\n\tif (user.location) {\n\t\treturn [user.location]\n\t}\n\treturn []\n}\n\n/**\n * Sorts and scores users based on proximity to the current user.\n *\n * Sorting order:\n * 1. Self first\n * 2. Same exercise step (exerciseNumber + stepNumber + type)\n * 3. Same exercise (exerciseNumber)\n * 4. Same workshop (workshopTitle)\n * 5. Same product host\n * 6. Most products logged into\n * 7. Opted-out users last\n */\nfunction scoreUsers(\n\tcurrentUser: { id?: string | null; location: User['location'] },\n\tusers: Array<User>,\n) {\n\tconst { location } = currentUser\n\n\tconst scoredUsers = users.map((user) => {\n\t\t// Calculate score for visual styling (0-1)\n\t\t// Higher score = closer proximity = more prominent display\n\t\tlet score = 0\n\n\t\t// Opted-out users get no score for visual purposes\n\t\tif (user.optOut) {\n\t\t\treturn { user, score: 0 }\n\t\t}\n\n\t\tconst userLocations = getUserLocations(user)\n\n\t\t// Check if any of the user's locations match the current user's location\n\t\tfor (const userLoc of userLocations) {\n\t\t\t// Same workshop title\n\t\t\tif (\n\t\t\t\tlocation?.workshopTitle &&\n\t\t\t\tlocation.workshopTitle === userLoc.workshopTitle\n\t\t\t) {\n\t\t\t\tscore = Math.max(score, 0.4)\n\n\t\t\t\t// Same exercise\n\t\t\t\tif (\n\t\t\t\t\tlocation.exercise?.exerciseNumber != null &&\n\t\t\t\t\tlocation.exercise.exerciseNumber === userLoc.exercise?.exerciseNumber\n\t\t\t\t) {\n\t\t\t\t\tscore = Math.max(score, 0.6)\n\n\t\t\t\t\t// Same step\n\t\t\t\t\tif (\n\t\t\t\t\t\tlocation.exercise.stepNumber != null &&\n\t\t\t\t\t\tlocation.exercise.stepNumber === userLoc.exercise?.stepNumber\n\t\t\t\t\t) {\n\t\t\t\t\t\tscore = Math.max(score, 0.8)\n\n\t\t\t\t\t\t// Same type (problem/solution)\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tlocation.exercise.type &&\n\t\t\t\t\t\t\tlocation.exercise.type === userLoc.exercise?.type\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tscore = 1\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tlocation?.productHost &&\n\t\t\t\tlocation.productHost === userLoc.productHost\n\t\t\t) {\n\t\t\t\t// Same product host but different workshop\n\t\t\t\tscore = Math.max(score, 0.2)\n\t\t\t}\n\t\t}\n\n\t\treturn { user, score }\n\t})\n\n\treturn scoredUsers.sort((a, b) => {\n\t\t// Self always first\n\t\tif (a.user.id === currentUser.id) return -1\n\t\tif (b.user.id === currentUser.id) return 1\n\n\t\t// Opted-out users always last\n\t\tif (a.user.optOut && !b.user.optOut) return 1\n\t\tif (!a.user.optOut && b.user.optOut) return -1\n\n\t\t// Same step (exerciseNumber + stepNumber + type match)\n\t\tconst aOnSameStep = userHasSameStep(location, a.user)\n\t\tconst bOnSameStep = userHasSameStep(location, b.user)\n\t\tif (aOnSameStep && !bOnSameStep) return -1\n\t\tif (!aOnSameStep && bOnSameStep) return 1\n\n\t\t// Same exercise (exerciseNumber match)\n\t\tconst aOnSameExercise = userHasSameExercise(location, a.user)\n\t\tconst bOnSameExercise = userHasSameExercise(location, b.user)\n\t\tif (aOnSameExercise && !bOnSameExercise) return -1\n\t\tif (!aOnSameExercise && bOnSameExercise) return 1\n\n\t\t// Same workshop\n\t\tconst aOnSameWorkshop = userHasSameWorkshop(location, a.user)\n\t\tconst bOnSameWorkshop = userHasSameWorkshop(location, b.user)\n\t\tif (aOnSameWorkshop && !bOnSameWorkshop) return -1\n\t\tif (!aOnSameWorkshop && bOnSameWorkshop) return 1\n\n\t\t// Same product host\n\t\tconst aOnSameProductHost = userHasSameProductHost(location, a.user)\n\t\tconst bOnSameProductHost = userHasSameProductHost(location, b.user)\n\t\tif (aOnSameProductHost && !bOnSameProductHost) return -1\n\t\tif (!aOnSameProductHost && bOnSameProductHost) return 1\n\n\t\t// Most products logged into\n\t\tconst aProductCount = a.user.loggedInProductHosts?.length ?? 0\n\t\tconst bProductCount = b.user.loggedInProductHosts?.length ?? 0\n\t\tif (aProductCount !== bProductCount) {\n\t\t\treturn bProductCount - aProductCount\n\t\t}\n\n\t\treturn 0\n\t})\n}\n\nfunction userHasSameStep(\n\tcurrentLocation: User['location'],\n\tuser: User,\n): boolean {\n\tif (!currentLocation?.exercise) return false\n\tconst userLocations = getUserLocations(user)\n\treturn userLocations.some(\n\t\t(loc) =>\n\t\t\tloc.workshopTitle === currentLocation.workshopTitle &&\n\t\t\tloc.exercise?.exerciseNumber ===\n\t\t\t\tcurrentLocation.exercise?.exerciseNumber &&\n\t\t\tloc.exercise?.stepNumber === currentLocation.exercise?.stepNumber &&\n\t\t\tloc.exercise?.type === currentLocation.exercise?.type,\n\t)\n}\n\nfunction userHasSameExercise(\n\tcurrentLocation: User['location'],\n\tuser: User,\n): boolean {\n\tif (!currentLocation?.exercise?.exerciseNumber) return false\n\tconst userLocations = getUserLocations(user)\n\treturn userLocations.some(\n\t\t(loc) =>\n\t\t\tloc.workshopTitle === currentLocation.workshopTitle &&\n\t\t\tloc.exercise?.exerciseNumber === currentLocation.exercise?.exerciseNumber,\n\t)\n}\n\nfunction userHasSameWorkshop(\n\tcurrentLocation: User['location'],\n\tuser: User,\n): boolean {\n\tif (!currentLocation?.workshopTitle) return false\n\tconst userLocations = getUserLocations(user)\n\treturn userLocations.some(\n\t\t(loc) => loc.workshopTitle === currentLocation.workshopTitle,\n\t)\n}\n\nfunction userHasSameProductHost(\n\tcurrentLocation: User['location'],\n\tuser: User,\n): boolean {\n\tif (!currentLocation?.productHost) return false\n\tconst userLocations = getUserLocations(user)\n\treturn userLocations.some(\n\t\t(loc) => loc.productHost === currentLocation.productHost,\n\t)\n}\n\nfunction PresenceOnline({\n\tuser,\n\tchildren,\n}: {\n\tuser?: User | null\n\tchildren: React.ReactNode\n}) {\n\treturn (\n\t\t<PresenceContext.Provider value={usePresenceSocket(user)}>\n\t\t\t{children}\n\t\t</PresenceContext.Provider>\n\t)\n}\n\nfunction PresenceOffline({\n\tuser,\n\tchildren,\n}: {\n\tuser?: User | null\n\tchildren: React.ReactNode\n}) {\n\tconst usersLocation = useUsersLocation()\n\tconst { presence } = useRootLoaderData() ?? {}\n\treturn (\n\t\t<PresenceContext.Provider\n\t\t\tvalue={{\n\t\t\t\tusers: scoreUsers(\n\t\t\t\t\t{ id: user?.id, location: usersLocation },\n\t\t\t\t\tpresence?.users ?? [],\n\t\t\t\t),\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</PresenceContext.Provider>\n\t)\n}\n\nexport function Presence({\n\tuser,\n\tchildren,\n}: {\n\tuser?: User | null\n\tchildren: React.ReactNode\n}) {\n\tconst isOnline = useIsOnline()\n\tif (isOnline) {\n\t\treturn <PresenceOnline user={user}>{children}</PresenceOnline>\n\t} else {\n\t\treturn <PresenceOffline user={user}>{children}</PresenceOffline>\n\t}\n}\n\nexport function usePresence() {\n\tconst presence = useContext(PresenceContext)\n\tif (!presence) {\n\t\tthrow new Error('usePresence must be used within a PresenceProvider')\n\t}\n\treturn presence\n}\n"],"names":["DIALOG_NAME","createDialogContext","createContextScope","DialogProvider","useDialogContext","Dialog","props","__scopeDialog","children","openProp","defaultOpen","onOpenChange","modal","triggerRef","React.useRef","contentRef","open","setOpen","useControllableState","jsx","useId","React.useCallback","prevOpen","TRIGGER_NAME","DialogTrigger","React.forwardRef","forwardedRef","triggerProps","context","composedTriggerRef","useComposedRefs","Primitive","getState","composeEventHandlers","PORTAL_NAME","PortalProvider","usePortalContext","DialogPortal","forceMount","container","React.Children","child","Presence","PortalPrimitive","OVERLAY_NAME","DialogOverlay","portalContext","overlayProps","DialogOverlayImpl","Slot","createSlot","RemoveScroll","CONTENT_NAME","DialogContent","contentProps","DialogContentModal","DialogContentNonModal","composedRefs","React.useEffect","content","hideOthers","DialogContentImpl","event","originalEvent","ctrlLeftClick","hasInteractedOutsideRef","hasPointerDownOutsideRef","target","trapFocus","onOpenAutoFocus","onCloseAutoFocus","useFocusGuards","jsxs","Fragment","FocusScope","DismissableLayer","TitleWarning","DescriptionWarning","TITLE_NAME","DialogTitle","titleProps","DESCRIPTION_NAME","DialogDescription","descriptionProps","CLOSE_NAME","DialogClose","closeProps","TITLE_WARNING_NAME","WarningProvider","useWarningContext","createContext","titleId","titleWarningContext","MESSAGE","DESCRIPTION_WARNING_NAME","descriptionId","describedById","Root","Trigger","Portal","Overlay","Content","Title","Description","Close","DialogPrimitive.Root","DialogPrimitive.Trigger","DialogPrimitive.Portal","className","ref","DialogPrimitive.Overlay","cn","DialogPrimitive.Content","DialogPrimitive.Close","Icon","DialogHeader","DialogPrimitive.Title","DialogPrimitive.Description","partykitRoom","partykitBaseUrl","LocationSchema","z.object","z.string","z.union","z.literal","z.number","UserSchema","z.boolean","z.array","MessageSchema","productHostEmojis","getProductHostEmoji","host","ErrorEvent","error","CloseEvent","code","reason","Events","assert","condition","msg","cloneEventBrowser","cloneEventNode","_a","isNode","cloneEvent","DEFAULT","didWarnAboutMissingWebSocket","ReconnectingWebSocket","_ReconnectingWebSocket","url","protocols","options","value","acc","message","data","maxEnqueuedMessages","args","reconnectionDelayGrowFactor","minReconnectionDelay","maxReconnectionDelay","delay","resolve","protocolsProvider","urlProvider","maxRetries","connectionTimeout","WS","err","minUptime","_a2","valueIsNotNil","keyValuePair","generateUUID","d","d2","c","r","getPartyInfo","partySocketOptions","defaultProtocol","defaultParams","rawHost","rawPath","rawProtocol","room","party","basePath","prefix","query","name","path","protocol","baseUrl","makeUrl","query2","PartySocket","_b","wsOptions","getWSOptions","_pk","_pkurl","init","id","_host","_path","_party","_room","_protocol","_query","socketOptions","useAttachWebSocketEventHandlers","socket","handlersRef","useRef","useEffect","onOpen","onMessage","onClose","onError","getOptionsThatShouldCauseRestartWhenChanged","useStableSocket","createSocket","createOptionsMemoKey","shouldReconnect","useMemo","setSocket","useState","socketInitializedRef","useRef2","createSocketRef","useEffect2","newSocket","usePartySocket","otherOptions","options2","PresenceContext","usePresencePreferences","useRootLoaderData","useOptionalWorkshopTitle","ExerciseAppParamsSchema","z.coerce","useFirstCallDelayedCallback","cb","timedPromise","mounted","currentCallRef","lastCbRef","useCallback","thisOne","useProductHost","useLoggedInProductHosts","useUsersLocation","workshopTitle","requestInfo","useRequestInfo","productHost","rawParams","useParams","paramsResult","params","usePresenceSocket","user","prefs","userHasAccess","userId","presence","users","setUsers","usersLocation","loggedInProductHosts","handleMessage","evt","messageResult","messageJson","scoreUsers","getUserLocations","currentUser","location","score","userLocations","userLoc","a","b","aOnSameStep","userHasSameStep","bOnSameStep","aOnSameExercise","userHasSameExercise","bOnSameExercise","aOnSameWorkshop","userHasSameWorkshop","bOnSameWorkshop","aOnSameProductHost","userHasSameProductHost","bOnSameProductHost","aProductCount","bProductCount","currentLocation","loc","PresenceOnline","PresenceOffline","useIsOnline","usePresence","useContext"],"mappings":"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","x_google_ignoreList":[0,3,4,5,6]}
@@ -1,2 +1,2 @@
1
- import{L as V,c as A,w as Y,a as $,b as L,f as z,O as H,M as K,J as X,S as J,K as Z}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{j as a}from"./jsx-runtime-C5WNSv3b.js";import{g as ee,R as O,r as f}from"./index-Az39ZADK.js";import{I as G,j as te,k as ne,c as re}from"./misc-BapXpylh.js";import{C as ie}from"./client-only-DtkKCk_i.js";import{G as se}from"./error-boundary-C8da5z08.js";import{D as oe,b as ae,c as ce,e as ue,d as le,P as fe}from"./presence-OxG7Cpak.js";import{E as he}from"./progress-bar-D66irkpP.js";import{T as de,t as p}from"./index-Dd9cSrtE.js";import{T as pe}from"./tooltip-C2AQeNhD.js";import{o as ve,s as me,a9 as ge}from"./types-Cl2NuNg4.js";import{u as xe,C as ye}from"./index-_LzGTKVC.js";import{g as we}from"./seo-t5J-DRxw.js";import"./pe-Bs-DFNma.js";import"./preload-helper-BXl3LOEh.js";import"./index-Cod-PQ6D.js";import"./index-CjiomtK6.js";import"./online-Dw7HU4wM.js";import"./root-loader-C5P2c7MU.js";var C,B;function ke(){if(B)return C;B=1;var s={linear:function(e,n,t,i){var r=t-n;return r*e/i+n},easeInQuad:function(e,n,t,i){var r=t-n;return r*(e/=i)*e+n},easeOutQuad:function(e,n,t,i){var r=t-n;return-r*(e/=i)*(e-2)+n},easeInOutQuad:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e+n:-r/2*(--e*(e-2)-1)+n},easeInCubic:function(e,n,t,i){var r=t-n;return r*(e/=i)*e*e+n},easeOutCubic:function(e,n,t,i){var r=t-n;return r*((e=e/i-1)*e*e+1)+n},easeInOutCubic:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e*e+n:r/2*((e-=2)*e*e+2)+n},easeInQuart:function(e,n,t,i){var r=t-n;return r*(e/=i)*e*e*e+n},easeOutQuart:function(e,n,t,i){var r=t-n;return-r*((e=e/i-1)*e*e*e-1)+n},easeInOutQuart:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e*e*e+n:-r/2*((e-=2)*e*e*e-2)+n},easeInQuint:function(e,n,t,i){var r=t-n;return r*(e/=i)*e*e*e*e+n},easeOutQuint:function(e,n,t,i){var r=t-n;return r*((e=e/i-1)*e*e*e*e+1)+n},easeInOutQuint:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e*e*e*e+n:r/2*((e-=2)*e*e*e*e+2)+n},easeInSine:function(e,n,t,i){var r=t-n;return-r*Math.cos(e/i*(Math.PI/2))+r+n},easeOutSine:function(e,n,t,i){var r=t-n;return r*Math.sin(e/i*(Math.PI/2))+n},easeInOutSine:function(e,n,t,i){var r=t-n;return-r/2*(Math.cos(Math.PI*e/i)-1)+n},easeInExpo:function(e,n,t,i){var r=t-n;return e==0?n:r*Math.pow(2,10*(e/i-1))+n},easeOutExpo:function(e,n,t,i){var r=t-n;return e==i?n+r:r*(-Math.pow(2,-10*e/i)+1)+n},easeInOutExpo:function(e,n,t,i){var r=t-n;return e===0?n:e===i?n+r:(e/=i/2)<1?r/2*Math.pow(2,10*(e-1))+n:r/2*(-Math.pow(2,-10*--e)+2)+n},easeInCirc:function(e,n,t,i){var r=t-n;return-r*(Math.sqrt(1-(e/=i)*e)-1)+n},easeOutCirc:function(e,n,t,i){var r=t-n;return r*Math.sqrt(1-(e=e/i-1)*e)+n},easeInOutCirc:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?-r/2*(Math.sqrt(1-e*e)-1)+n:r/2*(Math.sqrt(1-(e-=2)*e)+1)+n},easeInElastic:function(e,n,t,i){var r=t-n,o,c,u;return u=1.70158,c=0,o=r,e===0?n:(e/=i)===1?n+r:(c||(c=i*.3),o<Math.abs(r)?(o=r,u=c/4):u=c/(2*Math.PI)*Math.asin(r/o),-(o*Math.pow(2,10*(e-=1))*Math.sin((e*i-u)*(2*Math.PI)/c))+n)},easeOutElastic:function(e,n,t,i){var r=t-n,o,c,u;return u=1.70158,c=0,o=r,e===0?n:(e/=i)===1?n+r:(c||(c=i*.3),o<Math.abs(r)?(o=r,u=c/4):u=c/(2*Math.PI)*Math.asin(r/o),o*Math.pow(2,-10*e)*Math.sin((e*i-u)*(2*Math.PI)/c)+r+n)},easeInOutElastic:function(e,n,t,i){var r=t-n,o,c,u;return u=1.70158,c=0,o=r,e===0?n:(e/=i/2)===2?n+r:(c||(c=i*(.3*1.5)),o<Math.abs(r)?(o=r,u=c/4):u=c/(2*Math.PI)*Math.asin(r/o),e<1?-.5*(o*Math.pow(2,10*(e-=1))*Math.sin((e*i-u)*(2*Math.PI)/c))+n:o*Math.pow(2,-10*(e-=1))*Math.sin((e*i-u)*(2*Math.PI)/c)*.5+r+n)},easeInBack:function(e,n,t,i,r){var o=t-n;return r===void 0&&(r=1.70158),o*(e/=i)*e*((r+1)*e-r)+n},easeOutBack:function(e,n,t,i,r){var o=t-n;return r===void 0&&(r=1.70158),o*((e=e/i-1)*e*((r+1)*e+r)+1)+n},easeInOutBack:function(e,n,t,i,r){var o=t-n;return r===void 0&&(r=1.70158),(e/=i/2)<1?o/2*(e*e*(((r*=1.525)+1)*e-r))+n:o/2*((e-=2)*e*(((r*=1.525)+1)*e+r)+2)+n},easeInBounce:function(e,n,t,i){var r=t-n,o;return o=s.easeOutBounce(i-e,0,r,i),r-o+n},easeOutBounce:function(e,n,t,i){var r=t-n;return(e/=i)<1/2.75?r*(7.5625*e*e)+n:e<2/2.75?r*(7.5625*(e-=1.5/2.75)*e+.75)+n:e<2.5/2.75?r*(7.5625*(e-=2.25/2.75)*e+.9375)+n:r*(7.5625*(e-=2.625/2.75)*e+.984375)+n},easeInOutBounce:function(e,n,t,i){var r=t-n,o;return e<i/2?(o=s.easeInBounce(e*2,0,r,i),o*.5+n):(o=s.easeOutBounce(e*2-i,0,r,i),o*.5+r*.5+n)}};return C=s,C}var je=ke();const Pe=ee(je);function Oe(s,e){for(var n=0;n<e.length;n++){var t=e[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(s,t.key,t)}}function Ie(s,e,n){return e&&Oe(s.prototype,e),s}function I(){return I=Object.assign||function(s){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(s[t]=n[t])}return s},I.apply(this,arguments)}function be(s,e){s.prototype=Object.create(e.prototype),s.prototype.constructor=s,N(s,e)}function N(s,e){return N=Object.setPrototypeOf||function(t,i){return t.__proto__=i,t},N(s,e)}function Ce(s){return s*Math.PI/180}function h(s,e){return s+Math.random()*(e-s)}function Se(s,e){return Math.floor(s+Math.random()*(e-s+1))}var P;(function(s){s[s.Circle=0]="Circle",s[s.Square=1]="Square",s[s.Strip=2]="Strip"})(P||(P={}));var m;(function(s){s[s.Positive=1]="Positive",s[s.Negative=-1]="Negative"})(m||(m={}));var Ne=(function(){function s(n,t,i,r){this.getOptions=t;var o=this.getOptions(),c=o.colors,u=o.initialVelocityX,l=o.initialVelocityY;this.context=n,this.x=i,this.y=r,this.w=h(5,20),this.h=h(5,20),this.radius=h(5,10),this.vx=h(-u,u),this.vy=h(-l,0),this.shape=Se(0,2),this.angle=Ce(h(0,360)),this.angularSpin=h(-.2,.2),this.color=c[Math.floor(Math.random()*c.length)],this.rotateY=h(0,1),this.rotationDirection=h(0,1)?m.Positive:m.Negative}var e=s.prototype;return e.update=function(){var t=this.getOptions(),i=t.gravity,r=t.wind,o=t.friction,c=t.opacity,u=t.drawShape;this.x+=this.vx,this.y+=this.vy,this.vy+=i,this.vx+=r,this.vx*=o,this.vy*=o,this.rotateY>=1&&this.rotationDirection===m.Positive?this.rotationDirection=m.Negative:this.rotateY<=-1&&this.rotationDirection===m.Negative&&(this.rotationDirection=m.Positive);var l=.1*this.rotationDirection;if(this.rotateY+=l,this.angle+=this.angularSpin,this.context.save(),this.context.translate(this.x,this.y),this.context.rotate(this.angle),this.context.scale(1,this.rotateY),this.context.rotate(this.angle),this.context.beginPath(),this.context.fillStyle=this.color,this.context.strokeStyle=this.color,this.context.globalAlpha=c,this.context.lineCap="round",this.context.lineWidth=2,u&&typeof u=="function")u.call(this,this.context);else switch(this.shape){case P.Circle:{this.context.beginPath(),this.context.arc(0,0,this.radius,0,2*Math.PI),this.context.fill();break}case P.Square:{this.context.fillRect(-this.w/2,-this.h/2,this.w,this.h);break}case P.Strip:{this.context.fillRect(-this.w/6,-this.h/2,this.w/3,this.h);break}default:throw new Error("Unknown type in Particle.ts")}this.context.closePath(),this.context.restore()},s})(),Me=function(e,n){var t=this;this.x=0,this.y=0,this.w=0,this.h=0,this.lastNumberOfPieces=0,this.tweenInitTime=Date.now(),this.particles=[],this.particlesGenerated=0,this.removeParticleAt=function(r){t.particles.splice(r,1)},this.getParticle=function(){var r=h(t.x,t.w+t.x),o=h(t.y,t.h+t.y);return new Ne(t.context,t.getOptions,r,o)},this.animate=function(){var r=t.canvas,o=t.context,c=t.particlesGenerated,u=t.lastNumberOfPieces,l=t.getOptions(),v=l.run,w=l.recycle,d=l.numberOfPieces,b=l.debug,D=l.tweenFunction,x=l.tweenDuration;if(!v)return!1;var k=t.particles.length,g=w?k:c,y=Date.now();if(g<d){u!==d&&(t.tweenInitTime=y,t.lastNumberOfPieces=d);for(var _=t.tweenInitTime,Q=y-_>x?x:Math.max(0,y-_),U=D(Q,g,d,x),R=Math.round(U-g),T=0;T<R;T+=1)t.particles.push(t.getParticle());t.particlesGenerated+=R}return b&&(o.font="12px sans-serif",o.fillStyle="#333",o.textAlign="right",o.fillText("Particles: "+k,r.width-10,r.height-20)),t.particles.forEach(function(j,F){j.update(),(j.y>r.height||j.y<-100||j.x>r.width+100||j.x<-100)&&(w&&g<=d?t.particles[F]=t.getParticle():t.removeParticleAt(F))}),k>0||g<d},this.canvas=e;var i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get canvas context");this.context=i,this.getOptions=n},M={width:typeof window<"u"?window.innerWidth:300,height:typeof window<"u"?window.innerHeight:200,numberOfPieces:200,friction:.99,wind:0,gravity:.1,initialVelocityX:4,initialVelocityY:10,colors:["#f44336","#e91e63","#9c27b0","#673ab7","#3f51b5","#2196f3","#03a9f4","#00bcd4","#009688","#4CAF50","#8BC34A","#CDDC39","#FFEB3B","#FFC107","#FF9800","#FF5722","#795548"],opacity:1,debug:!1,tweenFunction:Pe.easeInOutQuad,tweenDuration:5e3,recycle:!0,run:!0},Ee=(function(){function s(e,n){var t=this;this.setOptionsWithDefaults=function(r){var o={confettiSource:{x:0,y:0,w:t.canvas.width,h:0}};t._options=I({},o,M,r),Object.assign(t,r.confettiSource)},this.update=function(){var r=t.options,o=r.run,c=r.onConfettiComplete,u=t.canvas,l=t.context;o&&(l.fillStyle="white",l.clearRect(0,0,u.width,u.height)),t.generator.animate()?t.rafId=requestAnimationFrame(t.update):(c&&typeof c=="function"&&t.generator.particlesGenerated>0&&c.call(t,t),t._options.run=!1)},this.reset=function(){t.generator&&t.generator.particlesGenerated>0&&(t.generator.particlesGenerated=0,t.generator.particles=[],t.generator.lastNumberOfPieces=0)},this.stop=function(){t.options={run:!1},t.rafId&&(cancelAnimationFrame(t.rafId),t.rafId=void 0)},this.canvas=e;var i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get canvas context");this.context=i,this.generator=new Me(this.canvas,function(){return t.options}),this.options=n,this.update()}return Ie(s,[{key:"options",get:function(){return this._options},set:function(n){var t=this._options&&this._options.run,i=this._options&&this._options.recycle;this.setOptionsWithDefaults(n),this.generator&&(Object.assign(this.generator,this.options.confettiSource),typeof n.recycle=="boolean"&&n.recycle&&i===!1&&(this.generator.lastNumberOfPieces=this.generator.particles.length)),typeof n.run=="boolean"&&n.run&&t===!1&&this.update()}}]),s})(),q=O.createRef();function S(s){var e={},n={},t={},i=[].concat(Object.keys(M),["confettiSource","drawShape","onConfettiComplete"]),r=["canvasRef"];return Object.keys(s).forEach(function(o){var c=s[o];i.includes(o)?e[o]=c:r.includes(o)?r[o]=c:t[o]=c}),[e,t,n]}var E=(function(s){be(e,s);function e(t){var i;return i=s.call(this,t)||this,i.canvas=O.createRef(),i.canvas=t.canvasRef||q,i}var n=e.prototype;return n.componentDidMount=function(){if(this.canvas.current){var i=S(this.props)[0];this.confetti=new Ee(this.canvas.current,i)}},n.componentDidUpdate=function(){var i=S(this.props)[0];this.confetti&&(this.confetti.options=i)},n.componentWillUnmount=function(){this.confetti&&this.confetti.stop(),this.confetti=void 0},n.render=function(){var i=S(this.props),r=i[0],o=i[1],c=I({zIndex:2,position:"absolute",pointerEvents:"none",top:0,left:0,bottom:0,right:0},o.style);return O.createElement("canvas",Object.assign({width:r.width,height:r.height,ref:this.canvas},o,{style:c}))},e})(f.Component);E.defaultProps=I({},M);E.displayName="ConfettiReact";var De=O.forwardRef(function(s,e){return O.createElement(E,Object.assign({canvasRef:q},s))});function _e({id:s}){return s?a.jsx(ie,{children:()=>a.jsx(De,{run:!!s,recycle:!1,numberOfPieces:800,width:window.innerWidth,height:window.innerHeight},s)}):null}function Re(){return a.jsx("div",{className:"border-destructive bg-destructive fixed top-0 right-0 left-0 z-50 border-b",children:a.jsxs("div",{className:"relative w-full p-4",children:[a.jsx(V,{to:"/workspace-structure",className:"absolute inset-0 z-10 block h-full w-full","aria-label":"Learn more about workspace structure"}),a.jsxs("div",{className:"relative z-0 container flex items-center justify-between",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(G,{name:"Error",className:"text-destructive-foreground h-5 w-5"}),a.jsxs("div",{children:[a.jsx("h3",{className:"text-destructive-foreground text-sm font-semibold",children:"Warning: Changes detected in exercises directory"}),a.jsx("p",{className:"text-destructive-foreground/80 text-xs",children:"You should typically work in the playground directory, not the exercises directory."})]})]}),a.jsxs("div",{className:"text-destructive-foreground flex items-center gap-2 text-xs",children:[a.jsx("span",{children:"Learn more"}),a.jsx(G,{name:"ArrowRight",className:"h-3 w-3"})]})]})]})})}const Te=[{title:"Navigation",shortcuts:[{keys:["g","h"],description:"Go to home"},{keys:["g","1-9"],description:"Go to exercise (e.g., g+1 → /exercise/01)"},{keys:["g","1-9",".","1-9"],description:"Go to exercise step (e.g., g+1+.+2 → /exercise/01/02/problem)"},{keys:["g","1-9",".","f"],description:"Go to exercise finished page (e.g., g+1+.+f → /exercise/01/finished)"},{keys:["g","p"],description:"Go to previous step/page"},{keys:["g","n"],description:"Go to next step/page"},{keys:["g","a"],description:"Go to account page"},{keys:["g","d"],description:"Go to admin page"},{keys:["g","l"],description:"Go to last exercise solution"},{keys:["Escape"],description:"Close sidebar navigation (when open)"}]},{title:"Playback Controls",shortcuts:[{keys:["Space","k"],description:"Play/pause video"},{keys:["j"],description:"Seek backward 10 seconds"},{keys:["l"],description:"Seek forward 10 seconds"},{keys:["←"],description:"Seek backward 10 seconds"},{keys:["→"],description:"Seek forward 10 seconds"}]},{title:"Frame-by-Frame Navigation",shortcuts:[{keys:[","],description:"Go to previous frame (when paused)"},{keys:["."],description:"Go to next frame (when paused)"}]},{title:"Volume Control",shortcuts:[{keys:["↑"],description:"Increase volume by 10%"},{keys:["↓"],description:"Decrease volume by 10%"}]},{title:"Playback Speed",shortcuts:[{keys:["Shift",">"],description:"Increase playback speed"},{keys:["Shift","<"],description:"Decrease playback speed"}]},{title:"Fullscreen and Picture-in-Picture",shortcuts:[{keys:["f"],description:"Toggle fullscreen mode"},{keys:["i"],description:"Toggle picture-in-picture mode"}]},{title:"Captions",shortcuts:[{keys:["c"],description:"Toggle captions/subtitles"}]},{title:"Quick Seek",shortcuts:[{keys:["0-9"],description:"Seek to percentage of video (0 = 0%, 1 = 10%, ..., 9 = 90%)"}]}];function Fe({open:s,onOpenChange:e}){return a.jsx(oe,{open:s,onOpenChange:e,children:a.jsxs(ae,{className:"max-h-[80vh] max-w-2xl overflow-y-auto",children:[a.jsxs(ce,{children:[a.jsx(ue,{children:"Keyboard Shortcuts"}),a.jsx(le,{children:"Use these keyboard shortcuts to navigate and control the video player"})]}),a.jsx("div",{className:"space-y-6",children:Te.map(n=>a.jsxs("div",{children:[a.jsx("h3",{className:"text-foreground mb-3 text-sm font-semibold",children:n.title}),a.jsx("div",{className:"space-y-2",children:n.shortcuts.map((t,i)=>a.jsxs("div",{className:"flex items-center justify-between gap-4",children:[a.jsx("span",{className:"text-muted-foreground flex-1 text-sm",children:t.description}),a.jsx("div",{className:"flex shrink-0 items-center gap-1",children:t.keys.map((r,o)=>a.jsxs(f.Fragment,{children:[a.jsx("kbd",{className:"border-border bg-muted rounded border px-2 py-1 font-mono text-xs",children:r}),o<t.keys.length-1&&a.jsx("span",{className:"text-muted-foreground",children:"+"})]},o))})]},i))})]},n.title))}),a.jsx("div",{className:"border-border mt-4 border-t pt-4",children:a.jsxs("p",{className:"text-muted-foreground text-xs",children:[a.jsx("strong",{children:"Note:"})," Shortcuts are ignored when focus is on interactive elements (inputs, buttons, etc.). Press"," ",a.jsx("kbd",{className:"border-border bg-muted rounded border px-1.5 py-0.5 font-mono text-xs",children:"?"})," ","to toggle this dialog."]})})]})})}function Ge({toast:s}){return a.jsxs(a.Fragment,{children:[a.jsx(de,{closeButton:!0,position:"top-center"}),s?a.jsx(Be,{toast:s}):null]})}function Be({toast:s}){const{id:e,type:n,title:t,description:i}=s;return f.useEffect(()=>{setTimeout(()=>{p[n](t,{id:e,description:i})},0)},[i,e,t,n]),null}function Ae({repoUpdates:s}){const{updatesAvailable:e}=s,n="diffLink"in s?s.diffLink:null,t="remoteCommit"in s?s.remoteCommit:void 0,i=A(),r=f.useRef(i);f.useEffect(()=>{r.current=i},[i]);const o=f.useRef(null),c=f.useRef(null),u=f.useRef(!1);return f.useEffect(()=>{if(e&&t){const l=p.info("New workshop updates available",{duration:1/0,description:a.jsxs("div",{children:["Get the latest updates by clicking the update button. ",n?a.jsx("a",{href:n,target:"_blank",rel:"noreferrer",className:"text-xs underline",children:"View changes"}):null]}),onDismiss:()=>{},action:{label:"Update",onClick:async()=>{if(c.current&&(p.dismiss(c.current),c.current=null),o.current||(o.current=p.loading("Update in progress...")),!u.current){u.current=!0;try{const{EPICSHOP_PARENT_PORT:v,EPICSHOP_PARENT_TOKEN:w}=window.ENV||{};if(!v||!w)throw new Error("Update API not available");const d=await fetch(`http://localhost:${v}/__epicshop-restart`,{method:"POST",headers:{"x-epicshop-token":w}});if(!d.ok)throw new Error(`Request to update workshop failed: ${d.statusText}`);const b=await d.json().catch(()=>({})),x=ve({status:ge(["ok","error"]),message:me().optional()}).safeParse(b);if(!x.success)throw console.error("Invalid response from update API",b),new Error("Invalid response from update API");const{status:k,message:g}=x.data;if(k==="ok"){let y=!1;p.success("Workshop updated",{description:"Reloading in 2 seconds... You can reload now if you prefer.",duration:2e3,action:{label:"Reload now",onClick:()=>{y=!0,window.location.reload()}},onAutoClose:()=>{y||window.location.reload()}})}else p.error("Failed to update workshop",{description:g||"Unknown error"})}catch(v){p.error("Failed to update workshop",{description:v instanceof Error?v.message:String(v)})}finally{u.current=!1,o.current&&(p.dismiss(o.current),o.current=null)}}}},cancel:{label:"Dismiss",onClick:()=>{c.current&&(p.dismiss(c.current),c.current=null),r.current.submit({intent:"mute",id:`update-repo-${t}`},{method:"post",action:"/admin/notifications"})}}});c.current=l}},[e,n,t]),null}function Le({unmutedNotifications:s}){const e=A(),n=f.useRef(e),t=f.useRef(new Set);return f.useEffect(()=>{for(const i of s)t.current.has(i.id)||(t.current.add(i.id),p.info(i.title,{id:i.id,description:a.jsxs("div",{children:[a.jsx("p",{children:i.message}),i.link&&a.jsx("a",{href:i.link,target:"_blank",className:"text-xs underline",children:"Learn more"})]}),duration:1/0,action:{label:"Dismiss",onClick:()=>{n.current.submit({intent:"mute",id:i.id},{method:"post",action:"/admin/notifications"})}}}))},[s]),null}const qe="/assets/app-DXvLEREP.css",We="/assets/tailwind-Dwn16kR6.css",ut=()=>[{rel:"stylesheet",href:"/neogrotesk-font.css"},{rel:"stylesheet",href:"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,200;0,300;0,400;0,500;0,600;1,700&display=swap"},{rel:"stylesheet",href:We},{rel:"stylesheet",href:qe},{rel:"icon",href:"/favicon.ico",sizes:"48x48"},{rel:"icon",type:"image/svg+xml",href:"/favicon.svg"}],lt=({loaderData:s})=>s?we({instructor:s.instructor,title:s.workshopTitle,description:s.workshopSubtitle,requestInfo:s.requestInfo}):[];function W({children:s,env:e={},className:n,style:t}){return a.jsxs("html",{lang:"en",className:n,style:t,children:[a.jsxs("head",{children:[a.jsx(ye,{}),a.jsx(K,{}),a.jsx("meta",{charSet:"utf-8"}),a.jsx("meta",{name:"viewport",content:"width=device-width,initial-scale=1"}),a.jsx(X,{}),a.jsx("script",{dangerouslySetInnerHTML:{__html:`window.ENV = ${JSON.stringify(e)}`}})]}),a.jsxs("body",{className:"bg-background text-foreground scrollbar-thin scrollbar-thumb-scrollbar h-screen-safe",children:[s,a.jsx(J,{}),a.jsx(Z,{})]})]})}function Qe(){const s=L(),e=z(),n=te.useSpinDelay(e.state!=="idle",{delay:400,minDuration:200}),t=ne(),[i,r]=f.useState(!1);f.useEffect(()=>{const c=()=>{r(u=>!u)};return window.addEventListener("toggle-keyboard-shortcuts",c),()=>{window.removeEventListener("toggle-keyboard-shortcuts",c)}},[]);const o=xe();return a.jsxs(W,{style:s.preferences?.fontSize?{fontSize:`${s.preferences?.fontSize}px`}:{},className:re("h-screen-safe antialiased",o,{"cursor-progress":n},t?"alt-down":null),env:s.ENV,children:[s.exerciseChanges&&!s.preferences?.exerciseWarning?.dismissed&&a.jsx(Re,{}),a.jsx(H,{}),a.jsx(_e,{id:s.confettiId}),a.jsx(Ge,{toast:s.toast}),a.jsx(Ae,{repoUpdates:s.repoUpdates}),a.jsx(he,{}),a.jsx(Le,{unmutedNotifications:s.unmutedNotifications}),a.jsx(Fe,{open:i,onOpenChange:r})]})}const ft=Y(function(){const{user:e}=L();return a.jsx(fe,{user:e,children:a.jsx(pe,{children:a.jsx(Qe,{})})})}),ht=$(function(){return a.jsx(W,{className:"h-screen-safe",children:a.jsx(se,{})})});export{ht as ErrorBoundary,ft as default,ut as links,lt as meta};
2
- //# sourceMappingURL=root-8Sq6HSdp.js.map
1
+ import{L as V,c as A,w as Y,a as $,b as L,f as z,O as K,M as H,J as X,S as J,K as Z}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{j as a}from"./jsx-runtime-C5WNSv3b.js";import{g as ee,R as O,r as f}from"./index-Az39ZADK.js";import{I as G,j as te,k as ne,c as re}from"./misc-BapXpylh.js";import{C as ie}from"./client-only-DtkKCk_i.js";import{G as se}from"./error-boundary-C8da5z08.js";import{D as oe,b as ae,c as ce,e as ue,d as le,P as fe}from"./presence-D6KivDVU.js";import{E as he}from"./progress-bar-D66irkpP.js";import{T as de,t as p}from"./index-Dd9cSrtE.js";import{T as pe}from"./tooltip-C2AQeNhD.js";import{o as ve,s as me,a9 as ge}from"./types-Cl2NuNg4.js";import{u as xe,C as ye}from"./index-_LzGTKVC.js";import{g as we}from"./seo-t5J-DRxw.js";import"./pe-Bs-DFNma.js";import"./preload-helper-BXl3LOEh.js";import"./index-Cod-PQ6D.js";import"./index-CjiomtK6.js";import"./online-Dw7HU4wM.js";import"./root-loader-C5P2c7MU.js";var C,B;function ke(){if(B)return C;B=1;var s={linear:function(e,n,t,i){var r=t-n;return r*e/i+n},easeInQuad:function(e,n,t,i){var r=t-n;return r*(e/=i)*e+n},easeOutQuad:function(e,n,t,i){var r=t-n;return-r*(e/=i)*(e-2)+n},easeInOutQuad:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e+n:-r/2*(--e*(e-2)-1)+n},easeInCubic:function(e,n,t,i){var r=t-n;return r*(e/=i)*e*e+n},easeOutCubic:function(e,n,t,i){var r=t-n;return r*((e=e/i-1)*e*e+1)+n},easeInOutCubic:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e*e+n:r/2*((e-=2)*e*e+2)+n},easeInQuart:function(e,n,t,i){var r=t-n;return r*(e/=i)*e*e*e+n},easeOutQuart:function(e,n,t,i){var r=t-n;return-r*((e=e/i-1)*e*e*e-1)+n},easeInOutQuart:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e*e*e+n:-r/2*((e-=2)*e*e*e-2)+n},easeInQuint:function(e,n,t,i){var r=t-n;return r*(e/=i)*e*e*e*e+n},easeOutQuint:function(e,n,t,i){var r=t-n;return r*((e=e/i-1)*e*e*e*e+1)+n},easeInOutQuint:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?r/2*e*e*e*e*e+n:r/2*((e-=2)*e*e*e*e+2)+n},easeInSine:function(e,n,t,i){var r=t-n;return-r*Math.cos(e/i*(Math.PI/2))+r+n},easeOutSine:function(e,n,t,i){var r=t-n;return r*Math.sin(e/i*(Math.PI/2))+n},easeInOutSine:function(e,n,t,i){var r=t-n;return-r/2*(Math.cos(Math.PI*e/i)-1)+n},easeInExpo:function(e,n,t,i){var r=t-n;return e==0?n:r*Math.pow(2,10*(e/i-1))+n},easeOutExpo:function(e,n,t,i){var r=t-n;return e==i?n+r:r*(-Math.pow(2,-10*e/i)+1)+n},easeInOutExpo:function(e,n,t,i){var r=t-n;return e===0?n:e===i?n+r:(e/=i/2)<1?r/2*Math.pow(2,10*(e-1))+n:r/2*(-Math.pow(2,-10*--e)+2)+n},easeInCirc:function(e,n,t,i){var r=t-n;return-r*(Math.sqrt(1-(e/=i)*e)-1)+n},easeOutCirc:function(e,n,t,i){var r=t-n;return r*Math.sqrt(1-(e=e/i-1)*e)+n},easeInOutCirc:function(e,n,t,i){var r=t-n;return(e/=i/2)<1?-r/2*(Math.sqrt(1-e*e)-1)+n:r/2*(Math.sqrt(1-(e-=2)*e)+1)+n},easeInElastic:function(e,n,t,i){var r=t-n,o,c,u;return u=1.70158,c=0,o=r,e===0?n:(e/=i)===1?n+r:(c||(c=i*.3),o<Math.abs(r)?(o=r,u=c/4):u=c/(2*Math.PI)*Math.asin(r/o),-(o*Math.pow(2,10*(e-=1))*Math.sin((e*i-u)*(2*Math.PI)/c))+n)},easeOutElastic:function(e,n,t,i){var r=t-n,o,c,u;return u=1.70158,c=0,o=r,e===0?n:(e/=i)===1?n+r:(c||(c=i*.3),o<Math.abs(r)?(o=r,u=c/4):u=c/(2*Math.PI)*Math.asin(r/o),o*Math.pow(2,-10*e)*Math.sin((e*i-u)*(2*Math.PI)/c)+r+n)},easeInOutElastic:function(e,n,t,i){var r=t-n,o,c,u;return u=1.70158,c=0,o=r,e===0?n:(e/=i/2)===2?n+r:(c||(c=i*(.3*1.5)),o<Math.abs(r)?(o=r,u=c/4):u=c/(2*Math.PI)*Math.asin(r/o),e<1?-.5*(o*Math.pow(2,10*(e-=1))*Math.sin((e*i-u)*(2*Math.PI)/c))+n:o*Math.pow(2,-10*(e-=1))*Math.sin((e*i-u)*(2*Math.PI)/c)*.5+r+n)},easeInBack:function(e,n,t,i,r){var o=t-n;return r===void 0&&(r=1.70158),o*(e/=i)*e*((r+1)*e-r)+n},easeOutBack:function(e,n,t,i,r){var o=t-n;return r===void 0&&(r=1.70158),o*((e=e/i-1)*e*((r+1)*e+r)+1)+n},easeInOutBack:function(e,n,t,i,r){var o=t-n;return r===void 0&&(r=1.70158),(e/=i/2)<1?o/2*(e*e*(((r*=1.525)+1)*e-r))+n:o/2*((e-=2)*e*(((r*=1.525)+1)*e+r)+2)+n},easeInBounce:function(e,n,t,i){var r=t-n,o;return o=s.easeOutBounce(i-e,0,r,i),r-o+n},easeOutBounce:function(e,n,t,i){var r=t-n;return(e/=i)<1/2.75?r*(7.5625*e*e)+n:e<2/2.75?r*(7.5625*(e-=1.5/2.75)*e+.75)+n:e<2.5/2.75?r*(7.5625*(e-=2.25/2.75)*e+.9375)+n:r*(7.5625*(e-=2.625/2.75)*e+.984375)+n},easeInOutBounce:function(e,n,t,i){var r=t-n,o;return e<i/2?(o=s.easeInBounce(e*2,0,r,i),o*.5+n):(o=s.easeOutBounce(e*2-i,0,r,i),o*.5+r*.5+n)}};return C=s,C}var je=ke();const Pe=ee(je);function Oe(s,e){for(var n=0;n<e.length;n++){var t=e[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(s,t.key,t)}}function Ie(s,e,n){return e&&Oe(s.prototype,e),s}function I(){return I=Object.assign||function(s){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(s[t]=n[t])}return s},I.apply(this,arguments)}function be(s,e){s.prototype=Object.create(e.prototype),s.prototype.constructor=s,N(s,e)}function N(s,e){return N=Object.setPrototypeOf||function(t,i){return t.__proto__=i,t},N(s,e)}function Ce(s){return s*Math.PI/180}function h(s,e){return s+Math.random()*(e-s)}function Se(s,e){return Math.floor(s+Math.random()*(e-s+1))}var P;(function(s){s[s.Circle=0]="Circle",s[s.Square=1]="Square",s[s.Strip=2]="Strip"})(P||(P={}));var m;(function(s){s[s.Positive=1]="Positive",s[s.Negative=-1]="Negative"})(m||(m={}));var Ne=(function(){function s(n,t,i,r){this.getOptions=t;var o=this.getOptions(),c=o.colors,u=o.initialVelocityX,l=o.initialVelocityY;this.context=n,this.x=i,this.y=r,this.w=h(5,20),this.h=h(5,20),this.radius=h(5,10),this.vx=h(-u,u),this.vy=h(-l,0),this.shape=Se(0,2),this.angle=Ce(h(0,360)),this.angularSpin=h(-.2,.2),this.color=c[Math.floor(Math.random()*c.length)],this.rotateY=h(0,1),this.rotationDirection=h(0,1)?m.Positive:m.Negative}var e=s.prototype;return e.update=function(){var t=this.getOptions(),i=t.gravity,r=t.wind,o=t.friction,c=t.opacity,u=t.drawShape;this.x+=this.vx,this.y+=this.vy,this.vy+=i,this.vx+=r,this.vx*=o,this.vy*=o,this.rotateY>=1&&this.rotationDirection===m.Positive?this.rotationDirection=m.Negative:this.rotateY<=-1&&this.rotationDirection===m.Negative&&(this.rotationDirection=m.Positive);var l=.1*this.rotationDirection;if(this.rotateY+=l,this.angle+=this.angularSpin,this.context.save(),this.context.translate(this.x,this.y),this.context.rotate(this.angle),this.context.scale(1,this.rotateY),this.context.rotate(this.angle),this.context.beginPath(),this.context.fillStyle=this.color,this.context.strokeStyle=this.color,this.context.globalAlpha=c,this.context.lineCap="round",this.context.lineWidth=2,u&&typeof u=="function")u.call(this,this.context);else switch(this.shape){case P.Circle:{this.context.beginPath(),this.context.arc(0,0,this.radius,0,2*Math.PI),this.context.fill();break}case P.Square:{this.context.fillRect(-this.w/2,-this.h/2,this.w,this.h);break}case P.Strip:{this.context.fillRect(-this.w/6,-this.h/2,this.w/3,this.h);break}default:throw new Error("Unknown type in Particle.ts")}this.context.closePath(),this.context.restore()},s})(),Me=function(e,n){var t=this;this.x=0,this.y=0,this.w=0,this.h=0,this.lastNumberOfPieces=0,this.tweenInitTime=Date.now(),this.particles=[],this.particlesGenerated=0,this.removeParticleAt=function(r){t.particles.splice(r,1)},this.getParticle=function(){var r=h(t.x,t.w+t.x),o=h(t.y,t.h+t.y);return new Ne(t.context,t.getOptions,r,o)},this.animate=function(){var r=t.canvas,o=t.context,c=t.particlesGenerated,u=t.lastNumberOfPieces,l=t.getOptions(),v=l.run,w=l.recycle,d=l.numberOfPieces,b=l.debug,_=l.tweenFunction,x=l.tweenDuration;if(!v)return!1;var k=t.particles.length,g=w?k:c,y=Date.now();if(g<d){u!==d&&(t.tweenInitTime=y,t.lastNumberOfPieces=d);for(var D=t.tweenInitTime,Q=y-D>x?x:Math.max(0,y-D),U=_(Q,g,d,x),R=Math.round(U-g),T=0;T<R;T+=1)t.particles.push(t.getParticle());t.particlesGenerated+=R}return b&&(o.font="12px sans-serif",o.fillStyle="#333",o.textAlign="right",o.fillText("Particles: "+k,r.width-10,r.height-20)),t.particles.forEach(function(j,F){j.update(),(j.y>r.height||j.y<-100||j.x>r.width+100||j.x<-100)&&(w&&g<=d?t.particles[F]=t.getParticle():t.removeParticleAt(F))}),k>0||g<d},this.canvas=e;var i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get canvas context");this.context=i,this.getOptions=n},M={width:typeof window<"u"?window.innerWidth:300,height:typeof window<"u"?window.innerHeight:200,numberOfPieces:200,friction:.99,wind:0,gravity:.1,initialVelocityX:4,initialVelocityY:10,colors:["#f44336","#e91e63","#9c27b0","#673ab7","#3f51b5","#2196f3","#03a9f4","#00bcd4","#009688","#4CAF50","#8BC34A","#CDDC39","#FFEB3B","#FFC107","#FF9800","#FF5722","#795548"],opacity:1,debug:!1,tweenFunction:Pe.easeInOutQuad,tweenDuration:5e3,recycle:!0,run:!0},Ee=(function(){function s(e,n){var t=this;this.setOptionsWithDefaults=function(r){var o={confettiSource:{x:0,y:0,w:t.canvas.width,h:0}};t._options=I({},o,M,r),Object.assign(t,r.confettiSource)},this.update=function(){var r=t.options,o=r.run,c=r.onConfettiComplete,u=t.canvas,l=t.context;o&&(l.fillStyle="white",l.clearRect(0,0,u.width,u.height)),t.generator.animate()?t.rafId=requestAnimationFrame(t.update):(c&&typeof c=="function"&&t.generator.particlesGenerated>0&&c.call(t,t),t._options.run=!1)},this.reset=function(){t.generator&&t.generator.particlesGenerated>0&&(t.generator.particlesGenerated=0,t.generator.particles=[],t.generator.lastNumberOfPieces=0)},this.stop=function(){t.options={run:!1},t.rafId&&(cancelAnimationFrame(t.rafId),t.rafId=void 0)},this.canvas=e;var i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get canvas context");this.context=i,this.generator=new Me(this.canvas,function(){return t.options}),this.options=n,this.update()}return Ie(s,[{key:"options",get:function(){return this._options},set:function(n){var t=this._options&&this._options.run,i=this._options&&this._options.recycle;this.setOptionsWithDefaults(n),this.generator&&(Object.assign(this.generator,this.options.confettiSource),typeof n.recycle=="boolean"&&n.recycle&&i===!1&&(this.generator.lastNumberOfPieces=this.generator.particles.length)),typeof n.run=="boolean"&&n.run&&t===!1&&this.update()}}]),s})(),q=O.createRef();function S(s){var e={},n={},t={},i=[].concat(Object.keys(M),["confettiSource","drawShape","onConfettiComplete"]),r=["canvasRef"];return Object.keys(s).forEach(function(o){var c=s[o];i.includes(o)?e[o]=c:r.includes(o)?r[o]=c:t[o]=c}),[e,t,n]}var E=(function(s){be(e,s);function e(t){var i;return i=s.call(this,t)||this,i.canvas=O.createRef(),i.canvas=t.canvasRef||q,i}var n=e.prototype;return n.componentDidMount=function(){if(this.canvas.current){var i=S(this.props)[0];this.confetti=new Ee(this.canvas.current,i)}},n.componentDidUpdate=function(){var i=S(this.props)[0];this.confetti&&(this.confetti.options=i)},n.componentWillUnmount=function(){this.confetti&&this.confetti.stop(),this.confetti=void 0},n.render=function(){var i=S(this.props),r=i[0],o=i[1],c=I({zIndex:2,position:"absolute",pointerEvents:"none",top:0,left:0,bottom:0,right:0},o.style);return O.createElement("canvas",Object.assign({width:r.width,height:r.height,ref:this.canvas},o,{style:c}))},e})(f.Component);E.defaultProps=I({},M);E.displayName="ConfettiReact";var _e=O.forwardRef(function(s,e){return O.createElement(E,Object.assign({canvasRef:q},s))});function De({id:s}){return s?a.jsx(ie,{children:()=>a.jsx(_e,{run:!!s,recycle:!1,numberOfPieces:800,width:window.innerWidth,height:window.innerHeight},s)}):null}function Re(){return a.jsx("div",{className:"border-destructive bg-destructive fixed top-0 right-0 left-0 z-50 border-b",children:a.jsxs("div",{className:"relative w-full p-4",children:[a.jsx(V,{to:"/workspace-structure",className:"absolute inset-0 z-10 block h-full w-full","aria-label":"Learn more about workspace structure"}),a.jsxs("div",{className:"relative z-0 container flex items-center justify-between",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(G,{name:"Error",className:"text-destructive-foreground h-5 w-5"}),a.jsxs("div",{children:[a.jsx("h3",{className:"text-destructive-foreground text-sm font-semibold",children:"Warning: Changes detected in exercises directory"}),a.jsx("p",{className:"text-destructive-foreground/80 text-xs",children:"You should typically work in the playground directory, not the exercises directory."})]})]}),a.jsxs("div",{className:"text-destructive-foreground flex items-center gap-2 text-xs",children:[a.jsx("span",{children:"Learn more"}),a.jsx(G,{name:"ArrowRight",className:"h-3 w-3"})]})]})]})})}const Te=[{title:"Navigation",shortcuts:[{keys:["g","h"],description:"Go to home"},{keys:["g","1-9"],description:"Go to exercise (e.g., g+1 → /exercise/01)"},{keys:["g","1-9",".","1-9"],description:"Go to exercise step (e.g., g+1+.+2 → /exercise/01/02/problem)"},{keys:["g","1-9",".","f"],description:"Go to exercise finished page (e.g., g+1+.+f → /exercise/01/finished)"},{keys:["g","p"],description:"Go to previous step/page"},{keys:["g","n"],description:"Go to next step/page"},{keys:["g","a"],description:"Go to account page"},{keys:["g","d"],description:"Go to admin page"},{keys:["g","l"],description:"Go to last exercise solution"},{keys:["Escape"],description:"Close sidebar navigation (when open)"}]},{title:"Playback Controls",shortcuts:[{keys:["Space","k"],description:"Play/pause video"},{keys:["j"],description:"Seek backward 10 seconds"},{keys:["l"],description:"Seek forward 10 seconds"},{keys:["←"],description:"Seek backward 10 seconds"},{keys:["→"],description:"Seek forward 10 seconds"}]},{title:"Frame-by-Frame Navigation",shortcuts:[{keys:[","],description:"Go to previous frame (when paused)"},{keys:["."],description:"Go to next frame (when paused)"}]},{title:"Volume Control",shortcuts:[{keys:["↑"],description:"Increase volume by 10%"},{keys:["↓"],description:"Decrease volume by 10%"}]},{title:"Playback Speed",shortcuts:[{keys:["Shift",">"],description:"Increase playback speed"},{keys:["Shift","<"],description:"Decrease playback speed"}]},{title:"Fullscreen and Picture-in-Picture",shortcuts:[{keys:["f"],description:"Toggle fullscreen mode"},{keys:["i"],description:"Toggle picture-in-picture mode"}]},{title:"Captions",shortcuts:[{keys:["c"],description:"Toggle captions/subtitles"}]},{title:"Quick Seek",shortcuts:[{keys:["0-9"],description:"Seek to percentage of video (0 = 0%, 1 = 10%, ..., 9 = 90%)"}]}];function Fe({open:s,onOpenChange:e}){return a.jsx(oe,{open:s,onOpenChange:e,children:a.jsxs(ae,{className:"max-h-[80vh] max-w-2xl overflow-y-auto",children:[a.jsxs(ce,{children:[a.jsx(ue,{children:"Keyboard Shortcuts"}),a.jsx(le,{children:"Use these keyboard shortcuts to navigate and control the video player"})]}),a.jsx("div",{className:"space-y-6",children:Te.map(n=>a.jsxs("div",{children:[a.jsx("h3",{className:"text-foreground mb-3 text-sm font-semibold",children:n.title}),a.jsx("div",{className:"space-y-2",children:n.shortcuts.map((t,i)=>a.jsxs("div",{className:"flex items-center justify-between gap-4",children:[a.jsx("span",{className:"text-muted-foreground flex-1 text-sm",children:t.description}),a.jsx("div",{className:"flex shrink-0 items-center gap-1",children:t.keys.map((r,o)=>a.jsxs(f.Fragment,{children:[a.jsx("kbd",{className:"border-border bg-muted rounded border px-2 py-1 font-mono text-xs",children:r}),o<t.keys.length-1&&a.jsx("span",{className:"text-muted-foreground",children:"+"})]},o))})]},i))})]},n.title))}),a.jsx("div",{className:"border-border mt-4 border-t pt-4",children:a.jsxs("p",{className:"text-muted-foreground text-xs",children:[a.jsx("strong",{children:"Note:"})," Shortcuts are ignored when focus is on interactive elements (inputs, buttons, etc.). Press"," ",a.jsx("kbd",{className:"border-border bg-muted rounded border px-1.5 py-0.5 font-mono text-xs",children:"?"})," ","to toggle this dialog."]})})]})})}function Ge({toast:s}){return a.jsxs(a.Fragment,{children:[a.jsx(de,{closeButton:!0,position:"top-center"}),s?a.jsx(Be,{toast:s}):null]})}function Be({toast:s}){const{id:e,type:n,title:t,description:i}=s;return f.useEffect(()=>{setTimeout(()=>{p[n](t,{id:e,description:i})},0)},[i,e,t,n]),null}function Ae({repoUpdates:s}){const{updatesAvailable:e}=s,n="diffLink"in s?s.diffLink:null,t="remoteCommit"in s?s.remoteCommit:void 0,i=A(),r=f.useRef(i);f.useEffect(()=>{r.current=i},[i]);const o=f.useRef(null),c=f.useRef(null),u=f.useRef(!1);return f.useEffect(()=>{if(e&&t){const l=p.info("New workshop updates available",{duration:1/0,description:a.jsxs("div",{children:["Get the latest updates by clicking the update button. ",n?a.jsx("a",{href:n,target:"_blank",rel:"noreferrer",className:"text-xs underline",children:"View changes"}):null]}),onDismiss:()=>{},action:{label:"Update",onClick:async()=>{if(c.current&&(p.dismiss(c.current),c.current=null),o.current||(o.current=p.loading("Update in progress...")),!u.current){u.current=!0;try{const{EPICSHOP_PARENT_PORT:v,EPICSHOP_PARENT_TOKEN:w}=window.ENV||{};if(!v||!w)throw new Error("Update API not available");const d=await fetch(`http://localhost:${v}/__epicshop-restart`,{method:"POST",headers:{"x-epicshop-token":w}});if(!d.ok)throw new Error(`Request to update workshop failed: ${d.statusText}`);const b=await d.json().catch(()=>({})),x=ve({status:ge(["ok","error"]),message:me().optional()}).safeParse(b);if(!x.success)throw console.error("Invalid response from update API",b),new Error("Invalid response from update API");const{status:k,message:g}=x.data;if(k==="ok"){let y=!1;p.success("Workshop updated",{description:"Reloading in 2 seconds... You can reload now if you prefer.",duration:2e3,action:{label:"Reload now",onClick:()=>{y=!0,window.location.reload()}},onAutoClose:()=>{y||window.location.reload()}})}else p.error("Failed to update workshop",{description:g||"Unknown error"})}catch(v){p.error("Failed to update workshop",{description:v instanceof Error?v.message:String(v)})}finally{u.current=!1,o.current&&(p.dismiss(o.current),o.current=null)}}}},cancel:{label:"Dismiss",onClick:()=>{c.current&&(p.dismiss(c.current),c.current=null),r.current.submit({intent:"mute",id:`update-repo-${t}`},{method:"post",action:"/admin/notifications"})}}});c.current=l}},[e,n,t]),null}function Le({unmutedNotifications:s}){const e=A(),n=f.useRef(e),t=f.useRef(new Set);return f.useEffect(()=>{for(const i of s)t.current.has(i.id)||(t.current.add(i.id),p.info(i.title,{id:i.id,description:a.jsxs("div",{children:[a.jsx("p",{children:i.message}),i.link&&a.jsx("a",{href:i.link,target:"_blank",className:"text-xs underline",children:"Learn more"})]}),duration:1/0,action:{label:"Dismiss",onClick:()=>{n.current.submit({intent:"mute",id:i.id},{method:"post",action:"/admin/notifications"})}}}))},[s]),null}const qe="/assets/app-DXvLEREP.css",We="/assets/tailwind-RrZj7_KO.css",ut=()=>[{rel:"stylesheet",href:"/neogrotesk-font.css"},{rel:"stylesheet",href:"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,200;0,300;0,400;0,500;0,600;1,700&display=swap"},{rel:"stylesheet",href:We},{rel:"stylesheet",href:qe},{rel:"icon",href:"/favicon.ico",sizes:"48x48"},{rel:"icon",type:"image/svg+xml",href:"/favicon.svg"}],lt=({loaderData:s})=>s?we({instructor:s.instructor,title:s.workshopTitle,description:s.workshopSubtitle,requestInfo:s.requestInfo}):[];function W({children:s,env:e={},className:n,style:t}){return a.jsxs("html",{lang:"en",className:n,style:t,children:[a.jsxs("head",{children:[a.jsx(ye,{}),a.jsx(H,{}),a.jsx("meta",{charSet:"utf-8"}),a.jsx("meta",{name:"viewport",content:"width=device-width,initial-scale=1"}),a.jsx(X,{}),a.jsx("script",{dangerouslySetInnerHTML:{__html:`window.ENV = ${JSON.stringify(e)}`}})]}),a.jsxs("body",{className:"bg-background text-foreground scrollbar-thin scrollbar-thumb-scrollbar h-screen-safe",children:[s,a.jsx(J,{}),a.jsx(Z,{})]})]})}function Qe(){const s=L(),e=z(),n=te.useSpinDelay(e.state!=="idle",{delay:400,minDuration:200}),t=ne(),[i,r]=f.useState(!1);f.useEffect(()=>{const c=()=>{r(u=>!u)};return window.addEventListener("toggle-keyboard-shortcuts",c),()=>{window.removeEventListener("toggle-keyboard-shortcuts",c)}},[]);const o=xe();return a.jsxs(W,{style:s.preferences?.fontSize?{fontSize:`${s.preferences?.fontSize}px`}:{},className:re("h-screen-safe antialiased",o,{"cursor-progress":n},t?"alt-down":null),env:s.ENV,children:[s.exerciseChanges&&!s.preferences?.exerciseWarning?.dismissed&&a.jsx(Re,{}),a.jsx(K,{}),a.jsx(De,{id:s.confettiId}),a.jsx(Ge,{toast:s.toast}),a.jsx(Ae,{repoUpdates:s.repoUpdates}),a.jsx(he,{}),a.jsx(Le,{unmutedNotifications:s.unmutedNotifications}),a.jsx(Fe,{open:i,onOpenChange:r})]})}const ft=Y(function(){const{user:e}=L();return a.jsx(fe,{user:e,children:a.jsx(pe,{children:a.jsx(Qe,{})})})}),ht=$(function(){return a.jsx(W,{className:"h-screen-safe",children:a.jsx(se,{})})});export{ht as ErrorBoundary,ft as default,ut as links,lt as meta};
2
+ //# sourceMappingURL=root-1p9mpscc.js.map