@alextheman/components 6.25.3 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,3 +1,2 @@
1
- import e from"@mui/material/Box";import t from"@mui/material/Card";import n from"@mui/material/CardContent";import r from"@mui/material/CardHeader";import i from"@mui/material/Chip";import a from"@mui/material/Divider";import o from"@mui/material/Stack";import s from"@mui/material/Typography";import{Fragment as c,jsx as l,jsxs as u}from"react/jsx-runtime";import d from"@mui/material/ButtonBase";import f from"@mui/material/Collapse";import{Fragment as p,createContext as m,use as h,useCallback as g,useEffect as _,useId as v,useMemo as y,useRef as ee,useState as b,useSyncExternalStore as te}from"react";import{MdArrowDropDown as x,MdArrowDropUp as ne,MdChevronLeft as re,MdChevronRight as ie,MdCloudUpload as ae,MdDelete as oe,MdMenu as se,MdOutlineDarkMode as ce,MdOutlineLightMode as le,MdVisibility as ue}from"react-icons/md";import S from"@mui/material/Link";import C from"@mui/material/Button";import{ThemeProvider as de,createTheme as fe,styled as w,useTheme as pe}from"@mui/material/styles";import T from"@mui/material/IconButton";import me from"@mui/material/List";import he from"@mui/material/ListItem";import ge from"@mui/material/ListItemText";import _e from"@mui/material/Tooltip";import ve from"@mui/material/Switch";import{DataError as E}from"@alextheman/utility/v6";import D from"@mui/material/CssBaseline";import{fillArray as ye,truncate as O,wait as be}from"@alextheman/utility";import xe from"@mui/material/Alert";import Se from"@mui/material/Snackbar";import Ce from"@mui/material/CircularProgress";import{stripIndent as we}from"common-tags";import{LiveEditor as Te,LiveError as Ee,LivePreview as De,LiveProvider as Oe}from"react-live";import ke from"@mui/material/Skeleton";import Ae from"@mui/material/TableCell";import je from"@mui/material/TableRow";import k from"@mui/material/Menu";import Me from"@mui/material/BottomNavigation";import Ne from"@mui/material/BottomNavigationAction";import Pe from"@mui/material/Paper";import Fe from"@mui/material/AppBar";import Ie from"@mui/material/Drawer";import A from"@mui/material/ListItemButton";import Le from"@mui/material/ListItemIcon";import Re from"@mui/material/Toolbar";import j from"@mui/material/MenuItem";import{Link as M,useLocation as ze}from"react-router-dom";import Be from"@mui/material/Popover";import{useFormContext as Ve}from"react-hook-form";function He({containerLabel:e,chipLabels:r}){return l(t,{sx:{width:320,height:420,backgroundColor:`rgba(255,255,255,0.07)`,backdropFilter:`blur(8px)`,border:`1px solid rgba(255,255,255,0.06)`,boxShadow:`0 10px 40px rgba(0,0,0,0.35)`},children:u(n,{children:[l(s,{variant:`h6`,gutterBottom:!0,sx:{color:`#f8fafc`},children:e}),l(o,{spacing:1,children:r.map(e=>l(i,{label:e,sx:{backgroundColor:`rgba(255,255,255,0.11)`,color:`rgba(255,255,255,0.88)`,border:`1px solid rgba(255,255,255,0.06)`}},e))})]})})}function Ue(){return l(e,{sx:{width:120,height:6,borderRadius:3,background:`linear-gradient(90deg, #f43f5e, #a78bfa, #22d3ee)`,boxShadow:`0 0 24px rgba(167,139,250,0.55)`}})}function We(){return u(t,{sx:{width:1e3,height:1e3,display:`flex`,flexDirection:`column`,justifyContent:`space-between`,p:4,background:`radial-gradient(circle at 20% 10%, rgba(167,139,250,0.35) 0%, rgba(167,139,250,0.12) 35%, rgba(0,0,0,0) 55%), linear-gradient(135deg, #3a3380 0%, #1d2e5f 40%, #2d3f55 100%)`,color:`white`},elevation:0,children:[l(r,{title:`An Interface For You And I`,sx:{color:`#f8fafc`,textAlign:`center`,"& .MuiCardHeader-title":{fontSize:40,fontWeight:600,letterSpacing:2}}}),l(a,{sx:{borderColor:`rgba(255,255,255,0.2)`}}),l(n,{sx:{flex:1,display:`flex`,alignItems:`center`},children:u(o,{direction:`row`,spacing:4,sx:{width:`100%`,justifyContent:`center`,alignItems:`center`},children:[l(He,{containerLabel:`You`,chipLabels:[`state`,`context`,`input`,`event`,`focus`,`value`,`history`]}),l(Ue,{}),l(He,{containerLabel:`I`,chipLabels:[`render`,`effect`,`response`,`update`,`history`,`layout`,`provider`]})]})})]})}function Ge({isInitiallyOpen:t,onOpen:n,onClose:r,children:i,buttonStyles:a,buttonContents:o,buttonComponent:s=d,collapseProps:c,openIcon:p=l(ne,{}),closedIcon:m=l(x,{}),useDefaultStyling:h=s===d}){let[g,v]=b(!!t);return _(()=>{g&&n?n():!g&&r&&r()},[g,n,r]),u(e,{children:[u(s,{onClick:()=>{v(e=>!e)},sx:h?{width:`100%`,display:`flex`,alignItems:`center`,justifyContent:`center`,paddingY:1.5,paddingX:2,textAlign:`center`,"&:hover":s===d?{backgroundColor:`action.hover`}:null,...a}:a,"aria-expanded":g,children:[o,g?p:m]}),l(f,{in:g,...c,children:i})]})}function Ke({href:e,children:t,ref:n,...r}){return l(S,{component:`a`,href:e,ref:n,target:`_blank`,rel:`noopener noreferrer`,...r,children:t})}const qe={PDF:`application/pdf`,PNG:`image/png`,JPEG:`image/jpeg`,JPG:`image/jpg`,XLSX:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,DOCX:`application/vnd.openxmlformats-officedocument.wordprocessingml.document`,MP3:`audio/mp3`,MP4:`video/mp4`,WAV:`audio/wav`},Je=w(`input`)({clip:`rect(0 0 0 0)`,clipPath:`inset(50%)`,height:1,overflow:`hidden`,position:`absolute`,bottom:0,left:0,whiteSpace:`nowrap`,width:1}),Ye=w(`div`)(({theme:e,$dragging:t})=>({border:`2px dashed`,borderColor:t?e.palette.primary.main:`#ccc`,backgroundColor:t?e.palette.action.hover:`transparent`,borderRadius:8,padding:`1.5rem`,textAlign:`center`,transition:`border-color 0.2s`,cursor:`pointer`}));function Xe({onFileInput:e,label:t=`Upload files`,multiple:n,accept:r,useDropzone:i,...a}){let[o,s]=b(!1),c=v(),d=u(C,{variant:`contained`,component:`label`,"aria-label":`File input button`,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),document.getElementById(c)?.click())},...a,startIcon:a.startIcon??l(ae,{}),children:[t,l(Je,{id:c,type:`file`,onChange:t=>{let n=t.target;e(Array.from(n.files??[])),n.value=``},multiple:n,accept:r?.join(`,`),disabled:a.disabled})]});return i?l(Ye,{$dragging:o,onDragOver:e=>{e.preventDefault(),!a.disabled&&s(!0)},onDragLeave:e=>{e.preventDefault(),s(!1)},onDrop:t=>{t.preventDefault(),s(!1),!a.disabled&&e(Array.from(t.dataTransfer.files??[]))},children:d}):d}function Ze({files:t,setFiles:n,multiple:r=!0,...i}){function a(e){n(t=>[...t,...e])}return u(e,{children:[l(Xe,{...i,multiple:r,onFileInput:a}),l(me,{children:t.map(e=>l(he,{secondaryAction:l(T,{"aria-label":`Delete`,edge:`end`,onClick:()=>{n(t=>t.filter(t=>t!==e))},children:l(oe,{})}),children:l(ge,{primary:e.name})},`${e.name}-${e.lastModified}`))})]})}const Qe=w(ve)(()=>({padding:8,"& .MuiSwitch-track":{borderRadius:11,"&::before, &::after":{content:`""`,position:`absolute`,top:`50%`,transform:`translateY(-50%)`,fontSize:16,width:28,height:28}}}));function $e({checkedIcon:t,checkedIconStyles:n,uncheckedIcon:r,uncheckedIconStyles:i,...a}){let o={borderRadius:`50%`,borderColor:`white`,backgroundColor:`white`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:.25},s={color:`black`,maxWidth:16.5,maxHeight:16.5};return l(Qe,{checkedIcon:l(e,{sx:o,children:l(t,{style:{...s,...n}})}),icon:l(e,{sx:o,children:l(r,{style:{...s,...i}})}),...a})}const N=m(void 0);function P({strict:e=!0}={}){let t=h(N);if(e&&!t)throw new E({strict:e,context:t},`AUDIO_PROVIDER_NOT_FOUND`,`Could not find the AudioProvider context. Please double-check that it is present.`);return t}function et({tracks:e,children:t}){let[n,r]=b(e[0]);return l(N,{value:{tracks:e,currentTrack:n,setCurrentTrack:r},children:t})}function tt(){let{currentTrack:e}=P();return l(`audio`,{src:e.src,controls:!0,children:l(`track`,{kind:`captions`})})}const F=m({toggleMode:()=>{},mode:`dark`});function I({strict:e=!0}={}){let t=h(F);if(e&&!t)throw new E({strict:e,context:t},`MODE_PROVIDER_NOT_FOUND`,`Could not find the ModeProvider context. Please double-check that it is present.`);return t}function nt({children:e,mode:t=`dark`}){let[n,r]=b(t),i=y(()=>fe({palette:{mode:n},components:{MuiPaper:{styleOverrides:{root:({theme:e})=>({border:1,borderStyle:`solid`,borderColor:e.palette.divider})}}}}),[n]);return l(F,{value:{mode:n,toggleMode:()=>{r(e=>e===`light`?`dark`:`light`)}},children:u(de,{theme:i,children:[l(D,{}),e]})})}const L=m({windowWidth:0,windowHeight:0,isLargeScreen:!1});function rt({strict:e=!0}={}){let t=h(L);if(e&&!t)throw new E({strict:e,context:t},`SCREEN_SIZE_PROVIDER_NOT_FOUND`,`Could not find the ScreenSizeProvider context. Please double-check that it is present.`);return t}let R={windowWidth:window.innerWidth,windowHeight:window.innerHeight};function it(){return R}function at(e){function t(){R={windowWidth:window.innerWidth,windowHeight:window.innerHeight},e()}return window.addEventListener(`resize`,t),()=>{window.removeEventListener(`resize`,t)}}function ot({children:e,largeScreenWidth:t=669,largeScreenHeight:n=660}){let{windowWidth:r,windowHeight:i}=te(at,it);return l(L,{value:{isLargeScreen:y(()=>r>t&&i>n,[r,i,t,n]),windowWidth:r,windowHeight:i},children:e})}const z=m(void 0);function st({strict:e=!0}={}){let t=h(z);if(e&&!t)throw new E({strict:e,context:t},`SNACKBAR_PROVIDER_NOT_FOUND`,`Could not find the SnackbarProvider context. Please double-check that it is present.`);return t}function ct({children:e,autoHideDuration:t=5e3}){let[n,r]=b(!1),[i,a]=b(t),[o,s]=b(``),[c,d]=b(`info`);function f(e,n,i){r(!0),a(i??t),d(n??`info`),s(e)}async function p(){r(!1),await be(.2),s(``)}return u(z,{value:{addSnackbar:f},children:[l(Se,{open:n,autoHideDuration:i,onClose:p,children:l(xe,{onClose:p,severity:c,children:o})}),e]})}function B(){let{mode:e,toggleMode:t}=I(),n=e===`dark`,r=`Enable ${n?`light`:`dark`} mode`;return l(_e,{title:r,children:l($e,{uncheckedIcon:le,checkedIcon:ce,checked:n,onChange:t,"aria-label":r})})}function lt({title:e,subtitle:i,action:o,children:d,tabs:f,disablePadding:p}){return u(t,{children:[l(r,{title:u(c,{children:[typeof e==`string`?l(s,{variant:`h6`,children:e}):e,i?typeof i==`string`?l(s,{variant:`body2`,color:`text.secondary`,children:i}):i:null]}),action:o}),f,l(a,{}),p?d:l(n,{children:d})]})}const V=m(void 0);function H({strict:e=!0}={}){let t=h(V);if(e&&!t)throw new E({strict:e,context:t},`QUERY_BOUNDARY_PROVIDER_NOT_FOUND`,`Could not find the QueryBoundaryProvider context. Please double-check that it is present.`);return t}function U({children:e,loadingComponent:t=l(Ce,{}),...n}){return l(V,{value:{loadingComponent:t,...n},children:e})}function W({children:e,logError:t}){let{data:n,error:r,errorComponent:i,logError:a}=H(),o=t??a,s=ee(!1),u=e??i;return r?(o&&!s.current&&(n==null?console.error(r):console.error(`An error has occurred but data is still present. This may indicate an invalid query state.`,{data:n,error:r}),s.current=!0),typeof u==`function`?u(r):u===void 0?l(xe,{severity:`error`,children:typeof r==`object`&&`message`in r&&typeof r.message==`string`?r.message:`An unknown error has occured.`}):l(c,{children:u})):null}function G({undefinedComponent:e,nullComponent:t,nullableComponent:n}){let{isLoading:r,data:i,error:a}=H();if(r||a)return null;if(i==null){if(n!==void 0)return l(c,{children:n});if(i===void 0)return e===void 0?l(s,{children:`No data available.`}):l(c,{children:e});if(i===null)return t===void 0?l(s,{children:`No data found.`}):l(c,{children:t})}return null}function K({errorComponent:e,logError:t,...n}){return u(c,{children:[l(W,{logError:t,children:e}),l(G,{...n})]})}function q({query:e}){return{Context:({children:t})=>l(U,{isLoading:e.isLoading,error:e.error,data:e.data,children:t}),Error:W,Fallback:K,Nullable:G}}function J({children:e,loadingComponent:t,itemKey:n,itemParser:r,dataParser:i,emptyComponent:a=l(s,{children:`No data present`}),strictlyRequireArray:o=!0}){let{isLoading:u,data:d,dataParser:f,loadingComponent:m,error:h}=H(),g=i??f,_=t??m;if(u)return l(c,{children:_});if(h||d==null)return null;if(!Array.isArray(d)){if(o)throw new E({data:d,strictlyRequireArray:o},`NOT_AN_ARRAY`,`Expected the data to be an array but it was not an array.`);return null}if(d.length===0)return l(c,{children:a});let v;return v=g?g(d):r?d.map(r):d,l(c,{children:v.map((t,r)=>l(p,{children:typeof e==`function`?e(t):e},n?n(t,r):r))})}function ut({query:e}){return{...q({query:e}),DataMap:J}}function dt({loadingComponent:e,undefinedComponent:t,nullComponent:n,nullableComponent:r,logError:i,errorComponent:a,children:o,isLoading:s,error:c,data:d,dataParser:f,itemParser:p,itemKey:m}){let h=ut({query:{isLoading:s,error:c,data:d}}),g=l(h.Fallback,{logError:i,errorComponent:a});r?g=l(h.Fallback,{nullableComponent:r,logError:i,errorComponent:a}):(t||n)&&(g=l(h.Fallback,{undefinedComponent:t,nullComponent:n,logError:i,errorComponent:a}));let _=l(h.DataMap,{loadingComponent:e,itemKey:m,children:o});return f?_=l(h.DataMap,{loadingComponent:e,itemKey:m,dataParser:f,children:o}):p&&(_=l(h.DataMap,{loadingComponent:e,itemKey:m,itemParser:p,children:o})),u(h.Context,{children:[g,_]})}function Y({children:e,dataParser:t,loadingComponent:n}){let{isLoading:r,data:i,dataParser:a,loadingComponent:o,error:s}=H(),u=t??a;return s?null:r?l(c,{children:n??o}):i==null?null:l(c,{children:typeof e==`function`?e(u?u(i):i):e})}function ft({query:e}){return{...q({query:e}),Data:Y}}function X({children:e,errorComponent:t,undefinedComponent:n,nullComponent:r,nullableComponent:i,logError:a,loadingComponent:o=l(Ce,{}),isLoading:s,error:c,data:d,dataParser:f}){let p=ft({query:{isLoading:s,error:c,data:d}}),m=l(p.Fallback,{logError:a,errorComponent:t});return i?m=l(p.Fallback,{nullableComponent:i,logError:a,errorComponent:t}):(n||r)&&(m=l(p.Fallback,{undefinedComponent:n,nullComponent:r,logError:a,errorComponent:t})),u(p.Context,{children:[m,l(p.Data,{loadingComponent:o,dataParser:f,children:e})]})}function pt({code:t,previewStyles:n,...r}){let{mode:i}=I(),a={backgroundColor:i===`dark`?`black`:`white`,border:.3,borderRadius:1,padding:2,borderColor:`darkgray`},o=n?{...a,...n}:{...a};return l(e,{sx:{borderRadius:1,border:.5,padding:2},children:u(Oe,{...r,code:we(t??``),children:[l(s,{variant:`h5`,children:`Code`}),l(e,{sx:{border:.3,borderRadius:.3,borderColor:`darkgray`},children:l(Te,{})}),l(`br`,{}),l(s,{variant:`h5`,children:`Result`}),u(e,{sx:o,children:[l(De,{}),l(Ee,{})]})]})})}function mt({columns:e}){return l(je,{children:ye(e=>l(Ae,{children:l(ke,{})},e),e)})}const ht=B;function gt({children:t,button:n=C,buttonChildren:r=`Menu`,buttonProps:i,isOpenIcon:a=l(ne,{}),isClosedIcon:o=l(x,{}),onOpen:s,onClose:c}){let[d,f]=b(null),p=y(()=>!!d,[d]),m={...i,onClick:e=>{f(e.currentTarget)},"aria-controls":p?`dropdown-menu`:void 0,"aria-haspopup":`true`,"aria-expanded":p};return n===C&&(m.endIcon=p?a:o),_(()=>{p&&s?s():!p&&c&&c()},[p,s,c]),u(e,{children:[l(n,{...m,children:r}),l(k,{id:`dropdown-menu`,anchorEl:d,open:p,onClose:()=>{f(null)},children:typeof t==`function`?l(e,{children:t(()=>{f(null)})}):t})]})}const _t=m(void 0);function Z({strict:e=!0}={}){let t=h(_t);if(e&&!t)throw new E({strict:e,context:t},`DROPDOWN_MENU_NOT_FOUND`,`Could not find the DropdownMenu context. Please double-check that it is present.`);return t}function vt({strict:e=!0}={}){return Z({strict:e})}function yt({children:e,onClose:t,...n}){let{anchorElement:r,isDropdownOpen:i,closeMenu:a}=vt();return l(k,{anchorEl:r,open:i,onClose:(e,n)=>{e.defaultPrevented||a(),t&&t(e,n)},...n,children:e})}function bt({component:e,children:t,ref:n,onClick:r,...i}){let{closeMenu:a}=Z();return l(j,{component:e,ref:n,...i,onClick:e=>{r&&r(e),!e.defaultPrevented&&a()},children:t})}const Q=Z,xt=yt,St=bt;var Ct=xt;function wt({ref:e,href:t,children:n,onClick:r,...i}){let{closeMenu:a}=Q();return l(j,{component:Ke,href:t,ref:e,...i,onClick:e=>{e.defaultPrevented||a(),r&&r(e)},children:n})}function $({to:e,component:t=M,children:n,ref:r,...i}){return l(S,{component:t,to:e,ref:r,...i,children:n})}function Tt({to:e,ref:t,children:n,onClick:r,...i}){let{closeMenu:a}=Q();return l(j,{component:$,to:e,ref:t,...i,onClick:e=>{e.defaultPrevented||a(),r&&r(e)},children:n})}function Et({icon:t=ue,onOpen:n,onClose:r,iconProps:i,children:a}){let[o,s]=b(null),c=!!o,d=v();function f(e){s(e.currentTarget),n&&n()}function p(){s(null),r&&r()}return u(e,{children:[l(t,{"aria-owns":c?d:void 0,"aria-haspopup":`true`,onMouseEnter:f,onMouseLeave:p,...i}),l(Be,{id:d,disablePortal:!0,disableScrollLock:!0,slotProps:{root:{disableEnforceFocus:!0,disableAutoFocus:!0,disableRestoreFocus:!0}},sx:{pointerEvents:`none`},open:c,anchorEl:o,anchorOrigin:{vertical:`bottom`,horizontal:`left`},transformOrigin:{vertical:`top`,horizontal:`left`},onClose:p,disableRestoreFocus:!0,children:a})]})}function Dt({children:e,...t}){return l(A,{component:$,...t,children:e})}const Ot=X;function kt({query:e}){return{Context:({children:t})=>l(U,{isLoading:e.isLoading,error:e.error,data:`data`in e?e.data:e.dataCollection,children:t}),Error:W,Data:Y,DataMap:J,Fallback:K,Nullable:G}}const At=Y,jt=K,Mt=U;function Nt({children:t,navItems:n}){let[r,i]=b(``);return u(c,{children:[l(e,{sx:{paddingBottom:7},children:t}),l(Pe,{sx:{position:`fixed`,bottom:0,left:0,right:0},children:l(Me,{showLabels:!0,value:r,onChange:(e,t)=>{i(t)},children:n.map(e=>l(Ne,{...e,component:M},e.value))})})]})}function Pt(e){return{width:240,transition:e.transitions.create(`width`,{easing:e.transitions.easing.sharp,duration:e.transitions.duration.enteringScreen}),overflowX:`hidden`}}function Ft(e){return{transition:e.transitions.create(`width`,{easing:e.transitions.easing.sharp,duration:e.transitions.duration.leavingScreen}),overflowX:`hidden`,width:`calc(${e.spacing(7)} + 1px)`,[e.breakpoints.up(`sm`)]:{width:`calc(${e.spacing(8)} + 1px)`}}}const It=w(`div`)(({theme:e})=>({display:`flex`,alignItems:`center`,justifyContent:`flex-end`,padding:e.spacing(0,1),...e.mixins.toolbar})),Lt=w(Fe,{shouldForwardProp:e=>e!==`open`})(({theme:e})=>({zIndex:e.zIndex.drawer+1,transition:e.transitions.create([`width`,`margin`],{easing:e.transitions.easing.sharp,duration:e.transitions.duration.leavingScreen}),variants:[{props:({open:e})=>e,style:{marginLeft:240,width:`calc(100% - 240px)`,transition:e.transitions.create([`width`,`margin`],{easing:e.transitions.easing.sharp,duration:e.transitions.duration.enteringScreen})}}]})),Rt=w(Ie,{shouldForwardProp:e=>e!==`open`})(({theme:e})=>({width:240,flexShrink:0,whiteSpace:`nowrap`,boxSizing:`border-box`,variants:[{props:({open:e})=>e,style:{...Pt(e),"& .MuiDrawer-paper":Pt(e)}},{props:({open:e})=>!e,style:{...Ft(e),"& .MuiDrawer-paper":Ft(e)}}]}));function zt({title:t,navItems:n,children:r,headerElements:i}){let o=pe(),[c,d]=b(!0),f=ze();function m(){d(!0)}function h(){d(!1)}return u(e,{sx:{display:`flex`},children:[l(D,{}),l(Lt,{position:`fixed`,open:c,children:u(Re,{children:[l(T,{color:`inherit`,"aria-label":`open drawer`,onClick:m,edge:`start`,sx:[{marginRight:5},c&&{display:`none`}],children:l(se,{})}),l(s,{variant:`h6`,noWrap:!0,component:`div`,children:t}),i]})}),u(Rt,{variant:`permanent`,open:c,children:[l(It,{children:l(T,{onClick:h,children:o.direction===`rtl`?l(ie,{}):l(re,{})})}),l(a,{}),n.map(e=>u(p,{children:[u(me,{children:[l(s,{variant:c?`h5`:`h6`,sx:{paddingLeft:c?2:1},children:c?e.category:O(e.category,4)}),e.options.map(e=>l(he,{disablePadding:!0,sx:{display:`block`},children:u(A,{sx:[{minHeight:48,px:2.5},c?{justifyContent:`initial`}:{justifyContent:`center`}],component:M,to:e.to,selected:f.pathname===e.to,children:[l(Le,{sx:[{minWidth:0,justifyContent:`center`},c?{mr:3}:{mr:`auto`}],children:e.icon?e.icon:c?null:l(s,{children:O(e.label,4)})}),l(ge,{primary:e.label,sx:[c?{opacity:1}:{opacity:0}]})]})},e.to))]}),l(a,{})]},e.category))]}),u(e,{component:`main`,sx:{flexGrow:1,p:3},children:[l(It,{}),r]})]})}function Bt({text:e,sx:t,...n}){return l(c,{children:e.split(`
2
- `).map((e,r)=>l(s,{sx:{margin:1,...t},...n,children:e},r))})}const Vt=X;function Ht({disableClean:e,label:t,...n}){let{formState:{disabled:r,isDirty:i,isSubmitting:a}}=Ve();return l(C,{color:`primary`,disabled:n.disabled||e&&!i||r,loading:a,type:`submit`,variant:`contained`,...n,children:t})}function Ut(e,t=500){let[n,r]=b(e);return _(()=>{let n=setTimeout(()=>{r(e)},t);return()=>{clearTimeout(n)}},[e,t]),n}function Wt(e){let[t,n]=b(()=>{let t=window.location.hash.replace(`#`,``);return e&&t===``?e:t}),r=g(()=>{let t=window.location.hash.replace(`#`,``);n(e&&t===``?e:t)},[n,e]);return _(()=>(window.addEventListener(`hashchange`,r),()=>{window.removeEventListener(`hashchange`,r)}),[r]),[t,g(e=>{let n=typeof e==`function`?e(t):e;n!==t&&(window.location.hash=n)},[t])]}export{We as Artwork,tt as AudioControls,et as AudioProvider,Ge as CollapsableItem,ht as DarkModeToggle,gt as DropdownMenu,Ct as DropdownMenu2,wt as DropdownMenuExternalLink,Tt as DropdownMenuInternalLink,St as DropdownMenuItem,Ke as ExternalLink,Xe as FileInput,Ze as FileInputList,qe as FileType,Et as IconWithPopover,$ as InternalLink,Dt as ListItemInternalLink,Ot as Loader,At as LoaderData,jt as LoaderError,Mt as LoaderProvider,nt as ModeProvider,B as ModeToggle,Nt as NavigationBottom,zt as NavigationDrawer,lt as Page,Bt as PopoverText,Vt as QueryBoundary,Y as QueryBoundaryData,J as QueryBoundaryDataMap,W as QueryBoundaryError,K as QueryBoundaryFallback,dt as QueryBoundaryMap,G as QueryBoundaryNullable,U as QueryBoundaryProvider,X as QueryBoundaryWrapper,pt as ReactPlayground,ot as ScreenSizeProvider,mt as SkeletonRow,ct as SnackbarProvider,Ht as SubmitButton,$e as SwitchWithIcons,q as createBaseQueryBoundary,ft as createItemQueryBoundary,ut as createListQueryBoundary,kt as createQueryBoundary,P as useAudioContext,Ut as useDebounce,Q as useDropdownMenu,Wt as useHash,I as useMode,H as useQueryBoundary,rt as useScreenSize,st as useSnackbar};
1
+ import e from"@mui/material/Box";import t from"@mui/material/Card";import n from"@mui/material/CardContent";import r from"@mui/material/CardHeader";import i from"@mui/material/Chip";import a from"@mui/material/Divider";import o from"@mui/material/Stack";import s from"@mui/material/Typography";import{Fragment as c,jsx as l,jsxs as u}from"react/jsx-runtime";import d from"@mui/material/ButtonBase";import f from"@mui/material/Collapse";import{useCallback as p,useEffect as m,useState as h}from"react";import{MdArrowDropDown as g,MdArrowDropUp as _}from"react-icons/md";import v from"@mui/material/Link";import{fillArray as y}from"@alextheman/utility";import b from"@mui/material/Skeleton";import x from"@mui/material/TableCell";import S from"@mui/material/TableRow";import{styled as C}from"@mui/material/styles";import w from"@mui/material/Switch";import T from"@mui/material/useMediaQuery";function E({containerLabel:e,chipLabels:r}){return l(t,{sx:{width:320,height:420,backgroundColor:`rgba(255,255,255,0.07)`,backdropFilter:`blur(8px)`,border:`1px solid rgba(255,255,255,0.06)`,boxShadow:`0 10px 40px rgba(0,0,0,0.35)`},children:u(n,{children:[l(s,{variant:`h6`,gutterBottom:!0,sx:{color:`#f8fafc`},children:e}),l(o,{spacing:1,children:r.map(e=>l(i,{label:e,sx:{backgroundColor:`rgba(255,255,255,0.11)`,color:`rgba(255,255,255,0.88)`,border:`1px solid rgba(255,255,255,0.06)`}},e))})]})})}function D(){return l(e,{sx:{width:120,height:6,borderRadius:3,background:`linear-gradient(90deg, #f43f5e, #a78bfa, #22d3ee)`,boxShadow:`0 0 24px rgba(167,139,250,0.55)`}})}function O(){return u(t,{sx:{width:1e3,height:1e3,display:`flex`,flexDirection:`column`,justifyContent:`space-between`,p:4,background:`radial-gradient(circle at 20% 10%, rgba(167,139,250,0.35) 0%, rgba(167,139,250,0.12) 35%, rgba(0,0,0,0) 55%), linear-gradient(135deg, #3a3380 0%, #1d2e5f 40%, #2d3f55 100%)`,color:`white`},elevation:0,children:[l(r,{title:`An Interface For You And I`,sx:{color:`#f8fafc`,textAlign:`center`,"& .MuiCardHeader-title":{fontSize:40,fontWeight:600,letterSpacing:2}}}),l(a,{sx:{borderColor:`rgba(255,255,255,0.2)`}}),l(n,{sx:{flex:1,display:`flex`,alignItems:`center`},children:u(o,{direction:`row`,spacing:4,sx:{width:`100%`,justifyContent:`center`,alignItems:`center`},children:[l(E,{containerLabel:`You`,chipLabels:[`state`,`context`,`input`,`event`,`focus`,`value`,`history`]}),l(D,{}),l(E,{containerLabel:`I`,chipLabels:[`render`,`effect`,`response`,`update`,`history`,`layout`,`provider`]})]})})]})}function k({isInitiallyOpen:t,onOpen:n,onClose:r,children:i,buttonStyles:a,buttonContents:o,buttonComponent:s=d,collapseProps:c,openIcon:p=l(_,{}),closedIcon:v=l(g,{}),useDefaultStyling:y=s===d}){let[b,x]=h(!!t);return m(()=>{b&&n?n():!b&&r&&r()},[b,n,r]),u(e,{children:[u(s,{onClick:()=>{x(e=>!e)},sx:y?{width:`100%`,display:`flex`,alignItems:`center`,justifyContent:`center`,paddingY:1.5,paddingX:2,textAlign:`center`,"&:hover":s===d?{backgroundColor:`action.hover`}:null,...a}:a,"aria-expanded":b,children:[o,b?p:v]}),l(f,{in:b,...c,children:i})]})}function A({href:e,children:t,ref:n,...r}){return l(v,{component:`a`,href:e,ref:n,target:`_blank`,rel:`noopener noreferrer`,...r,children:t})}function j({title:e,subtitle:i,action:o,children:d,tabs:f,disablePadding:p}){return u(t,{children:[l(r,{title:u(c,{children:[typeof e==`string`?l(s,{variant:`h6`,children:e}):e,i?typeof i==`string`?l(s,{variant:`body2`,color:`text.secondary`,children:i}):i:null]}),action:o}),f,l(a,{}),p?d:l(n,{children:d})]})}function M({columns:e}){return l(S,{children:y(e=>l(x,{children:l(b,{})},e),e)})}const N=C(w)(()=>({padding:8,"& .MuiSwitch-track":{borderRadius:11,"&::before, &::after":{content:`""`,position:`absolute`,top:`50%`,transform:`translateY(-50%)`,fontSize:16,width:28,height:28}}}));function P({checkedIcon:t,checkedIconStyles:n,uncheckedIcon:r,uncheckedIconStyles:i,...a}){let o={borderRadius:`50%`,borderColor:`white`,backgroundColor:`white`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:.25},s={color:`black`,maxWidth:16.5,maxHeight:16.5};return l(N,{checkedIcon:l(e,{sx:o,children:l(t,{style:{...s,...n}})}),icon:l(e,{sx:o,children:l(r,{style:{...s,...i}})}),...a})}function F(e,t=500){let[n,r]=h(e);return m(()=>{let n=setTimeout(()=>{r(e)},t);return()=>{clearTimeout(n)}},[e,t]),n}function I(e){let[t,n]=h(()=>{let t=window.location.hash.replace(`#`,``);return e&&t===``?e:t}),r=p(()=>{let t=window.location.hash.replace(`#`,``);n(e&&t===``?e:t)},[n,e]);return m(()=>(window.addEventListener(`hashchange`,r),()=>{window.removeEventListener(`hashchange`,r)}),[r]),[t,p(e=>{let n=typeof e==`function`?e(t):e;n!==t&&(window.location.hash=n)},[t])]}function L(){return T(e=>e.breakpoints.up(`md`))}export{O as Artwork,k as CollapsibleItem,A as ExternalLink,j as Page,M as SkeletonRow,P as SwitchWithIcons,F as useDebounce,I as useHash,L as useIsLargeScreen};
3
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Button","Fragment","useDropdownMenu","DropdownMenu","DropdownMenuItem","useDropdownMenu","useDropdownMenuV7","DropdownMenu","DropdownMenuItemV7","ReactDOMLink","Fragment","Button"],"sources":["../src/components/Artwork.tsx","../src/components/CollapsableItem.tsx","../src/components/ExternalLink.tsx","../src/components/FileInput.tsx","../src/components/FileInputList.tsx","../src/components/SwitchWithIcons.tsx","../src/providers/AudioProvider/index.tsx","../src/providers/AudioProvider/AudioControls.tsx","../src/providers/ModeProvider.tsx","../src/providers/ScreenSizeProvider.tsx","../src/providers/SnackbarProvider.tsx","../src/components/ModeToggle.tsx","../src/components/Page.tsx","../src/groups/QueryBoundary/QueryBoundaryProvider.tsx","../src/groups/QueryBoundary/QueryBoundaryError.tsx","../src/groups/QueryBoundary/QueryBoundaryNullable.tsx","../src/groups/QueryBoundary/QueryBoundaryFallback.tsx","../src/groups/QueryBoundary/creators/createBaseQueryBoundary.tsx","../src/groups/QueryBoundary/QueryBoundaryDataMap.tsx","../src/groups/QueryBoundary/creators/createListQueryBoundary.tsx","../src/components/QueryBoundaryMap.tsx","../src/groups/QueryBoundary/QueryBoundaryData.tsx","../src/groups/QueryBoundary/creators/createItemQueryBoundary.tsx","../src/components/QueryBoundaryWrapper.tsx","../src/components/ReactPlayground.tsx","../src/components/SkeletonRow.tsx","../src/deprecated/DarkModeToggle.tsx","../src/deprecated/DropdownMenu.tsx","../src/v7/components/DropdownMenu/DropdownMenuProvider.tsx","../src/v7/components/DropdownMenu/DropdownMenu.tsx","../src/v7/components/DropdownMenu/DropdownMenuItem.tsx","../src/deprecated/DropdownMenu2/DropdownMenu2.tsx","../src/deprecated/DropdownMenu2/DropdownMenuItem.tsx","../src/deprecated/DropdownMenu2/index.tsx","../src/deprecated/DropdownMenuExternalLink.tsx","../src/deprecated/InternalLink.tsx","../src/deprecated/DropdownMenuInternalLink.tsx","../src/deprecated/IconWithPopover.tsx","../src/deprecated/ListItemInternalLink.tsx","../src/deprecated/Loader.tsx","../src/groups/QueryBoundary/index.tsx","../src/deprecated/LoaderData.tsx","../src/deprecated/LoaderError.tsx","../src/deprecated/LoaderProvider.tsx","../src/deprecated/NavigationBottom.tsx","../src/deprecated/NavigationDrawer.tsx","../src/deprecated/PopoverText.tsx","../src/deprecated/QueryBoundary.tsx","../src/deprecated/SubmitButton.tsx","../src/hooks/useDebounce.ts","../src/hooks/useHash.ts"],"sourcesContent":["import Box from \"@mui/material/Box\";\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Chip from \"@mui/material/Chip\";\nimport Divider from \"@mui/material/Divider\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface ContainerProps {\n containerLabel: string;\n chipLabels: Array<string>;\n}\n\nfunction Container({ containerLabel, chipLabels }: ContainerProps) {\n return (\n <Card\n sx={{\n width: 320,\n height: 420,\n backgroundColor: \"rgba(255,255,255,0.07)\",\n backdropFilter: \"blur(8px)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n boxShadow: \"0 10px 40px rgba(0,0,0,0.35)\",\n }}\n >\n <CardContent>\n <Typography variant=\"h6\" gutterBottom sx={{ color: \"#f8fafc\" }}>\n {containerLabel}\n </Typography>\n\n <Stack spacing={1}>\n {chipLabels.map((label) => {\n return (\n <Chip\n key={label}\n label={label}\n sx={{\n backgroundColor: \"rgba(255,255,255,0.11)\",\n color: \"rgba(255,255,255,0.88)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n }}\n />\n );\n })}\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nfunction Connector() {\n return (\n <Box\n sx={{\n width: 120,\n height: 6,\n borderRadius: 3,\n background: \"linear-gradient(90deg, #f43f5e, #a78bfa, #22d3ee)\",\n boxShadow: \"0 0 24px rgba(167,139,250,0.55)\",\n }}\n />\n );\n}\n\n/** The artwork associated with the package's theme song, _An Interface For You And I_. */\nfunction Artwork() {\n return (\n <Card\n sx={{\n width: 1000,\n height: 1000,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n p: 4,\n background:\n \"radial-gradient(circle at 20% 10%, rgba(167,139,250,0.35) 0%, rgba(167,139,250,0.12) 35%, rgba(0,0,0,0) 55%), linear-gradient(135deg, #3a3380 0%, #1d2e5f 40%, #2d3f55 100%)\",\n color: \"white\",\n }}\n elevation={0}\n >\n <CardHeader\n title=\"An Interface For You And I\"\n sx={{\n color: \"#f8fafc\",\n textAlign: \"center\",\n \"& .MuiCardHeader-title\": {\n fontSize: 40,\n fontWeight: 600,\n letterSpacing: 2,\n },\n }}\n />\n\n <Divider sx={{ borderColor: \"rgba(255,255,255,0.2)\" }} />\n\n <CardContent sx={{ flex: 1, display: \"flex\", alignItems: \"center\" }}>\n <Stack\n direction=\"row\"\n spacing={4}\n sx={{ width: \"100%\", justifyContent: \"center\", alignItems: \"center\" }}\n >\n <Container\n containerLabel=\"You\"\n chipLabels={[\"state\", \"context\", \"input\", \"event\", \"focus\", \"value\", \"history\"]}\n />\n <Connector />\n <Container\n containerLabel=\"I\"\n chipLabels={[\"render\", \"effect\", \"response\", \"update\", \"history\", \"layout\", \"provider\"]}\n />\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nexport default Artwork;\n","import type { CollapseProps } from \"@mui/material/Collapse\";\nimport type { SxProps } from \"@mui/material/styles\";\nimport type { ElementType, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport ButtonBase from \"@mui/material/ButtonBase\";\nimport Collapse from \"@mui/material/Collapse\";\nimport { useEffect, useState } from \"react\";\nimport { MdArrowDropDown, MdArrowDropUp } from \"react-icons/md\";\n\nexport interface CollapsableItemProps {\n /** Whether the item should initially be open or not. */\n isInitiallyOpen?: boolean;\n /** A callback function to execute when the item is open. */\n onOpen?: () => void;\n /** A callback function to execute when the item is closed. */\n onClose?: () => void;\n /** The components to render when the item is open. */\n children: ReactNode;\n /** Styling for the button. */\n buttonStyles?: SxProps;\n /** The children to pass to the button. */\n buttonContents: ReactNode;\n /** The specific button component to use. */\n buttonComponent?: ElementType;\n /** The icon to show next to the button when open. */\n openIcon?: ReactNode;\n /** The icon to show next to the button when closed. */\n closedIcon?: ReactNode;\n /** Props to pass to collapse. */\n collapseProps?: Omit<CollapseProps, \"in\">;\n /**\n * Whether or not to use the default button styling.\n *\n * Defaults to `true` if `buttonComponent` is `ButtonBase`,\n * otherwise defaults to `false`.\n */\n useDefaultStyling?: boolean;\n}\n\n/**\n * Shows a display area that can be opened to show the children components, or hidden away.\n */\nfunction CollapsableItem({\n isInitiallyOpen,\n onOpen,\n onClose,\n children,\n buttonStyles,\n buttonContents,\n buttonComponent: ButtonComponent = ButtonBase,\n collapseProps,\n openIcon = <MdArrowDropUp />,\n closedIcon = <MdArrowDropDown />,\n useDefaultStyling = ButtonComponent === ButtonBase ? true : false,\n}: CollapsableItemProps) {\n const [isItemOpen, setIsItemOpen] = useState<boolean>(!!isInitiallyOpen);\n\n useEffect(() => {\n if (isItemOpen && onOpen) {\n onOpen();\n } else if (!isItemOpen && onClose) {\n onClose();\n }\n }, [isItemOpen, onOpen, onClose]);\n\n return (\n <Box>\n <ButtonComponent\n onClick={() => {\n setIsItemOpen((previouslyOpen) => {\n return !previouslyOpen;\n });\n }}\n sx={\n useDefaultStyling\n ? {\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n paddingY: 1.5,\n paddingX: 2,\n textAlign: \"center\",\n \"&:hover\":\n ButtonComponent === ButtonBase ? { backgroundColor: \"action.hover\" } : null,\n ...buttonStyles,\n }\n : buttonStyles\n }\n aria-expanded={isItemOpen}\n >\n {buttonContents}\n {isItemOpen ? openIcon : closedIcon}\n </ButtonComponent>\n <Collapse in={isItemOpen} {...collapseProps}>\n {children}\n </Collapse>\n </Box>\n );\n}\n\nexport default CollapsableItem;\n","import type { LinkProps } from \"@mui/material/Link\";\nimport type { ReactNode, Ref } from \"react\";\n\nimport MUILink from \"@mui/material/Link\";\n\nexport interface ExternalLinkProps extends Omit<LinkProps, \"to\" | \"target\" | \"rel\"> {\n /** The URL of the place you want to navigate to. */\n href: `https://${string}` | `http://${string}` | (string & {});\n to?: never;\n /** The readable content to display on the link. */\n children: ReactNode;\n /** An optional ref to allow it to be used with polymorphic components. */\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A stylised link that is best used when you want to navigate to a different domain.\n *\n * Opens the destination in a new tab and applies recommended security defaults automatically.\n */\nfunction ExternalLink({ href, children, ref, ...linkProps }: ExternalLinkProps) {\n return (\n <MUILink\n component=\"a\"\n href={href}\n ref={ref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {...linkProps}\n >\n {children}\n </MUILink>\n );\n}\n\nexport default ExternalLink;\n","import type { CreateEnumType } from \"@alextheman/utility\";\nimport type { ButtonOwnProps } from \"@mui/material/Button\";\n\nimport Button from \"@mui/material/Button\";\nimport { styled } from \"@mui/material/styles\";\nimport { useId, useState } from \"react\";\nimport { MdCloudUpload } from \"react-icons/md\";\n\nexport const FileType = {\n PDF: \"application/pdf\",\n PNG: \"image/png\",\n JPEG: \"image/jpeg\",\n JPG: \"image/jpg\",\n XLSX: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n DOCX: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n MP3: \"audio/mp3\",\n MP4: \"video/mp4\",\n WAV: \"audio/wav\",\n} as const;\nexport type FileType = CreateEnumType<typeof FileType>;\n\nconst VisuallyHiddenInput = styled(\"input\")({\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: 1,\n overflow: \"hidden\",\n position: \"absolute\",\n bottom: 0,\n left: 0,\n whiteSpace: \"nowrap\",\n width: 1,\n});\n\nconst Dropzone = styled(\"div\")<{ $dragging: boolean }>(({ theme, $dragging }) => {\n return {\n border: \"2px dashed\",\n borderColor: $dragging ? theme.palette.primary.main : \"#ccc\",\n backgroundColor: $dragging ? theme.palette.action.hover : \"transparent\",\n borderRadius: 8,\n padding: \"1.5rem\",\n textAlign: \"center\",\n transition: \"border-color 0.2s\",\n cursor: \"pointer\",\n };\n});\n\nexport interface FileInputProps extends ButtonOwnProps {\n /** A function to run when a file has been uploaded. */\n onFileInput: (allowedFiles: Array<File>) => void;\n /** The label to display on the input button (defaults to \"Upload files\") */\n label?: string;\n /** Whether to accept multiple files or not. */\n multiple?: boolean;\n /** An array of file types to accept. */\n accept?: Array<string>;\n /** Enable the dropzone, allowing users to drag and drop files. */\n useDropzone?: boolean;\n}\n\n/** Handles file inputs. */\nfunction FileInput({\n onFileInput,\n label = \"Upload files\",\n multiple,\n accept,\n useDropzone,\n ...buttonProps\n}: FileInputProps) {\n const [isDragging, setIsDragging] = useState<boolean>(false);\n const id = useId();\n\n const fileInputButton = (\n <Button\n variant=\"contained\"\n component=\"label\"\n aria-label=\"File input button\"\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n document.getElementById(id)?.click();\n }\n }}\n {...buttonProps}\n startIcon={buttonProps.startIcon ?? <MdCloudUpload />}\n >\n {label}\n <VisuallyHiddenInput\n id={id}\n type=\"file\"\n onChange={(event) => {\n const input = event.target;\n onFileInput(Array.from(input.files ?? []));\n input.value = \"\";\n }}\n multiple={multiple}\n accept={accept?.join(\",\")}\n disabled={buttonProps.disabled}\n />\n </Button>\n );\n\n return useDropzone ? (\n <Dropzone\n $dragging={isDragging}\n onDragOver={(event) => {\n event.preventDefault();\n if (buttonProps.disabled) {\n return;\n }\n setIsDragging(true);\n }}\n onDragLeave={(event) => {\n event.preventDefault();\n setIsDragging(false);\n }}\n onDrop={(event) => {\n event.preventDefault();\n setIsDragging(false);\n if (buttonProps.disabled) {\n return;\n }\n const filesArray = Array.from(event.dataTransfer.files ?? []);\n onFileInput(filesArray);\n }}\n >\n {fileInputButton}\n </Dropzone>\n ) : (\n fileInputButton\n );\n}\n\nexport default FileInput;\n","import type { Dispatch, SetStateAction } from \"react\";\n\nimport type { FileInputProps } from \"src/components/FileInput\";\n\nimport Box from \"@mui/material/Box\";\nimport IconButton from \"@mui/material/IconButton\";\nimport List from \"@mui/material/List\";\nimport ListItem from \"@mui/material/ListItem\";\nimport ListItemText from \"@mui/material/ListItemText\";\nimport { MdDelete } from \"react-icons/md\";\n\nimport FileInput from \"src/components/FileInput\";\n\nexport interface FileInputListProps extends Omit<FileInputProps, \"onFileInput\"> {\n /** The array of files (must be a React state). */\n files: Array<File>;\n /** The state setter for the array of files. */\n setFiles: Dispatch<SetStateAction<Array<File>>>;\n}\n\n/** Renders the `FileInput` component with a list of uploaded files underneath it. */\nfunction FileInputList({\n files,\n setFiles,\n multiple = true,\n ...fileInputProps\n}: FileInputListProps) {\n function onFileInput(newFiles: Array<File>) {\n setFiles((oldFiles) => {\n return [...oldFiles, ...newFiles];\n });\n }\n\n return (\n <Box>\n <FileInput {...fileInputProps} multiple={multiple} onFileInput={onFileInput} />\n <List>\n {files.map((file) => {\n return (\n <ListItem\n key={`${file.name}-${file.lastModified}`}\n secondaryAction={\n <IconButton\n aria-label=\"Delete\"\n edge=\"end\"\n onClick={() => {\n setFiles((oldFiles) => {\n return oldFiles.filter((fileToDelete) => {\n return fileToDelete !== file;\n });\n });\n }}\n >\n <MdDelete />\n </IconButton>\n }\n >\n <ListItemText primary={file.name} />\n </ListItem>\n );\n })}\n </List>\n </Box>\n );\n}\n\nexport default FileInputList;\n","import type { CommonProps } from \"@mui/material/OverridableComponent\";\nimport type { SwitchProps } from \"@mui/material/Switch\";\nimport type { ComponentType, CSSProperties } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport { styled } from \"@mui/material/styles\";\nimport Switch from \"@mui/material/Switch\";\n\nexport interface SwitchWithIconsProps extends Omit<SwitchProps, \"icon\" | \"checkedIcon\"> {\n /** The icon to show when the switch is in a checked state. */\n checkedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when checked. */\n checkedIconStyles?: CommonProps[\"style\"];\n /** The icon to show when the switch is in an unchecked state. */\n uncheckedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when unchecked. */\n uncheckedIconStyles?: CommonProps[\"style\"];\n}\n\nconst StyledSwitch = styled(Switch)(() => {\n return {\n padding: 8,\n \"& .MuiSwitch-track\": {\n borderRadius: 11,\n \"&::before, &::after\": {\n content: '\"\"',\n position: \"absolute\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n fontSize: 16,\n width: 28,\n height: 28,\n },\n },\n };\n});\n\n/** Renders a switch with your provided icons. */\nfunction SwitchWithIcons({\n checkedIcon: CheckedIcon,\n checkedIconStyles,\n uncheckedIcon: UncheckedIcon,\n uncheckedIconStyles,\n ...switchProps\n}: SwitchWithIconsProps) {\n const boxSx = {\n borderRadius: \"50%\",\n borderColor: \"white\",\n backgroundColor: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 0.25,\n };\n const defaultIconStyles = { color: \"black\", maxWidth: 16.5, maxHeight: 16.5 };\n return (\n <StyledSwitch\n checkedIcon={\n <Box sx={boxSx}>\n <CheckedIcon style={{ ...defaultIconStyles, ...checkedIconStyles }} />\n </Box>\n }\n icon={\n <Box sx={boxSx}>\n <UncheckedIcon style={{ ...defaultIconStyles, ...uncheckedIconStyles }} />\n </Box>\n }\n {...switchProps}\n />\n );\n}\n\nexport default SwitchWithIcons;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { Dispatch, ReactNode, SetStateAction } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport { createContext, use, useState } from \"react\";\n\nexport interface TrackData {\n title: string;\n src: string;\n artist: string;\n}\n\nexport interface AudioContextValue {\n tracks: Array<TrackData>;\n currentTrack: TrackData;\n setCurrentTrack: Dispatch<SetStateAction<TrackData>>;\n}\nexport interface AudioProviderProps {\n tracks: Array<TrackData>;\n children: ReactNode;\n}\n\nconst AudioContext = createContext<AudioContextValue | undefined>(undefined);\n\n/** Allows access to the audio information provided by AudioProvider. Will fail if AudioProvider could not be accessed and strict mode is true. */\nexport function useAudioContext<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, AudioContextValue> {\n const context = use(AudioContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"AUDIO_PROVIDER_NOT_FOUND\",\n \"Could not find the AudioProvider context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, AudioContextValue>;\n}\n\n/** Provides audio information to the children components. */\nfunction AudioProvider({ tracks, children }: AudioProviderProps) {\n const [currentTrack, setCurrentTrack] = useState<TrackData>(tracks[0]);\n\n return <AudioContext value={{ tracks, currentTrack, setCurrentTrack }}>{children}</AudioContext>;\n}\n\nexport default AudioProvider;\n","import { useAudioContext } from \"src/providers/AudioProvider\";\n\n/** Controls the tracks provided by the AudioProvider. */\nfunction AudioControls() {\n const { currentTrack } = useAudioContext();\n\n return (\n <audio src={currentTrack.src} controls>\n <track kind=\"captions\" />\n </audio>\n );\n}\n\nexport default AudioControls;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { PaletteMode } from \"@mui/material/styles\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport CssBaseline from \"@mui/material/CssBaseline\";\nimport { createTheme, ThemeProvider } from \"@mui/material/styles\";\nimport { createContext, use, useMemo, useState } from \"react\";\n\nexport interface ModeContextValue {\n toggleMode: () => void;\n mode: PaletteMode;\n}\n\nconst ModeContext = createContext<ModeContextValue>({\n toggleMode: () => {},\n mode: \"dark\",\n});\n\n/** Access the mode context directly. */\nexport function useMode<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, ModeContextValue> {\n const context = use(ModeContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"MODE_PROVIDER_NOT_FOUND\",\n \"Could not find the ModeProvider context. Please double-check that it is present.\",\n );\n }\n return context;\n}\n\nexport interface ModeProviderProps {\n /** The children that will have access to the current mode. */\n children: ReactNode;\n /** The initial mode. */\n mode?: PaletteMode;\n}\n\n/** Provides information about the current theme mode to its children components. */\nfunction ModeProvider({ children, mode: modeProp = \"dark\" }: ModeProviderProps) {\n const [mode, setMode] = useState<PaletteMode>(modeProp);\n\n const theme = useMemo(() => {\n return createTheme({\n palette: {\n mode,\n },\n components: {\n MuiPaper: {\n styleOverrides: {\n root: ({ theme }) => {\n return {\n border: 1,\n borderStyle: \"solid\",\n borderColor: theme.palette.divider,\n };\n },\n },\n },\n },\n });\n }, [mode]);\n\n return (\n <ModeContext\n value={{\n mode,\n toggleMode: () => {\n setMode((prev) => {\n return prev === \"light\" ? \"dark\" : \"light\";\n });\n },\n }}\n >\n <ThemeProvider theme={theme}>\n <CssBaseline />\n {children}\n </ThemeProvider>\n </ModeContext>\n );\n}\n\nexport default ModeProvider;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport { createContext, use, useMemo, useSyncExternalStore } from \"react\";\n\nexport interface ScreenSizeProps {\n /** The children that will be receiving the ScreenSizeContext. */\n children: ReactNode;\n /** The minimum screen width in pixels required to be considered a large screen. */\n largeScreenWidth?: number;\n /** The minimum screen height in pixels required to be considered a large screen. */\n largeScreenHeight?: number;\n}\n\nexport interface ScreenDimensions {\n /** The current window width. */\n windowWidth: number;\n /** The current window height. */\n windowHeight: number;\n}\n\nexport interface ScreenSizeContextValue extends ScreenDimensions {\n /** Whether the screen is a large screen or not. */\n isLargeScreen: boolean;\n}\n\nconst ScreenSizeContext = createContext<ScreenSizeContextValue>({\n windowWidth: 0,\n windowHeight: 0,\n isLargeScreen: false,\n});\n\n/** Access the screen size context directly. */\nexport function useScreenSize<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, ScreenSizeContextValue> {\n const context = use(ScreenSizeContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"SCREEN_SIZE_PROVIDER_NOT_FOUND\",\n \"Could not find the ScreenSizeProvider context. Please double-check that it is present.\",\n );\n }\n return context;\n}\n\nlet dimensions: ScreenDimensions = {\n windowWidth: window.innerWidth,\n windowHeight: window.innerHeight,\n};\n\nfunction getDimensions(): ScreenDimensions {\n return dimensions;\n}\n\nfunction subscribe(callback: () => void) {\n function handleResize() {\n dimensions = {\n windowWidth: window.innerWidth,\n windowHeight: window.innerHeight,\n };\n\n callback();\n }\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n}\n\n/** Provides context about the current screen size. */\nfunction ScreenSizeProvider({\n children,\n largeScreenWidth = 669,\n largeScreenHeight = 660,\n}: ScreenSizeProps) {\n const { windowWidth, windowHeight } = useSyncExternalStore<ScreenDimensions>(\n subscribe,\n getDimensions,\n );\n\n const isLargeScreen = useMemo(() => {\n return windowWidth > largeScreenWidth && windowHeight > largeScreenHeight;\n }, [windowWidth, windowHeight, largeScreenWidth, largeScreenHeight]);\n\n return (\n <ScreenSizeContext\n value={{\n isLargeScreen,\n windowWidth,\n windowHeight,\n }}\n >\n {children}\n </ScreenSizeContext>\n );\n}\n\nexport default ScreenSizeProvider;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { AlertColor } from \"@mui/material/Alert\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { wait } from \"@alextheman/utility\";\nimport { DataError } from \"@alextheman/utility/v6\";\nimport Alert from \"@mui/material/Alert\";\nimport Snackbar from \"@mui/material/Snackbar\";\nimport { createContext, use, useState } from \"react\";\n\nexport interface SnackbarProviderProps {\n /** The children that will have access to the snackbar context. */\n children: ReactNode;\n /** The amount of seconds to wait before hiding the snackbar. */\n autoHideDuration?: number;\n}\n\nexport interface SnackbarContextValue {\n /** A function that adds the snackbar to the page. */\n addSnackbar: (message: string, severity?: AlertColor, duration?: number) => void;\n}\n\nconst SnackbarContext = createContext<SnackbarContextValue | undefined>(undefined);\n\n/** Access the snackbar context directly. */\nexport function useSnackbar<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, SnackbarContextValue> {\n const context = use(SnackbarContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"SNACKBAR_PROVIDER_NOT_FOUND\",\n \"Could not find the SnackbarProvider context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, SnackbarContextValue>;\n}\n\n/** Controls the display of the snackbars on the page. */\nfunction SnackbarProvider({ children, autoHideDuration = 5000 }: SnackbarProviderProps) {\n const [open, setOpen] = useState<boolean>(false);\n const [autoHideDurationState, setAutoHideDurationState] = useState<number>(autoHideDuration);\n const [message, setMessage] = useState<string>(\"\");\n const [severity, setSeverity] = useState<AlertColor>(\"info\");\n\n function addSnackbar(message: string, severity?: AlertColor, duration?: number) {\n setOpen(true);\n setAutoHideDurationState(duration ?? autoHideDuration);\n setSeverity(severity ?? \"info\");\n setMessage(message);\n }\n\n async function handleClose() {\n setOpen(false);\n // Wait for 0.2 seconds to ensure that the message is only cleared after the snackbar is fully closed.\n // This prevents potential weird flickering that may occur if they happen synchronously.\n await wait(0.2);\n setMessage(\"\");\n }\n\n return (\n <SnackbarContext value={{ addSnackbar }}>\n <Snackbar open={open} autoHideDuration={autoHideDurationState} onClose={handleClose}>\n <Alert onClose={handleClose} severity={severity}>\n {message}\n </Alert>\n </Snackbar>\n {children}\n </SnackbarContext>\n );\n}\n\nexport default SnackbarProvider;\n","import Tooltip from \"@mui/material/Tooltip\";\nimport { MdOutlineDarkMode, MdOutlineLightMode } from \"react-icons/md\";\n\nimport SwitchWithIcons from \"src/components/SwitchWithIcons\";\nimport { useMode } from \"src/providers\";\n\n/** A toggle to switch between dark mode and light mode. Must be used in a `ModeProvider`. */\nfunction ModeToggle() {\n const { mode, toggleMode } = useMode();\n const isDarkMode = mode === \"dark\";\n const modeText = `Enable ${isDarkMode ? \"light\" : \"dark\"} mode`;\n\n return (\n <Tooltip title={modeText}>\n <SwitchWithIcons\n uncheckedIcon={MdOutlineLightMode}\n checkedIcon={MdOutlineDarkMode}\n checked={isDarkMode}\n onChange={toggleMode}\n aria-label={modeText}\n />\n </Tooltip>\n );\n}\n\nexport default ModeToggle;\n","import type { ReactNode } from \"react\";\n\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Divider from \"@mui/material/Divider\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface PageProps {\n /** The Page title to show */\n title: ReactNode;\n /** The subtitle to show under the Page title */\n subtitle?: ReactNode;\n /** The actions to show in the page header */\n action?: ReactNode;\n /** The actual page contents */\n children: ReactNode;\n /** Disable the inner padding of the Page contents. */\n disablePadding?: boolean;\n /** Optional tabs to display in the header. */\n tabs?: ReactNode;\n}\n\n/** Renders a pre-styled Page that can be used to structure pages throughout your React apps. */\nfunction Page({ title, subtitle, action, children, tabs, disablePadding }: PageProps) {\n return (\n <Card>\n <CardHeader\n title={\n <>\n {typeof title === \"string\" ? <Typography variant=\"h6\">{title}</Typography> : title}\n {subtitle ? (\n typeof subtitle === \"string\" ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {subtitle}\n </Typography>\n ) : (\n subtitle\n )\n ) : null}\n </>\n }\n action={action}\n />\n {tabs}\n <Divider />\n {disablePadding ? children : <CardContent>{children}</CardContent>}\n </Card>\n );\n}\n\nexport default Page;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\nimport { createContext, use } from \"react\";\n\nexport interface QueryBoundaryProviderBaseProps<DataType> {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The data being loaded. */\n data?: DataType | null | undefined;\n /** A parser for the data. */\n dataParser?: (data: unknown) => NonNullable<DataType>;\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n}\n\nexport interface QueryBoundaryProviderPropsWithNoError<\n DataType,\n> extends QueryBoundaryProviderBaseProps<DataType> {\n error?: never;\n errorComponent?: never;\n logError?: never;\n}\n\nexport interface QueryBoundaryProviderPropsWithError<\n DataType,\n> extends QueryBoundaryProviderBaseProps<DataType> {\n /** The error given if the request gave an error. */\n error: unknown;\n /** The component to show if an error has been thrown. Note that this may not be provided unless the error prop has also been provided. */\n errorComponent?: ReactNode | ((error: unknown) => ReactNode);\n /** Whether you want to log the error to the console or not. */\n logError?: boolean;\n}\n\nexport type QueryBoundaryContextValue<DataType> =\n | QueryBoundaryProviderPropsWithNoError<DataType>\n | QueryBoundaryProviderPropsWithError<DataType>;\nexport type QueryBoundaryProviderProps<DataType> = QueryBoundaryContextValue<DataType> & {\n children: ReactNode;\n};\n\nconst QueryBoundaryContext = createContext<QueryBoundaryContextValue<unknown> | undefined>(\n undefined,\n);\n\n/** Access the QueryBoundary context directly. */\nexport function useQueryBoundary<DataType, Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<\n Strict,\n QueryBoundaryContextValue<DataType>\n> {\n const context = use(QueryBoundaryContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"QUERY_BOUNDARY_PROVIDER_NOT_FOUND\",\n \"Could not find the QueryBoundaryProvider context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, QueryBoundaryContextValue<DataType>>;\n}\n\n/**\n * A provider for a context that deals with state management when fetching data from an API.\n * This may be used over QueryBoundary if you require more control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryProvider<DataType>({\n children,\n loadingComponent = <CircularProgress />,\n ...contextProps\n}: QueryBoundaryProviderProps<DataType>) {\n return (\n <QueryBoundaryContext value={{ loadingComponent, ...contextProps }}>\n {children}\n </QueryBoundaryContext>\n );\n}\n\nexport default QueryBoundaryProvider;\n","import type { ReactNode } from \"react\";\n\nimport Alert from \"@mui/material/Alert\";\nimport { useRef } from \"react\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryErrorProps {\n /** The component to show if an error has been thrown. */\n children?: ReactNode | ((error: unknown) => ReactNode);\n /** An option to log the error to the console. */\n logError?: boolean;\n}\n\n/**\n * The component responsible for showing any errors provided by QueryBoundaryProvider.\n */\nfunction QueryBoundaryError({ children, logError: propsLogError }: QueryBoundaryErrorProps) {\n const {\n data,\n error,\n errorComponent: contextErrorComponent,\n logError: contextLogError,\n } = useQueryBoundary();\n const logError = propsLogError ?? contextLogError;\n const warnedOnceRef = useRef(false);\n\n const errorComponent = children ?? contextErrorComponent;\n\n if (error) {\n if (logError && !warnedOnceRef.current) {\n if (data !== null && data !== undefined) {\n console.error(\n \"An error has occurred but data is still present. This may indicate an invalid query state.\",\n { data, error },\n );\n } else {\n console.error(error);\n }\n warnedOnceRef.current = true;\n }\n if (typeof errorComponent === \"function\") {\n return errorComponent(error);\n }\n if (errorComponent !== undefined) {\n return <>{errorComponent}</>;\n }\n\n return (\n <Alert severity=\"error\">\n {typeof error === \"object\" && \"message\" in error && typeof error.message === \"string\"\n ? error.message\n : \"An unknown error has occured.\"}\n </Alert>\n );\n }\n\n return null;\n}\n\nexport default QueryBoundaryError;\n","import type { ReactNode } from \"react\";\n\nimport Typography from \"@mui/material/Typography\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryNullablePropsWithUndefinedOrNull {\n /** The component to show if no error was thrown but data is undefined */\n undefinedComponent?: ReactNode;\n /** The component to show if no error was thrown but data is null */\n nullComponent?: ReactNode;\n nullableComponent?: never;\n}\n\nexport interface QueryBoundaryNullablePropsWithNullable {\n undefinedComponent?: never;\n nullComponent?: never;\n /** The component to show if no error was thrown but data is undefined or null */\n nullableComponent?: ReactNode;\n}\n\nexport type QueryBoundaryNullableProps =\n | QueryBoundaryNullablePropsWithUndefinedOrNull\n | QueryBoundaryNullablePropsWithNullable;\n\n/** The component responsible for handling cases when the data provided by `QueryBoundaryProvider` may be missing. */\nfunction QueryBoundaryNullable({\n undefinedComponent,\n nullComponent,\n nullableComponent,\n}: QueryBoundaryNullableProps) {\n const { isLoading, data, error } = useQueryBoundary();\n\n if (isLoading) {\n return null;\n }\n\n if (error) {\n return null;\n }\n\n if (data === null || data === undefined) {\n if (nullableComponent !== undefined) {\n return <>{nullableComponent}</>;\n }\n\n if (data === undefined) {\n if (undefinedComponent !== undefined) {\n return <>{undefinedComponent}</>;\n }\n return <Typography>No data available.</Typography>;\n }\n\n if (data === null) {\n if (nullComponent !== undefined) {\n return <>{nullComponent}</>;\n }\n return <Typography>No data found.</Typography>;\n }\n }\n\n return null;\n}\n\nexport default QueryBoundaryNullable;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryErrorProps } from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport type { QueryBoundaryNullableProps } from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\n\nimport QueryBoundaryError from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport QueryBoundaryNullable from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\n\nexport type QueryBoundaryFallbackProps = Omit<QueryBoundaryErrorProps, \"children\"> & {\n /** The component to show if an error has been thrown. */\n errorComponent?: ReactNode | ((error: unknown) => ReactNode);\n} & QueryBoundaryNullableProps;\n\n/**\n * The component responsible for handling both errors and nullable data from `QueryBoundaryProvider`\n */\nfunction QueryBoundaryFallback({\n errorComponent,\n logError,\n ...queryBoundaryNullableProps\n}: QueryBoundaryFallbackProps) {\n return (\n <>\n <QueryBoundaryError logError={logError}>{errorComponent}</QueryBoundaryError>\n <QueryBoundaryNullable {...queryBoundaryNullableProps} />\n </>\n );\n}\n\nexport default QueryBoundaryFallback;\n","import type { JSX, ReactNode } from \"react\";\n\nimport QueryBoundaryError from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport QueryBoundaryFallback from \"src/groups/QueryBoundary/QueryBoundaryFallback\";\nimport QueryBoundaryNullable from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\nimport QueryBoundaryProvider from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBase<DataType> {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The error given if the response gave an error. */\n error?: unknown;\n /** The data being loaded. */\n data: DataType;\n}\n\nexport interface CreateBaseQueryBoundaryParameters<DataType> {\n query: QueryBase<DataType>;\n}\n\nexport interface DefaultQueryBoundaryComponentsBase {\n Context: (props: { children: ReactNode }) => JSX.Element;\n Error: typeof QueryBoundaryError;\n Fallback: typeof QueryBoundaryFallback;\n Nullable: typeof QueryBoundaryNullable;\n}\n\n/** A creator function to create the base system of QueryBoundary components with the data fully typed throughout. */\nfunction createBaseQueryBoundary<DataType>({\n query,\n}: CreateBaseQueryBoundaryParameters<DataType>): DefaultQueryBoundaryComponentsBase {\n return {\n Context: ({ children }) => {\n return (\n <QueryBoundaryProvider isLoading={query.isLoading} error={query.error} data={query.data}>\n {children}\n </QueryBoundaryProvider>\n );\n },\n Error: QueryBoundaryError,\n Fallback: QueryBoundaryFallback,\n Nullable: QueryBoundaryNullable,\n };\n}\n\nexport default createBaseQueryBoundary;\n","import type { Key, ReactNode } from \"react\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport Typography from \"@mui/material/Typography\";\nimport { Fragment } from \"react\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryDataMapBaseProps<ItemType> {\n /**\n * The elements to show after data has been loaded.\n *\n * This is best provided as a function with a data argument that guarantees the data will not be undefined by the time you receive it here.\n */\n children: ReactNode | ((data: ItemType) => ReactNode);\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n /** The component to show if the array is empty. */\n emptyComponent?: ReactNode;\n /** Throw an error if the provided data is not an array. (defaults to `true`) */\n strictlyRequireArray?: boolean;\n /**\n * A function that takes a data item and returns the key to be used for the item.\n *\n * If not provided, it will fall back to using the index.\n */\n itemKey?: (item: ItemType, index: number) => Key;\n}\n\nexport interface QueryBoundaryDataMapPropsWithItemParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n /** A parser for each data item. */\n itemParser: (data: unknown) => ItemType;\n dataParser?: never;\n}\n\nexport interface QueryBoundaryDataMapPropsWithDataParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n /** A parser for each data item. */\n dataParser: (data: unknown) => Array<ItemType>;\n itemParser?: never;\n}\n\nexport interface QueryBoundaryDataMapPropsWithNoParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n dataParser?: never;\n itemParser?: never;\n}\n\nexport type QueryBoundaryDataMapProps<ItemType> =\n | QueryBoundaryDataMapPropsWithItemParser<ItemType>\n | QueryBoundaryDataMapPropsWithDataParser<ItemType>\n | QueryBoundaryDataMapPropsWithNoParser<ItemType>;\n\n/**\n * The component responsible for handling an array of data provided by `QueryBoundaryProvider`.\n *\n * It will map through the data array, rendering the result of the children function in a fragment with a key of its index in the list, unless overridden by the `itemKey` prop.\n *\n * @template ItemType - The type of data being loaded.\n *\n * @throws {DataError} If the data provided by `QueryBoundaryProvider` is not an array, and the `strictlyRequireArray` prop is `true` (it is by default).\n */\nfunction QueryBoundaryDataMap<ItemType>({\n children,\n loadingComponent: propLoadingComponent,\n itemKey,\n itemParser,\n dataParser: propDataParser,\n emptyComponent = <Typography>No data present</Typography>,\n strictlyRequireArray = true,\n}: QueryBoundaryDataMapProps<ItemType>) {\n const {\n isLoading,\n data,\n dataParser: contextDataParser,\n loadingComponent: contextLoadingComponent,\n error,\n } = useQueryBoundary<Array<ItemType>>();\n\n const dataParser = propDataParser ?? contextDataParser;\n const loadingComponent = propLoadingComponent ?? contextLoadingComponent;\n\n if (isLoading) {\n return <>{loadingComponent}</>;\n }\n\n if (error) {\n return null;\n }\n\n if (data === null || data === undefined) {\n return null;\n }\n\n if (!Array.isArray(data)) {\n if (strictlyRequireArray) {\n throw new DataError(\n { data, strictlyRequireArray },\n \"NOT_AN_ARRAY\",\n \"Expected the data to be an array but it was not an array.\",\n );\n }\n return null;\n }\n\n if (data.length === 0) {\n return <>{emptyComponent}</>;\n }\n\n let items: Array<ItemType>;\n\n if (dataParser) {\n items = dataParser(data);\n } else if (itemParser) {\n items = data.map(itemParser);\n } else {\n items = data;\n }\n\n return (\n <>\n {items.map((item, index) => {\n return (\n <Fragment key={itemKey ? itemKey(item, index) : index}>\n {typeof children === \"function\" ? children(item) : children}\n </Fragment>\n );\n })}\n </>\n );\n}\n\nexport default QueryBoundaryDataMap;\n","import type {\n DefaultQueryBoundaryComponentsBase,\n QueryBase,\n} from \"src/groups/QueryBoundary/creators/createBaseQueryBoundary\";\n\nimport createBaseQueryBoundary from \"src/groups/QueryBoundary/creators/createBaseQueryBoundary\";\nimport QueryBoundaryDataMap from \"src/groups/QueryBoundary/QueryBoundaryDataMap\";\n\nexport interface QueryList<DataType> extends Omit<QueryBase<DataType>, \"data\"> {\n /** The data being loaded. */\n data: Array<DataType> | null | undefined;\n}\n\nexport interface CreateListQueryBoundaryParameters<DataType> {\n query: QueryList<DataType>;\n}\n\nexport interface DefaultQueryBoundaryListComponents<\n DataType,\n> extends DefaultQueryBoundaryComponentsBase {\n DataMap: typeof QueryBoundaryDataMap<DataType>;\n}\n\n/** A creator function to create the system of QueryBoundary components with the data treated as an array of data items, fully typed throughout. */\nfunction createListQueryBoundary<DataType>({\n query,\n}: CreateListQueryBoundaryParameters<DataType>): DefaultQueryBoundaryListComponents<DataType> {\n const baseComponents = createBaseQueryBoundary({ query });\n\n return {\n ...baseComponents,\n DataMap: QueryBoundaryDataMap,\n };\n}\n\nexport default createListQueryBoundary;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryFallbackProps, QueryBoundaryProviderProps } from \"src/groups\";\nimport type { QueryBoundaryDataMapProps } from \"src/groups/QueryBoundary/QueryBoundaryDataMap\";\n\nimport createListQueryBoundary from \"src/groups/QueryBoundary/creators/createListQueryBoundary\";\n\nexport type QueryBoundaryMapProps<ItemType> = Omit<\n QueryBoundaryProviderProps<Array<ItemType>>,\n \"children\" | \"logError\"\n> &\n Omit<QueryBoundaryFallbackProps, \"errorComponent\"> &\n QueryBoundaryDataMapProps<ItemType>;\n\n/**\n * An in-line component that handles an array of data provided by `QueryBoundaryProvider`.\n *\n * This may be used over QueryBoundaryProvider/QueryBoundaryDataMap if you don't require as much control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryMap<ItemType>({\n loadingComponent,\n undefinedComponent,\n nullComponent,\n nullableComponent,\n logError,\n errorComponent,\n children,\n isLoading,\n error,\n data,\n dataParser,\n itemParser,\n itemKey,\n}: QueryBoundaryMapProps<ItemType>) {\n const QueryBoundary = createListQueryBoundary({ query: { isLoading, error, data } });\n\n let boundaryErrorComponent: ReactNode = (\n <QueryBoundary.Fallback logError={logError} errorComponent={errorComponent} />\n );\n\n if (nullableComponent) {\n boundaryErrorComponent = (\n <QueryBoundary.Fallback\n nullableComponent={nullableComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n } else if (undefinedComponent || nullComponent) {\n boundaryErrorComponent = (\n <QueryBoundary.Fallback\n undefinedComponent={undefinedComponent}\n nullComponent={nullComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n }\n\n let boundaryDataMapComponent: ReactNode = (\n <QueryBoundary.DataMap loadingComponent={loadingComponent} itemKey={itemKey}>\n {children}\n </QueryBoundary.DataMap>\n );\n\n if (dataParser) {\n boundaryDataMapComponent = (\n <QueryBoundary.DataMap\n loadingComponent={loadingComponent}\n itemKey={itemKey}\n dataParser={dataParser}\n >\n {children}\n </QueryBoundary.DataMap>\n );\n } else if (itemParser) {\n boundaryDataMapComponent = (\n <QueryBoundary.DataMap\n loadingComponent={loadingComponent}\n itemKey={itemKey}\n itemParser={itemParser}\n >\n {children}\n </QueryBoundary.DataMap>\n );\n }\n\n return (\n <QueryBoundary.Context>\n {boundaryErrorComponent}\n {boundaryDataMapComponent}\n </QueryBoundary.Context>\n );\n}\n\nexport default QueryBoundaryMap;\n","import type { ReactNode } from \"react\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryDataProps<DataType> {\n /**\n * The elements to show after data has been loaded.\n * This is best provided as a function with a data argument that guarantees the data will not be undefined by the time you receive it here.\n */\n children: ReactNode | ((data: NonNullable<DataType>) => ReactNode);\n /** A parser for the data. */\n dataParser?: (data: unknown) => NonNullable<DataType>;\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n}\n\n/**\n * The component responsible for showing the data provided by QueryBoundaryProvider.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryData<DataType>({\n children,\n dataParser: propDataParser,\n loadingComponent,\n}: QueryBoundaryDataProps<DataType>) {\n const {\n isLoading,\n data,\n dataParser: contextDataParser,\n loadingComponent: contextLoadingComponent,\n error,\n } = useQueryBoundary<DataType>();\n const dataParser = propDataParser ?? contextDataParser;\n\n if (error) {\n return null;\n }\n\n if (isLoading) {\n return <>{loadingComponent ?? contextLoadingComponent}</>;\n }\n\n if (data === null || data === undefined) {\n return null;\n }\n\n return (\n <>\n {typeof children === \"function\" ? children(dataParser ? dataParser(data) : data) : children}\n </>\n );\n}\n\nexport default QueryBoundaryData;\n","import type {\n DefaultQueryBoundaryComponentsBase,\n QueryBase,\n} from \"src/groups/QueryBoundary/creators/createBaseQueryBoundary\";\n\nimport createBaseQueryBoundary from \"src/groups/QueryBoundary/creators/createBaseQueryBoundary\";\nimport QueryBoundaryData from \"src/groups/QueryBoundary/QueryBoundaryData\";\n\nexport interface QueryItem<DataType> extends Omit<QueryBase<DataType>, \"data\"> {\n /** The data being loaded. */\n data: DataType | null | undefined;\n}\n\nexport interface CreateItemQueryBoundaryParameters<DataType> {\n query: QueryItem<DataType>;\n}\n\nexport interface DefaultQueryBoundaryItemComponents<\n DataType,\n> extends DefaultQueryBoundaryComponentsBase {\n Data: typeof QueryBoundaryData<DataType>;\n}\n\n/** A creator function to create the system of QueryBoundary components with the data treated as a single data item, fully typed throughout. */\nfunction createItemQueryBoundary<DataType>({\n query,\n}: CreateItemQueryBoundaryParameters<DataType>): DefaultQueryBoundaryItemComponents<DataType> {\n const baseComponents = createBaseQueryBoundary({ query });\n\n return {\n ...baseComponents,\n Data: QueryBoundaryData,\n };\n}\n\nexport default createItemQueryBoundary;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryDataProps, QueryBoundaryProviderProps } from \"src/groups\";\nimport type { QueryBoundaryFallbackProps } from \"src/groups/QueryBoundary/QueryBoundaryFallback\";\n\nimport CircularProgress from \"@mui/material/CircularProgress\";\n\nimport createItemQueryBoundary from \"src/groups/QueryBoundary/creators/createItemQueryBoundary\";\n\nexport type QueryBoundaryWrapperProps<DataType> = Omit<\n QueryBoundaryProviderProps<DataType>,\n \"children\" | \"logError\"\n> &\n Omit<QueryBoundaryFallbackProps, \"errorComponent\"> &\n Omit<QueryBoundaryDataProps<DataType>, \"showOnError\" | \"onUndefined\" | \"onNull\" | \"onNullable\">;\n\n/**\n * An in-line component that deals with state management when fetching data from an API.\n * This may be used over QueryBoundaryProvider if you don't require as much control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryWrapper<DataType>({\n children,\n errorComponent,\n undefinedComponent,\n nullComponent,\n nullableComponent,\n logError,\n loadingComponent = <CircularProgress />,\n isLoading,\n error,\n data,\n dataParser,\n}: QueryBoundaryWrapperProps<DataType>) {\n const QueryBoundary = createItemQueryBoundary({ query: { isLoading, error, data } });\n\n let boundaryFallbackComponent: ReactNode = (\n <QueryBoundary.Fallback logError={logError} errorComponent={errorComponent} />\n );\n\n if (nullableComponent) {\n boundaryFallbackComponent = (\n <QueryBoundary.Fallback\n nullableComponent={nullableComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n } else if (undefinedComponent || nullComponent) {\n boundaryFallbackComponent = (\n <QueryBoundary.Fallback\n undefinedComponent={undefinedComponent}\n nullComponent={nullComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n }\n\n return (\n <QueryBoundary.Context>\n {boundaryFallbackComponent}\n <QueryBoundary.Data loadingComponent={loadingComponent} dataParser={dataParser}>\n {children}\n </QueryBoundary.Data>\n </QueryBoundary.Context>\n );\n}\n\nexport default QueryBoundaryWrapper;\n","import type { SxProps, Theme } from \"@mui/material/styles\";\nimport type { ComponentProps } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\nimport { stripIndent } from \"common-tags\";\nimport { LiveEditor, LiveError, LivePreview, LiveProvider } from \"react-live\";\n\nimport { useMode } from \"src/providers\";\n\nexport interface ReactPlaygroundProps extends ComponentProps<typeof LiveProvider> {\n /** Extra styling to apply to the preview. Must be compatible with the Material UI `sx` prop. */\n previewStyles?: SxProps<Theme>;\n}\n\n/** Renders a playground to help demonstrate your React code in an interactive setting. */\nfunction ReactPlayground({ code, previewStyles, ...liveProviderProps }: ReactPlaygroundProps) {\n const { mode } = useMode();\n const defaultPreviewStyles: SxProps<Theme> = {\n backgroundColor: mode === \"dark\" ? \"black\" : \"white\",\n border: 0.3,\n borderRadius: 1,\n padding: 2,\n borderColor: \"darkgray\",\n };\n const allPreviewStyles = previewStyles\n ? { ...defaultPreviewStyles, ...previewStyles }\n : { ...defaultPreviewStyles };\n return (\n <Box sx={{ borderRadius: 1, border: 0.5, padding: 2 }}>\n <LiveProvider {...liveProviderProps} code={stripIndent(code ?? \"\")}>\n <Typography variant=\"h5\">Code</Typography>\n <Box\n sx={{\n border: 0.3,\n borderRadius: 0.3,\n borderColor: \"darkgray\",\n }}\n >\n <LiveEditor />\n </Box>\n <br />\n <Typography variant=\"h5\">Result</Typography>\n <Box sx={allPreviewStyles}>\n <LivePreview />\n <LiveError />\n </Box>\n </LiveProvider>\n </Box>\n );\n}\n\nexport default ReactPlayground;\n","import { fillArray } from \"@alextheman/utility\";\nimport Skeleton from \"@mui/material/Skeleton\";\nimport TableCell from \"@mui/material/TableCell\";\nimport TableRow from \"@mui/material/TableRow\";\n\nexport interface SkeletonRowProps {\n /** The number of columns the SkeletonRow should display. */\n columns: number;\n}\n\n/** Renders the skeleton of a table row. Often helpful to represent the loading state of the data in your table. */\nfunction SkeletonRow({ columns }: SkeletonRowProps) {\n return (\n <TableRow>\n {fillArray((index) => {\n return (\n <TableCell key={index}>\n <Skeleton />\n </TableCell>\n );\n }, columns)}\n </TableRow>\n );\n}\n\nexport default SkeletonRow;\n","import { ModeToggle } from \"src/components\";\n\n/** @deprecated This component has been renamed to `ModeToggle`. */\nconst DarkModeToggle = ModeToggle;\n\nexport default DarkModeToggle;\n","import type { ButtonOwnProps } from \"@mui/material/Button\";\nimport type { ElementType, MouseEvent as ReactMouseEvent, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport MUIButton from \"@mui/material/Button\";\nimport Menu from \"@mui/material/Menu\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { MdArrowDropDown, MdArrowDropUp } from \"react-icons/md\";\n\nexport interface DropdownMenuProps {\n children: ReactNode | ((closeMenu: () => void) => ReactNode);\n buttonChildren?: ReactNode;\n button?: ElementType;\n // Omit endIcon because the built-in isOpenIcon and isClosedIcon gives more control.\n // onClick is also omitted because that controls anchorElement, and the onOpen/onClose functions can be used instead.\n buttonProps?: Omit<ButtonOwnProps, \"onClick\" | \"endIcon\">;\n isOpenIcon?: ReactNode;\n isClosedIcon?: ReactNode;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\n/**\n * @deprecated This component does not support the new context-based pattern and individual DropdownMenuItem components. Please use DropdownMenu2 instead.\n */\nfunction DropdownMenu({\n children,\n button: Button = MUIButton,\n buttonChildren = \"Menu\",\n buttonProps: incomingButtonProps,\n isOpenIcon = <MdArrowDropUp />,\n isClosedIcon = <MdArrowDropDown />,\n onOpen,\n onClose,\n}: DropdownMenuProps) {\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n const isDropdownOpen = useMemo(() => {\n return !!anchorElement;\n }, [anchorElement]);\n\n const buttonProps: Record<string, unknown> = {\n ...incomingButtonProps,\n onClick: (event: ReactMouseEvent<HTMLElement>) => {\n setAnchorElement(event.currentTarget);\n },\n \"aria-controls\": isDropdownOpen ? \"dropdown-menu\" : undefined,\n \"aria-haspopup\": \"true\",\n \"aria-expanded\": isDropdownOpen,\n };\n\n if (Button === MUIButton) {\n buttonProps.endIcon = isDropdownOpen ? isOpenIcon : isClosedIcon;\n }\n\n useEffect(() => {\n if (isDropdownOpen && onOpen) {\n onOpen();\n } else if (!isDropdownOpen && onClose) {\n onClose();\n }\n }, [isDropdownOpen, onOpen, onClose]);\n\n return (\n <Box>\n <Button {...buttonProps}>{buttonChildren}</Button>\n <Menu\n id=\"dropdown-menu\"\n anchorEl={anchorElement}\n open={isDropdownOpen}\n onClose={() => {\n setAnchorElement(null);\n }}\n >\n {typeof children === \"function\" ? (\n <Box>\n {children(() => {\n setAnchorElement(null);\n })}\n </Box>\n ) : (\n children\n )}\n </Menu>\n </Box>\n );\n}\n\nexport default DropdownMenu;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { Dispatch, ReactNode, SetStateAction } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport { createContext, use, useMemo, useState } from \"react\";\n\nexport interface DropdownMenuContextValue {\n /** A function responsible for closing the dropdown menu. */\n closeMenu: () => void;\n /** Represents whether or not the dropdown is open. */\n isDropdownOpen: boolean;\n}\n\nexport type DropdownMenuInternalContextValue = DropdownMenuContextValue & {\n anchorElement: HTMLElement | null;\n setAnchorElement: Dispatch<SetStateAction<HTMLElement | null>>;\n};\nconst DropdownMenuContext = createContext<DropdownMenuInternalContextValue | undefined>(undefined);\n\n/**\n Access the DropdownMenu context directly.\n */\nexport function useDropdownMenu<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, DropdownMenuContextValue> {\n const context = use(DropdownMenuContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"DROPDOWN_MENU_NOT_FOUND\",\n \"Could not find the DropdownMenu context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, DropdownMenuContextValue>;\n}\n\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function useDropdownMenuInternal<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, DropdownMenuInternalContextValue> {\n return useDropdownMenu({ strict }) as OptionalOnCondition<\n Strict,\n DropdownMenuInternalContextValue\n >;\n}\n\nexport interface DropdownMenuProviderProps {\n /** The children to render inside of the dropdown. */\n children: ReactNode;\n}\n\n/** Provides shared context for the `DropdownMenu` related components. */\nfunction DropdownMenuProvider({ children }: DropdownMenuProviderProps) {\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n\n const isDropdownOpen = useMemo(() => {\n return !!anchorElement;\n }, [anchorElement]);\n\n function closeMenu() {\n setAnchorElement(null);\n }\n\n return (\n <DropdownMenuContext value={{ closeMenu, isDropdownOpen, anchorElement, setAnchorElement }}>\n {children}\n </DropdownMenuContext>\n );\n}\n\nexport default DropdownMenuProvider;\n","import type { MenuProps } from \"@mui/material/Menu\";\nimport type { MouseEvent, ReactNode } from \"react\";\n\nimport Menu from \"@mui/material/Menu\";\n\nimport { useDropdownMenuInternal } from \"src/v7/components/DropdownMenu/DropdownMenuProvider\";\n\nexport interface DropdownMenuProps extends Omit<MenuProps, \"anchorEl\" | \"open\"> {\n /** The children to render inside of the dropdown. */\n children: ReactNode;\n}\n\n/**\n * Renders a menu component that can be used alongside the `DropdownMenuProvider`.\n *\n * This component's open state would be controlled by the `DropdownMenuTrigger`.\n */\nfunction DropdownMenu({ children, onClose, ...menuProps }: DropdownMenuProps) {\n const { anchorElement, isDropdownOpen, closeMenu } = useDropdownMenuInternal();\n\n return (\n <Menu\n anchorEl={anchorElement}\n open={isDropdownOpen}\n onClose={(event: MouseEvent, reason) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClose) {\n onClose(event, reason);\n }\n }}\n {...menuProps}\n >\n {children}\n </Menu>\n );\n}\n\nexport default DropdownMenu;\n","import type Button from \"@mui/material/Button\";\nimport type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n ComponentPropsWithRef,\n ElementType,\n ReactNode,\n} from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { useDropdownMenu } from \"src/v7/components/DropdownMenu/DropdownMenuProvider\";\n\nexport type DropdownMenuItemProps<RootComponent extends ElementType = typeof Button> = {\n /**\n * An optional component to provide to override the current component.\n *\n * Note that the provided component must:\n * - accept a `to` prop.\n * - correctly handle the forwarded `ref`.\n * - render a valid anchor element (or equivalent) for proper accessibility.\n */\n component?: RootComponent;\n /** The children to be rendered within the menu item. */\n children?: ReactNode;\n /** The ref to forward to allow it to be used with polymorphic components */\n ref?: ComponentPropsWithRef<RootComponent>[\"ref\"];\n /** A function to execute after clicking the item. */\n onClick?: ComponentProps<RootComponent>[\"onClick\"];\n} & Omit<ComponentPropsWithoutRef<RootComponent>, \"children\" | \"ref\"> &\n MenuItemOwnProps;\n\n/** Represents a menu item to be used inside the `DropdownMenu`. It must be used as children of the `DropdownMenu` component. */\nfunction DropdownMenuItem<RootComponent extends ElementType = typeof Button>({\n component,\n children,\n ref,\n onClick,\n ...menuItemProps\n}: DropdownMenuItemProps<RootComponent>) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={component}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (onClick) {\n onClick(event);\n }\n if (event.defaultPrevented) {\n return;\n }\n closeMenu();\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuItem;\n","import type {\n DropdownMenuContextValue as DropdownMenuContextValueV7,\n DropdownMenuProps,\n} from \"src/v7\";\n\nimport { DropdownMenu, useDropdownMenu as useDropdownMenuV7 } from \"src/v7\";\n\nexport type DropdownMenuContextValue = DropdownMenuContextValueV7;\n\nexport const useDropdownMenu = useDropdownMenuV7;\n\n/**\n * @deprecated Please use `DropdownMenuProps` from `@alextheman/components/v7` instead.\n *\n * This will be replaced in the root entrypoint in a future release.\n */\nexport type DropdownMenu2Props = DropdownMenuProps;\n\n/**\n * @deprecated Please use `DropdownMenu` from `@alextheman/components/v7` instead.\n *\n * This will be replaced in the root entrypoint in a future release.\n */\nconst DropdownMenu2 = DropdownMenu;\n\nexport default DropdownMenu2;\n","import type { ElementType } from \"react\";\n\nimport type { DropdownMenuItemProps as DropdownMenuItemPropsV7 } from \"src/v7\";\n\nimport { DropdownMenuItem as DropdownMenuItemV7 } from \"src/v7\";\n\nexport type DropdownMenuItemProps<RootComponent extends ElementType> =\n DropdownMenuItemPropsV7<RootComponent>;\n\nconst DropdownMenuItem = DropdownMenuItemV7;\n\nexport default DropdownMenuItem;\n","import DropdownMenu2 from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\n\nexport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nexport { default as DropdownMenuItem } from \"src/deprecated/DropdownMenu2/DropdownMenuItem\";\n\nexport type { DropdownMenu2Props } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nexport type { DropdownMenuItemProps } from \"src/deprecated/DropdownMenu2/DropdownMenuItem\";\n\nexport default DropdownMenu2;\n","import type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type { ComponentProps, MouseEventHandler, ReactNode, Ref } from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { ExternalLink } from \"src/components\";\nimport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\n\nexport interface DropdownMenuExternalLinkProps extends MenuItemOwnProps {\n ref?: Ref<HTMLAnchorElement>;\n href: ComponentProps<typeof ExternalLink>[\"href\"];\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children: ReactNode;\n}\n\n/** @deprecated Please use `<DropdownMenuItem component={ExternalLink} />` instead. */\nfunction DropdownMenuExternalLink({\n ref,\n href,\n children,\n onClick,\n ...menuItemProps\n}: DropdownMenuExternalLinkProps) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={ExternalLink}\n href={href}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClick) {\n onClick(event);\n }\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuExternalLink;\n","import type { LinkProps } from \"@mui/material/Link\";\nimport type { ElementType, ReactNode, Ref } from \"react\";\n\nimport MUILink from \"@mui/material/Link\";\nimport { Link as ReactDOMLink } from \"react-router-dom\";\n\nexport interface InternalLinkProps extends Omit<LinkProps, \"href\" | \"component\"> {\n /** The path to navigate to */\n to: `/${string}` | `~/${string}` | (string & {});\n /**\n * An optional component to provide to override the current component.\n *\n * Note that the provided component must:\n * - accept a `to` prop\n * - correctly handle the forwarded `ref`\n * - render a valid anchor element (or equivalent) for proper accessibility\n */\n component?: ElementType;\n href?: never;\n /** The readable content to display on the link. */\n children: ReactNode;\n /** An optional ref to allow it to be used with polymorphic components. */\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A stylised link for navigating within your application.\n *\n * Uses the app router for client-side navigation and opens the destination in the same tab.\n *\n * Defaults to a React Router implementation but can be overridden via the `component` prop.\n *\n * @deprecated This component is not compatible with the rest of the Wouter setup for use in v7. Please use `InternalLink` from `@alextheman/components/v7` instead. This component will be replaced when v7 officially comes out.\n */\nfunction InternalLink({\n to,\n component = ReactDOMLink,\n children,\n ref,\n ...linkProps\n}: InternalLinkProps) {\n return (\n <MUILink component={component} to={to} ref={ref} {...linkProps}>\n {children}\n </MUILink>\n );\n}\n\nexport default InternalLink;\n","import type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type { ComponentProps, MouseEventHandler, ReactNode, Ref } from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nimport InternalLink from \"src/deprecated/InternalLink\";\n\nexport interface DropdownMenuInternalLinkProps extends MenuItemOwnProps {\n ref?: Ref<HTMLAnchorElement>;\n to: ComponentProps<typeof InternalLink>[\"to\"];\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children: ReactNode;\n}\n\n/** @deprecated Please use `<DropdownMenuItem component={InternalLink} />` instead. */\nfunction DropdownMenuInternalLink({\n to,\n ref,\n children,\n onClick,\n ...menuItemProps\n}: DropdownMenuInternalLinkProps) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={InternalLink}\n to={to}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClick) {\n onClick(event);\n }\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuInternalLink;\n","import type { OverridableComponent } from \"@mui/material/OverridableComponent\";\nimport type { SvgIconTypeMap } from \"@mui/material/SvgIcon\";\nimport type { ElementType, MouseEvent as ReactMouseEvent, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport Popover from \"@mui/material/Popover\";\nimport { useId, useState } from \"react\";\nimport { MdVisibility } from \"react-icons/md\";\n\nexport interface IconWithPopoverProps {\n icon?:\n | (OverridableComponent<SvgIconTypeMap<unknown, \"svg\">> & {\n muiName: string;\n })\n | ElementType;\n onOpen?: () => void;\n onClose?: () => void;\n iconProps?: SvgIconTypeMap<unknown, \"svg\">[\"props\"];\n children: ReactNode;\n}\n\n/**\n * @deprecated This component is not well-designed for accessibility purposes. Please use the `Tooltip` component from `@mui/material` instead.\n *\n * @example\n * ```tsx\n * <Tooltip title=\"Text to display on hover\">\n * <MdVisibility />\n * </Tooltip>\n * ```\n */\nfunction IconWithPopover({\n icon: Icon = MdVisibility,\n onOpen,\n onClose,\n iconProps,\n children,\n}: IconWithPopoverProps) {\n const [anchorElement, setAnchorElement] = useState<Element | null>(null);\n const isPopoverOpen = !!anchorElement;\n const popoverId = useId();\n\n function handleOpen(event: ReactMouseEvent<SVGSVGElement, MouseEvent>) {\n setAnchorElement(event.currentTarget);\n if (onOpen) {\n onOpen();\n }\n }\n\n function handleClose() {\n setAnchorElement(null);\n if (onClose) {\n onClose();\n }\n }\n\n return (\n <Box>\n <Icon\n aria-owns={isPopoverOpen ? popoverId : undefined}\n aria-haspopup=\"true\"\n onMouseEnter={handleOpen}\n onMouseLeave={handleClose}\n {...iconProps}\n />\n <Popover\n id={popoverId}\n disablePortal\n disableScrollLock\n slotProps={{\n root: {\n disableEnforceFocus: true,\n disableAutoFocus: true,\n disableRestoreFocus: true,\n },\n }}\n sx={{ pointerEvents: \"none\" }}\n open={isPopoverOpen}\n anchorEl={anchorElement}\n anchorOrigin={{\n vertical: \"bottom\",\n horizontal: \"left\",\n }}\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"left\",\n }}\n onClose={handleClose}\n disableRestoreFocus\n >\n {children}\n </Popover>\n </Box>\n );\n}\n\nexport default IconWithPopover;\n","import type { ListItemButtonProps } from \"@mui/material/ListItemButton\";\nimport type { ReactNode } from \"react\";\n\nimport ListItemButton from \"@mui/material/ListItemButton\";\n\nimport InternalLink from \"src/deprecated/InternalLink\";\n\nexport interface ListItemInternalLinkProps extends Omit<ListItemButtonProps, \"href\"> {\n children: ReactNode;\n to: string;\n}\n\n/** @deprecated Probably not that worth centralising here - can be easily recreated per use case. */\nfunction ListItemInternalLink({ children, ...listItemButtonProps }: ListItemInternalLinkProps) {\n return (\n <ListItemButton component={InternalLink} {...listItemButtonProps}>\n {children}\n </ListItemButton>\n );\n}\n\nexport default ListItemInternalLink;\n","import type { QueryBoundaryWrapperProps } from \"src/components/QueryBoundaryWrapper\";\n\nimport { QueryBoundaryWrapper } from \"src/components\";\n/** @deprecated This type has been renamed to QueryBoundaryProps. */\nexport type LoaderProps<DataType> = QueryBoundaryWrapperProps<DataType>;\n/** @deprecated This component has been renamed to QueryBoundary */\nconst Loader = QueryBoundaryWrapper;\n\nexport default Loader;\n","import type { JSX, ReactNode } from \"react\";\n\nimport QueryBoundaryData from \"src/groups/QueryBoundary/QueryBoundaryData\";\nimport QueryBoundaryDataMap from \"src/groups/QueryBoundary/QueryBoundaryDataMap\";\nimport QueryBoundaryError from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport QueryBoundaryFallback from \"src/groups/QueryBoundary/QueryBoundaryFallback\";\nimport QueryBoundaryNullable from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\nimport QueryBoundaryProvider from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBase {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The error given if the response gave an error. */\n error?: unknown;\n}\n\nexport interface QuerySingle<DataType> extends QueryBase {\n /** The data being loaded. */\n data: DataType | null | undefined;\n dataCollection?: never;\n}\n\nexport interface QueryMultiple<ItemType> extends QueryBase {\n /** An array of data items being loaded. */\n dataCollection: Array<ItemType> | null | undefined;\n data?: never;\n}\n\nexport type Query<DataType> = QuerySingle<DataType> | QueryMultiple<DataType>;\n\nexport interface CreateQueryBoundaryParameters<DataType> {\n query: Query<DataType>;\n}\n\nexport interface DefaultQueryBoundaryComponents<DataType> {\n Context: (props: { children: ReactNode }) => JSX.Element;\n Error: typeof QueryBoundaryError;\n Data: typeof QueryBoundaryData<DataType>;\n DataMap: typeof QueryBoundaryDataMap<DataType>;\n Fallback: typeof QueryBoundaryFallback;\n Nullable: typeof QueryBoundaryNullable;\n}\n\n/**\n * A creator function to create a system of QueryBoundary components with the data fully typed throughout.\n *\n * @deprecated Please use either `createBaseQueryBoundary`, `createItemQueryBoundary`, or `createListQueryBoundary` from `@alextheman/components/v7` instead.\n */\nfunction createQueryBoundary<DataType>({\n query,\n}: CreateQueryBoundaryParameters<DataType>): DefaultQueryBoundaryComponents<DataType> {\n return {\n Context: ({ children }) => {\n return (\n <QueryBoundaryProvider\n isLoading={query.isLoading}\n error={query.error}\n data={\"data\" in query ? query.data : query.dataCollection}\n >\n {children}\n </QueryBoundaryProvider>\n );\n },\n Error: QueryBoundaryError,\n Data: QueryBoundaryData<DataType>,\n DataMap: QueryBoundaryDataMap<DataType>,\n Fallback: QueryBoundaryFallback,\n Nullable: QueryBoundaryNullable,\n };\n}\n\nexport default createQueryBoundary;\n","import type { QueryBoundaryDataProps } from \"src/groups\";\n\nimport { QueryBoundaryData } from \"src/groups\";\n\n/** @deprecated This type has been renamed to QueryBoundaryDataProps. */\nexport type LoaderDataProps<DataType> = QueryBoundaryDataProps<DataType>;\n\n/** @deprecated This component has been renamed to QueryBoundaryData. */\nconst LoaderData = QueryBoundaryData;\n\nexport default LoaderData;\n","import type {\n QueryBoundaryErrorProps,\n QueryBoundaryFallbackProps,\n QueryBoundaryNullablePropsWithNullable,\n QueryBoundaryNullablePropsWithUndefinedOrNull,\n} from \"src/groups\";\n\nimport { QueryBoundaryFallback } from \"src/groups\";\n\n/** @deprecated This type has been renamed to QueryBoundaryErrorProps. */\nexport type LoaderErrorBaseProps = QueryBoundaryErrorProps;\n\n/** @deprecated This type has been renamed to QueryBoundaryNullablePropsWithUndefinedOrNull. */\nexport type LoaderErrorPropsWithUndefinedOrNull = LoaderErrorBaseProps &\n QueryBoundaryNullablePropsWithUndefinedOrNull;\n\n/** @deprecated This type has been renamed to QueryBoundaryNullablePropsWithNullable. */\nexport type LoaderErrorPropsWithNullable = LoaderErrorBaseProps &\n QueryBoundaryNullablePropsWithNullable;\n\n/** @deprecated This type has been renamed to QueryBoundaryFallbackProps. */\nexport type LoaderErrorProps = QueryBoundaryFallbackProps;\n\n/** @deprecated This component has been renamed to LoaderError. */\nconst LoaderError = QueryBoundaryFallback;\n\nexport default LoaderError;\n","import type {\n QueryBoundaryContextValue,\n QueryBoundaryProviderBaseProps,\n QueryBoundaryProviderProps,\n QueryBoundaryProviderPropsWithError,\n QueryBoundaryProviderPropsWithNoError,\n} from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nimport QueryBoundaryProvider, {\n useQueryBoundary,\n} from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderBaseProps. */\nexport type LoaderProviderBaseProps<DataType> = QueryBoundaryProviderBaseProps<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderPropsWithNoError. */\nexport type LoaderProviderPropsWithNoError<DataType> =\n QueryBoundaryProviderPropsWithNoError<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderPropsWithError. */\nexport type LoaderProviderPropsWithError<DataType> = QueryBoundaryProviderPropsWithError<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryContextValue. */\nexport type LoaderContextValue<DataType> = QueryBoundaryContextValue<DataType>;\n/** @deprecated This type has been renamed to QueryBoundaryProviderProps. */\nexport type LoaderProviderProps<DataType> = QueryBoundaryProviderProps<DataType>;\n\n/** @deprecated This hook has been renamed to useQueryBoundary */\nexport const useLoader = useQueryBoundary;\n\n/** @deprecated This component has been renamed to QueryBoundaryProvider */\nconst LoaderProvider = QueryBoundaryProvider;\n\nexport default LoaderProvider;\n","import type { JSX, ReactNode } from \"react\";\n\nimport BottomNavigation from \"@mui/material/BottomNavigation\";\nimport BottomNavigationAction from \"@mui/material/BottomNavigationAction\";\nimport Box from \"@mui/material/Box\";\nimport Paper from \"@mui/material/Paper\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\n\nexport interface NavItemBottom {\n /** The value associated with the nav item. */\n value: string;\n /** The label to display on the nav item. */\n label: string;\n /** An icon to display alongside the nav item. */\n icon?: JSX.Element;\n /** Where in your app the nav item should navigate to. */\n to: string;\n}\n\nexport interface NavigationBottomProps {\n /** Children to display above the nav bar. */\n children: ReactNode;\n /** An array of nav items to show. */\n navItems: Array<NavItemBottom>;\n}\n\n/**\n * Renders a navigation bar at the bottom of the screen. Especially helpful for common navigation options in a mobile app.\n *\n * @deprecated Please use `NavigationBottom` from the `@alextheman/components/v7` entrypoint instead.\n */\nfunction NavigationBottom({ children, navItems }: NavigationBottomProps) {\n const [value, setValue] = useState<string>(\"\");\n return (\n <>\n <Box sx={{ paddingBottom: 7 }}>{children}</Box>\n <Paper sx={{ position: \"fixed\", bottom: 0, left: 0, right: 0 }}>\n <BottomNavigation\n showLabels\n value={value}\n onChange={(_, value) => {\n setValue(value);\n }}\n >\n {navItems.map((item) => {\n return <BottomNavigationAction key={item.value} {...item} component={Link} />;\n })}\n </BottomNavigation>\n </Paper>\n </>\n );\n}\n\nexport default NavigationBottom;\n","import type { AppBarProps as MuiAppBarProps } from \"@mui/material/AppBar\";\nimport type { CSSObject, Theme } from \"@mui/material/styles\";\nimport type { ReactNode } from \"react\";\n\nimport { truncate } from \"@alextheman/utility\";\nimport MuiAppBar from \"@mui/material/AppBar\";\nimport Box from \"@mui/material/Box\";\nimport CssBaseline from \"@mui/material/CssBaseline\";\nimport Divider from \"@mui/material/Divider\";\nimport MuiDrawer from \"@mui/material/Drawer\";\nimport IconButton from \"@mui/material/IconButton\";\nimport List from \"@mui/material/List\";\nimport ListItem from \"@mui/material/ListItem\";\nimport ListItemButton from \"@mui/material/ListItemButton\";\nimport ListItemIcon from \"@mui/material/ListItemIcon\";\nimport ListItemText from \"@mui/material/ListItemText\";\nimport { styled, useTheme } from \"@mui/material/styles\";\nimport Toolbar from \"@mui/material/Toolbar\";\nimport Typography from \"@mui/material/Typography\";\nimport { Fragment, useState } from \"react\";\nimport { MdChevronLeft, MdChevronRight, MdMenu } from \"react-icons/md\";\nimport { Link, useLocation } from \"react-router-dom\";\n\nconst drawerWidth = 240;\n\nfunction openedMixin(theme: Theme): CSSObject {\n return {\n width: drawerWidth,\n transition: theme.transitions.create(\"width\", {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.enteringScreen,\n }),\n overflowX: \"hidden\",\n };\n}\n\nfunction closedMixin(theme: Theme): CSSObject {\n return {\n transition: theme.transitions.create(\"width\", {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n overflowX: \"hidden\",\n width: `calc(${theme.spacing(7)} + 1px)`,\n [theme.breakpoints.up(\"sm\")]: {\n width: `calc(${theme.spacing(8)} + 1px)`,\n },\n };\n}\n\nconst DrawerHeader = styled(\"div\")(({ theme }) => {\n return {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n padding: theme.spacing(0, 1),\n // necessary for content to be below app bar\n ...theme.mixins.toolbar,\n };\n});\n\ninterface AppBarProps extends MuiAppBarProps {\n open?: boolean;\n}\n\nconst AppBar = styled(MuiAppBar, {\n shouldForwardProp: (prop) => {\n return prop !== \"open\";\n },\n})<AppBarProps>(({ theme }) => {\n return {\n zIndex: theme.zIndex.drawer + 1,\n transition: theme.transitions.create([\"width\", \"margin\"], {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n variants: [\n {\n props: ({ open }) => {\n return open;\n },\n style: {\n marginLeft: drawerWidth,\n width: `calc(100% - ${drawerWidth}px)`,\n transition: theme.transitions.create([\"width\", \"margin\"], {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.enteringScreen,\n }),\n },\n },\n ],\n };\n});\n\nconst Drawer = styled(MuiDrawer, {\n shouldForwardProp: (prop) => {\n return prop !== \"open\";\n },\n})(({ theme }) => {\n return {\n width: drawerWidth,\n flexShrink: 0,\n whiteSpace: \"nowrap\",\n boxSizing: \"border-box\",\n variants: [\n {\n props: ({ open }) => {\n return open;\n },\n style: {\n ...openedMixin(theme),\n \"& .MuiDrawer-paper\": openedMixin(theme),\n },\n },\n {\n props: ({ open }) => {\n return !open;\n },\n style: {\n ...closedMixin(theme),\n \"& .MuiDrawer-paper\": closedMixin(theme),\n },\n },\n ],\n };\n});\n\nexport interface NavMenuItemOptions {\n /** The label to display on the nav item option. */\n label: string;\n /** Where in your app the nav item option should navigate to. */\n to: string;\n /** An icon to display alongside the nav item option. */\n icon?: ReactNode;\n}\n\nexport interface NavMenuItem {\n /** The category to display all the nav item options under. */\n category: string;\n /** An array of nav options to display under the chosen category. */\n options: Array<NavMenuItemOptions>;\n}\n\nexport interface NavigationDrawerProps {\n /** The title to display at the top of the wrapper. */\n title: string;\n /** An array of nav items to show. */\n navItems: Array<NavMenuItem>;\n /** Any extra elements to add to the header. */\n headerElements?: ReactNode;\n /** Children to display within the wrapper. */\n children: ReactNode;\n}\n\n/**\n * Renders a collapsable drawer to help with navigation. Best used as the main means of navigation on desktop apps.\n *\n * @deprecated This component is not compatible with the rest of the Wouter setup for use in v7. Please use `NavigationDrawer` from `@alextheman/components/v7` instead. This component will be replaced when v7 officially comes out.\n */\nfunction NavigationDrawer({ title, navItems, children, headerElements }: NavigationDrawerProps) {\n const theme = useTheme();\n const [open, setOpen] = useState(true);\n const location = useLocation();\n\n function handleDrawerOpen() {\n setOpen(true);\n }\n\n function handleDrawerClose() {\n setOpen(false);\n }\n\n return (\n <Box sx={{ display: \"flex\" }}>\n <CssBaseline />\n <AppBar position=\"fixed\" open={open}>\n <Toolbar>\n <IconButton\n color=\"inherit\"\n aria-label=\"open drawer\"\n onClick={handleDrawerOpen}\n edge=\"start\"\n sx={[\n {\n marginRight: 5,\n },\n open && { display: \"none\" },\n ]}\n >\n <MdMenu />\n </IconButton>\n <Typography variant=\"h6\" noWrap component=\"div\">\n {title}\n </Typography>\n {headerElements}\n </Toolbar>\n </AppBar>\n <Drawer variant=\"permanent\" open={open}>\n <DrawerHeader>\n <IconButton onClick={handleDrawerClose}>\n {theme.direction === \"rtl\" ? <MdChevronRight /> : <MdChevronLeft />}\n </IconButton>\n </DrawerHeader>\n <Divider />\n {navItems.map((item) => {\n return (\n <Fragment key={item.category}>\n <List>\n <Typography variant={open ? \"h5\" : \"h6\"} sx={{ paddingLeft: open ? 2 : 1 }}>\n {open ? item.category : truncate(item.category, 4)}\n </Typography>\n {item.options.map((option) => {\n return (\n <ListItem key={option.to} disablePadding sx={{ display: \"block\" }}>\n <ListItemButton\n sx={[\n {\n minHeight: 48,\n px: 2.5,\n },\n open\n ? {\n justifyContent: \"initial\",\n }\n : {\n justifyContent: \"center\",\n },\n ]}\n component={Link}\n to={option.to}\n selected={location.pathname === option.to}\n >\n <ListItemIcon\n sx={[\n {\n minWidth: 0,\n justifyContent: \"center\",\n },\n open\n ? {\n mr: 3,\n }\n : {\n mr: \"auto\",\n },\n ]}\n >\n {option.icon ? (\n option.icon\n ) : !open ? (\n <Typography>{truncate(option.label, 4)}</Typography>\n ) : null}\n </ListItemIcon>\n <ListItemText\n primary={option.label}\n sx={[\n open\n ? {\n opacity: 1,\n }\n : {\n opacity: 0,\n },\n ]}\n />\n </ListItemButton>\n </ListItem>\n );\n })}\n </List>\n <Divider />\n </Fragment>\n );\n })}\n </Drawer>\n <Box component=\"main\" sx={{ flexGrow: 1, p: 3 }}>\n <DrawerHeader />\n {children}\n </Box>\n </Box>\n );\n}\n\nexport default NavigationDrawer;\n","import type { TypographyProps } from \"@mui/material/Typography\";\n\nimport Typography from \"@mui/material/Typography\";\n\nexport interface PopoverTextProps extends TypographyProps {\n text: string;\n}\n\n/**\n * @deprecated This component has been deprecated alongside `IconWithPopover`.\n */\nfunction PopoverText({ text, sx, ...typographyProps }: PopoverTextProps) {\n return (\n <>\n {text.split(\"\\n\").map((line, index) => {\n return (\n <Typography key={index} sx={{ margin: 1, ...sx }} {...typographyProps}>\n {line}\n </Typography>\n );\n })}\n </>\n );\n}\n\nexport default PopoverText;\n","import type { QueryBoundaryWrapperProps } from \"src/components/QueryBoundaryWrapper\";\n\nimport QueryBoundaryWrapper from \"src/components/QueryBoundaryWrapper\";\n\n/** @deprecated This type has been renamed to `QueryBoundaryWrapperProps`. */\nexport type QueryBoundaryProps<DataType> = QueryBoundaryWrapperProps<DataType>;\n\n/** @deprecated This component has been renamed to `QueryBoundaryWrapper` */\nconst QueryBoundary = QueryBoundaryWrapper;\n\nexport default QueryBoundary;\n","import type { ButtonProps } from \"@mui/material/Button\";\n\nimport Button from \"@mui/material/Button\";\nimport { useFormContext } from \"react-hook-form\";\n\nexport interface SubmitButtonProps extends Omit<ButtonProps, \"type\"> {\n /** An option to disable the button on submit if the form is not dirty. */\n disableClean?: boolean;\n /** The label for the button. */\n label: string;\n}\n\n/**\n * A Submit Button for use with `react-hook-form`.\n *\n * @deprecated This component is not compatible with `@tanstack/react-form`. Please use `SubmitButton` from the `@alextheman/components/v7` entrypoint instead. This component will be replaced when v7 officially comes out.\n */\nfunction SubmitButton({ disableClean, label, ...buttonProps }: SubmitButtonProps) {\n const {\n formState: { disabled: formDisabled, isDirty, isSubmitting },\n } = useFormContext();\n\n return (\n <Button\n color=\"primary\"\n disabled={buttonProps.disabled || (disableClean && !isDirty) || formDisabled}\n loading={isSubmitting}\n type=\"submit\"\n variant=\"contained\"\n {...buttonProps}\n >\n {label}\n </Button>\n );\n}\n\nexport default SubmitButton;\n","import { useEffect, useState } from \"react\";\n\n/**\n * Assign a variable a given value after a given amount of milliseconds.\n *\n * @template ValueType The type of the value to set.\n *\n * @param value - The value to assign.\n * @param delay - The amount of milliseconds to wait before assigning the value.\n *\n * @returns The input value after a given number of seconds.\n */\nfunction useDebounce<ValueType>(value: ValueType, delay: number = 500): ValueType {\n const [debouncedValue, setDebouncedValue] = useState<ValueType>(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n\nexport default useDebounce;\n","import type { Dispatch, SetStateAction } from \"react\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Stores changes to the window hash as React state.\n *\n * @template StateType - The type of the hash state.\n *\n * @param initialHash - The initial value of the hash.\n *\n * @returns A tuple containing the hash state, and a updater function to set the hash state.\n */\nfunction useHash<StateType extends string>(\n initialHash: StateType | undefined,\n): [StateType, Dispatch<SetStateAction<StateType>>] {\n const [hash, setHash] = useState<StateType>(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n return !initialHash ? hash : hash === \"\" ? initialHash : hash;\n });\n const hashChangeHandler = useCallback(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n setHash(!initialHash ? hash : hash === \"\" ? initialHash : hash);\n }, [setHash, initialHash]);\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", hashChangeHandler);\n return () => {\n window.removeEventListener(\"hashchange\", hashChangeHandler);\n };\n }, [hashChangeHandler]);\n\n const updateHash = useCallback(\n (newHash: StateType | ((previousState: StateType) => StateType)) => {\n const resolvedHash = typeof newHash === \"function\" ? newHash(hash) : newHash;\n if (resolvedHash !== hash) {\n window.location.hash = resolvedHash;\n }\n },\n [hash],\n );\n\n return [hash, updateHash];\n}\n\nexport default useHash;\n"],"mappings":"0xEAcA,SAAS,GAAU,CAAE,iBAAgB,cAA8B,CACjE,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,IACR,gBAAiB,yBACjB,eAAgB,YAChB,OAAQ,mCACR,UAAW,8BACb,WAEA,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAY,QAAQ,KAAK,aAAA,GAAa,GAAI,CAAE,MAAO,SAAU,WAC1D,CACS,CAAA,EAEZ,EAAC,EAAD,CAAO,QAAS,WACb,EAAW,IAAK,GAEb,EAAC,EAAD,CAES,QACP,GAAI,CACF,gBAAiB,yBACjB,MAAO,yBACP,OAAQ,kCACV,CACD,EAPM,CAON,CAEJ,CACI,CAAA,CACI,CAAA,CAAA,CACT,CAAA,CAEV,CAEA,SAAS,IAAY,CACnB,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,EACR,aAAc,EACd,WAAY,oDACZ,UAAW,iCACb,CACD,CAAA,CAEL,CAGA,SAAS,IAAU,CACjB,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,IACR,QAAS,OACT,cAAe,SACf,eAAgB,gBAChB,EAAG,EACH,WACE,+KACF,MAAO,OACT,EACA,UAAW,WAZb,CAcE,EAAC,EAAD,CACE,MAAM,6BACN,GAAI,CACF,MAAO,UACP,UAAW,SACX,yBAA0B,CACxB,SAAU,GACV,WAAY,IACZ,cAAe,CACjB,CACF,CACD,CAAA,EAED,EAAC,EAAD,CAAS,GAAI,CAAE,YAAa,uBAAwB,CAAI,CAAA,EAExD,EAAC,EAAD,CAAa,GAAI,CAAE,KAAM,EAAG,QAAS,OAAQ,WAAY,QAAS,WAChE,EAAC,EAAD,CACE,UAAU,MACV,QAAS,EACT,GAAI,CAAE,MAAO,OAAQ,eAAgB,SAAU,WAAY,QAAS,WAHtE,CAKE,EAAC,GAAD,CACE,eAAe,MACf,WAAY,CAAC,QAAS,UAAW,QAAS,QAAS,QAAS,QAAS,SAAS,CAC/E,CAAA,EACD,EAAC,GAAD,CAAY,CAAA,EACZ,EAAC,GAAD,CACE,eAAe,IACf,WAAY,CAAC,SAAU,SAAU,WAAY,SAAU,UAAW,SAAU,UAAU,CACvF,CAAA,CACI,GACI,CAAA,CACT,GAEV,CCzEA,SAAS,GAAgB,CACvB,kBACA,SACA,UACA,WACA,eACA,iBACA,gBAAiB,EAAkB,EACnC,gBACA,WAAW,EAAC,GAAD,CAAgB,CAAA,EAC3B,aAAa,EAAC,EAAD,CAAkB,CAAA,EAC/B,oBAAoB,IAAoB,GACjB,CACvB,GAAM,CAAC,EAAY,GAAiB,EAAkB,CAAC,CAAC,CAAe,EAUvE,OARA,MAAgB,CACV,GAAc,EAChB,EAAO,EACE,CAAC,GAAc,GACxB,EAAQ,CAEZ,EAAG,CAAC,EAAY,EAAQ,CAAO,CAAC,EAG9B,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,YAAe,CACb,EAAe,GACN,CAAC,CACT,CACH,EACA,GACE,EACI,CACE,MAAO,OACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,SAAU,IACV,SAAU,EACV,UAAW,SACX,UACE,IAAoB,EAAa,CAAE,gBAAiB,cAAe,EAAI,KACzE,GAAG,CACL,EACA,EAEN,gBAAe,WAtBjB,CAwBG,EACA,EAAa,EAAW,CACV,IACjB,EAAC,EAAD,CAAU,GAAI,EAAY,GAAI,EAC3B,UACO,CAAA,CACP,CAAA,CAAA,CAET,CChFA,SAAS,GAAa,CAAE,OAAM,WAAU,MAAK,GAAG,GAAgC,CAC9E,OACE,EAAC,EAAD,CACE,UAAU,IACJ,OACD,MACL,OAAO,SACP,IAAI,sBACJ,GAAI,EAEH,UACM,CAAA,CAEb,CCzBA,MAAa,GAAW,CACtB,IAAK,kBACL,IAAK,YACL,KAAM,aACN,IAAK,YACL,KAAM,oEACN,KAAM,0EACN,IAAK,YACL,IAAK,YACL,IAAK,WACP,EAGM,GAAsB,EAAO,OAAO,EAAE,CAC1C,KAAM,gBACN,SAAU,aACV,OAAQ,EACR,SAAU,SACV,SAAU,WACV,OAAQ,EACR,KAAM,EACN,WAAY,SACZ,MAAO,CACT,CAAC,EAEK,GAAW,EAAO,KAAK,GAA2B,CAAE,QAAO,gBACxD,CACL,OAAQ,aACR,YAAa,EAAY,EAAM,QAAQ,QAAQ,KAAO,OACtD,gBAAiB,EAAY,EAAM,QAAQ,OAAO,MAAQ,cAC1D,aAAc,EACd,QAAS,SACT,UAAW,SACX,WAAY,oBACZ,OAAQ,SACV,EACD,EAgBD,SAAS,GAAU,CACjB,cACA,QAAQ,eACR,WACA,SACA,cACA,GAAG,GACc,CACjB,GAAM,CAAC,EAAY,GAAiB,EAAkB,EAAK,EACrD,EAAK,EAAM,EAEX,EACJ,EAACA,EAAD,CACE,QAAQ,YACR,UAAU,QACV,aAAW,oBACX,UAAY,GAAU,EAChB,EAAM,MAAQ,SAAW,EAAM,MAAQ,OACzC,EAAM,eAAe,EACrB,SAAS,eAAe,CAAE,GAAG,MAAM,EAEvC,EACA,GAAI,EACJ,UAAW,EAAY,WAAa,EAAC,GAAD,CAAgB,CAAA,WAXtD,CAaG,EACD,EAAC,GAAD,CACM,KACJ,KAAK,OACL,SAAW,GAAU,CACnB,IAAM,EAAQ,EAAM,OACpB,EAAY,MAAM,KAAK,EAAM,OAAS,CAAC,CAAC,CAAC,EACzC,EAAM,MAAQ,EAChB,EACU,WACV,OAAQ,GAAQ,KAAK,GAAG,EACxB,SAAU,EAAY,QACvB,CAAA,CACK,IAGV,OAAO,EACL,EAAC,GAAD,CACE,UAAW,EACX,WAAa,GAAU,CACrB,EAAM,eAAe,EACjB,GAAY,UAGhB,EAAc,EAAI,CACpB,EACA,YAAc,GAAU,CACtB,EAAM,eAAe,EACrB,EAAc,EAAK,CACrB,EACA,OAAS,GAAU,CACjB,EAAM,eAAe,EACrB,EAAc,EAAK,EACf,GAAY,UAIhB,EADmB,MAAM,KAAK,EAAM,aAAa,OAAS,CAAC,CACtC,CAAC,CACxB,WAEC,CACO,CAAA,EAEV,CAEJ,CC7GA,SAAS,GAAc,CACrB,QACA,WACA,WAAW,GACX,GAAG,GACkB,CACrB,SAAS,EAAY,EAAuB,CAC1C,EAAU,GACD,CAAC,GAAG,EAAU,GAAG,CAAQ,CACjC,CACH,CAEA,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,GAAD,CAAW,GAAI,EAA0B,WAAuB,aAAc,CAAA,EAC9E,EAAC,GAAD,CAAA,SACG,EAAM,IAAK,GAER,EAAC,GAAD,CAEE,gBACE,EAAC,EAAD,CACE,aAAW,SACX,KAAK,MACL,YAAe,CACb,EAAU,GACD,EAAS,OAAQ,GACf,IAAiB,CACzB,CACF,CACH,WAEA,EAAC,GAAD,CAAW,CAAA,CACD,CAAA,WAGd,EAAC,GAAD,CAAc,QAAS,EAAK,IAAO,CAAA,CAC3B,EAlBH,GAAG,EAAK,KAAK,GAAG,EAAK,cAkBlB,CAEb,CACG,CAAA,CACH,CAAA,CAAA,CAET,CC7CA,MAAM,GAAe,EAAO,EAAM,OACzB,CACL,QAAS,EACT,qBAAsB,CACpB,aAAc,GACd,sBAAuB,CACrB,QAAS,KACT,SAAU,WACV,IAAK,MACL,UAAW,mBACX,SAAU,GACV,MAAO,GACP,OAAQ,EACV,CACF,CACF,EACD,EAGD,SAAS,GAAgB,CACvB,YAAa,EACb,oBACA,cAAe,EACf,sBACA,GAAG,GACoB,CACvB,IAAM,EAAQ,CACZ,aAAc,MACd,YAAa,QACb,gBAAiB,QACjB,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,QAAS,GACX,EACM,EAAoB,CAAE,MAAO,QAAS,SAAU,KAAM,UAAW,IAAK,EAC5E,OACE,EAAC,GAAD,CACE,YACE,EAAC,EAAD,CAAK,GAAI,WACP,EAAC,EAAD,CAAa,MAAO,CAAE,GAAG,EAAmB,GAAG,CAAkB,CAAI,CAAA,CAClE,CAAA,EAEP,KACE,EAAC,EAAD,CAAK,GAAI,WACP,EAAC,EAAD,CAAe,MAAO,CAAE,GAAG,EAAmB,GAAG,CAAoB,CAAI,CAAA,CACtE,CAAA,EAEP,GAAI,CACL,CAAA,CAEL,CC9CA,MAAM,EAAe,EAA6C,IAAA,EAAS,EAG3E,SAAgB,EAA+C,CAC7D,SAAS,IACqB,CAAC,EAAmD,CAClF,IAAM,EAAU,EAAI,CAAY,EAChC,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,2BACA,mFACF,EAEF,OAAO,CACT,CAGA,SAAS,GAAc,CAAE,SAAQ,YAAgC,CAC/D,GAAM,CAAC,EAAc,GAAmB,EAAoB,EAAO,EAAE,EAErE,OAAO,EAAC,EAAD,CAAc,MAAO,CAAE,SAAQ,eAAc,iBAAgB,EAAI,UAAuB,CAAA,CACjG,CC3CA,SAAS,IAAgB,CACvB,GAAM,CAAE,gBAAiB,EAAgB,EAEzC,OACE,EAAC,QAAD,CAAO,IAAK,EAAa,IAAK,SAAA,YAC5B,EAAC,QAAD,CAAO,KAAK,UAAY,CAAA,CACnB,CAAA,CAEX,CCKA,MAAM,EAAc,EAAgC,CAClD,eAAkB,CAAC,EACnB,KAAM,MACR,CAAC,EAGD,SAAgB,EAAuC,CACrD,SAAS,IACqB,CAAC,EAAkD,CACjF,IAAM,EAAU,EAAI,CAAW,EAC/B,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,0BACA,kFACF,EAEF,OAAO,CACT,CAUA,SAAS,GAAa,CAAE,WAAU,KAAM,EAAW,QAA6B,CAC9E,GAAM,CAAC,EAAM,GAAW,EAAsB,CAAQ,EAEhD,EAAQ,MACL,GAAY,CACjB,QAAS,CACP,MACF,EACA,WAAY,CACV,SAAU,CACR,eAAgB,CACd,MAAO,CAAE,YACA,CACL,OAAQ,EACR,YAAa,QACb,YAAa,EAAM,QAAQ,OAC7B,EAEJ,CACF,CACF,CACF,CAAC,EACA,CAAC,CAAI,CAAC,EAET,OACE,EAAC,EAAD,CACE,MAAO,CACL,OACA,eAAkB,CAChB,EAAS,GACA,IAAS,QAAU,OAAS,OACpC,CACH,CACF,WAEA,EAAC,GAAD,CAAsB,iBAAtB,CACE,EAAC,EAAD,CAAc,CAAA,EACb,CACY,GACJ,CAAA,CAEjB,CCxDA,MAAM,EAAoB,EAAsC,CAC9D,YAAa,EACb,aAAc,EACd,cAAe,EACjB,CAAC,EAGD,SAAgB,GAA6C,CAC3D,SAAS,IACqB,CAAC,EAAwD,CACvF,IAAM,EAAU,EAAI,CAAiB,EACrC,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,iCACA,wFACF,EAEF,OAAO,CACT,CAEA,IAAI,EAA+B,CACjC,YAAa,OAAO,WACpB,aAAc,OAAO,WACvB,EAEA,SAAS,IAAkC,CACzC,OAAO,CACT,CAEA,SAAS,GAAU,EAAsB,CACvC,SAAS,GAAe,CACtB,EAAa,CACX,YAAa,OAAO,WACpB,aAAc,OAAO,WACvB,EAEA,EAAS,CACX,CAEA,OADA,OAAO,iBAAiB,SAAU,CAAY,MACjC,CACX,OAAO,oBAAoB,SAAU,CAAY,CACnD,CACF,CAGA,SAAS,GAAmB,CAC1B,WACA,mBAAmB,IACnB,oBAAoB,KACF,CAClB,GAAM,CAAE,cAAa,gBAAiB,GACpC,GACA,EACF,EAMA,OACE,EAAC,EAAD,CACE,MAAO,CACL,cAPgB,MACb,EAAc,GAAoB,EAAe,EACvD,CAAC,EAAa,EAAc,EAAkB,CAAiB,CAKhD,EACZ,cACA,cACF,EAEC,UACgB,CAAA,CAEvB,CC5EA,MAAM,EAAkB,EAAgD,IAAA,EAAS,EAGjF,SAAgB,GAA2C,CACzD,SAAS,IACqB,CAAC,EAAsD,CACrF,IAAM,EAAU,EAAI,CAAe,EACnC,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,8BACA,sFACF,EAEF,OAAO,CACT,CAGA,SAAS,GAAiB,CAAE,WAAU,mBAAmB,KAA+B,CACtF,GAAM,CAAC,EAAM,GAAW,EAAkB,EAAK,EACzC,CAAC,EAAuB,GAA4B,EAAiB,CAAgB,EACrF,CAAC,EAAS,GAAc,EAAiB,EAAE,EAC3C,CAAC,EAAU,GAAe,EAAqB,MAAM,EAE3D,SAAS,EAAY,EAAiB,EAAuB,EAAmB,CAC9E,EAAQ,EAAI,EACZ,EAAyB,GAAY,CAAgB,EACrD,EAAY,GAAY,MAAM,EAC9B,EAAW,CAAO,CACpB,CAEA,eAAe,GAAc,CAC3B,EAAQ,EAAK,EAGb,MAAM,GAAK,EAAG,EACd,EAAW,EAAE,CACf,CAEA,OACE,EAAC,EAAD,CAAiB,MAAO,CAAE,aAAY,WAAtC,CACE,EAAC,GAAD,CAAgB,OAAM,iBAAkB,EAAuB,QAAS,WACtE,EAAC,GAAD,CAAO,QAAS,EAAuB,oBACpC,CACI,CAAA,CACC,CAAA,EACT,CACc,GAErB,CClEA,SAAS,GAAa,CACpB,GAAM,CAAE,OAAM,cAAe,EAAQ,EAC/B,EAAa,IAAS,OACtB,EAAW,UAAU,EAAa,QAAU,OAAO,OAEzD,OACE,EAAC,GAAD,CAAS,MAAO,WACd,EAAC,GAAD,CACE,cAAe,GACf,YAAa,GACb,QAAS,EACT,SAAU,EACV,aAAY,CACb,CAAA,CACM,CAAA,CAEb,CCCA,SAAS,GAAK,CAAE,QAAO,WAAU,SAAQ,WAAU,OAAM,kBAA6B,CACpF,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,MACE,EAAA,EAAA,CAAA,SAAA,CACG,OAAO,GAAU,SAAW,EAAC,EAAD,CAAY,QAAQ,cAAM,CAAkB,CAAA,EAAI,EAC5E,EACC,OAAO,GAAa,SAClB,EAAC,EAAD,CAAY,QAAQ,QAAQ,MAAM,0BAC/B,CACS,CAAA,EAEZ,EAEA,IACJ,CAAA,CAAA,EAEI,QACT,CAAA,EACA,EACD,EAAC,EAAD,CAAU,CAAA,EACT,EAAiB,EAAW,EAAC,EAAD,CAAc,UAAsB,CAAA,CAC7D,CAAA,CAAA,CAEV,CCHA,MAAM,EAAuB,EAC3B,IAAA,EACF,EAGA,SAAgB,EAA0D,CACxE,SAAS,IACqB,CAAC,EAG/B,CACA,IAAM,EAAU,EAAI,CAAoB,EACxC,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,oCACA,2FACF,EAEF,OAAO,CACT,CAQA,SAAS,EAAgC,CACvC,WACA,mBAAmB,EAAC,GAAD,CAAmB,CAAA,EACtC,GAAG,GACoC,CACvC,OACE,EAAC,EAAD,CAAsB,MAAO,CAAE,mBAAkB,GAAG,CAAa,EAC9D,UACmB,CAAA,CAE1B,CCnEA,SAAS,EAAmB,CAAE,WAAU,SAAU,GAA0C,CAC1F,GAAM,CACJ,OACA,QACA,eAAgB,EAChB,SAAU,GACR,EAAiB,EACf,EAAW,GAAiB,EAC5B,EAAgB,GAAO,EAAK,EAE5B,EAAiB,GAAY,EA8BnC,OA5BI,GACE,GAAY,CAAC,EAAc,UACzB,GAAS,KAMX,QAAQ,MAAM,CAAK,EALnB,QAAQ,MACN,6FACA,CAAE,OAAM,OAAM,CAChB,EAIF,EAAc,QAAU,IAEtB,OAAO,GAAmB,WACrB,EAAe,CAAK,EAEzB,IAAmB,IAAA,GAKrB,EAAC,GAAD,CAAO,SAAS,iBACb,OAAO,GAAU,UAAY,YAAa,GAAS,OAAO,EAAM,SAAY,SACzE,EAAM,QACN,+BACC,CAAA,EARA,EAAA,EAAA,CAAA,SAAG,CAAiB,CAAA,GAYxB,IACT,CChCA,SAAS,EAAsB,CAC7B,qBACA,gBACA,qBAC6B,CAC7B,GAAM,CAAE,YAAW,OAAM,SAAU,EAAiB,EAMpD,GAJI,GAIA,EACF,OAAO,KAGT,GAAI,GAAS,KAA4B,CACvC,GAAI,IAAsB,IAAA,GACxB,OAAO,EAAA,EAAA,CAAA,SAAG,CAAoB,CAAA,EAGhC,GAAI,IAAS,IAAA,GAIX,OAHI,IAAuB,IAAA,GAGpB,EAAC,EAAD,CAAA,SAAY,oBAA8B,CAAA,EAFxC,EAAA,EAAA,CAAA,SAAG,CAAqB,CAAA,EAKnC,GAAI,IAAS,KAIX,OAHI,IAAkB,IAAA,GAGf,EAAC,EAAD,CAAA,SAAY,gBAA0B,CAAA,EAFpC,EAAA,EAAA,CAAA,SAAG,CAAgB,CAAA,CAIhC,CAEA,OAAO,IACT,CC9CA,SAAS,EAAsB,CAC7B,iBACA,WACA,GAAG,GAC0B,CAC7B,OACE,EAAA,EAAA,CAAA,SAAA,CACE,EAAC,EAAD,CAA8B,oBAAW,CAAmC,CAAA,EAC5E,EAAC,EAAD,CAAuB,GAAI,CAA6B,CAAA,CACxD,CAAA,CAAA,CAEN,CCCA,SAAS,EAAkC,CACzC,SACkF,CAClF,MAAO,CACL,SAAU,CAAE,cAER,EAAC,EAAD,CAAuB,UAAW,EAAM,UAAW,MAAO,EAAM,MAAO,KAAM,EAAM,KAChF,UACoB,CAAA,EAG3B,MAAO,EACP,SAAU,EACV,SAAU,CACZ,CACF,CCuBA,SAAS,EAA+B,CACtC,WACA,iBAAkB,EAClB,UACA,aACA,WAAY,EACZ,iBAAiB,EAAC,EAAD,CAAA,SAAY,iBAA2B,CAAA,EACxD,uBAAuB,IACe,CACtC,GAAM,CACJ,YACA,OACA,WAAY,EACZ,iBAAkB,EAClB,SACE,EAAkC,EAEhC,EAAa,GAAkB,EAC/B,EAAmB,GAAwB,EAEjD,GAAI,EACF,OAAO,EAAA,EAAA,CAAA,SAAG,CAAmB,CAAA,EAO/B,GAJI,GAIA,GAAS,KACX,OAAO,KAGT,GAAI,CAAC,MAAM,QAAQ,CAAI,EAAG,CACxB,GAAI,EACF,MAAM,IAAI,EACR,CAAE,OAAM,sBAAqB,EAC7B,eACA,2DACF,EAEF,OAAO,IACT,CAEA,GAAI,EAAK,SAAW,EAClB,OAAO,EAAA,EAAA,CAAA,SAAG,CAAiB,CAAA,EAG7B,IAAI,EAUJ,MARA,CAKE,EALE,EACM,EAAW,CAAI,EACd,EACD,EAAK,IAAI,CAAU,EAEnB,EAIR,EAAA,EAAA,CAAA,SACG,EAAM,KAAK,EAAM,IAEd,EAACC,EAAD,CAAA,SACG,OAAO,GAAa,WAAa,EAAS,CAAI,EAAI,CAC3C,EAFK,EAAU,EAAQ,EAAM,CAAK,EAAI,CAEtC,CAEb,CACD,CAAA,CAEN,CC9GA,SAAS,GAAkC,CACzC,SAC4F,CAG5F,MAAO,CACL,GAHqB,EAAwB,CAAE,OAAM,CAGrC,EAChB,QAAS,CACX,CACF,CCZA,SAAS,GAA2B,CAClC,mBACA,qBACA,gBACA,oBACA,WACA,iBACA,WACA,YACA,QACA,OACA,aACA,aACA,WACkC,CAClC,IAAM,EAAgB,GAAwB,CAAE,MAAO,CAAE,YAAW,QAAO,MAAK,CAAE,CAAC,EAE/E,EACF,EAAC,EAAc,SAAf,CAAkC,WAA0B,gBAAiB,CAAA,EAG3E,EACF,EACE,EAAC,EAAc,SAAf,CACqB,oBACT,WACM,gBACjB,CAAA,GAEM,GAAsB,KAC/B,EACE,EAAC,EAAc,SAAf,CACsB,qBACL,gBACL,WACM,gBACjB,CAAA,GAIL,IAAI,EACF,EAAC,EAAc,QAAf,CAAyC,mBAA2B,UACjE,UACoB,CAAA,EAyBzB,OAtBI,EACF,EACE,EAAC,EAAc,QAAf,CACoB,mBACT,UACG,aAEX,UACoB,CAAA,EAEhB,IACT,EACE,EAAC,EAAc,QAAf,CACoB,mBACT,UACG,aAEX,UACoB,CAAA,GAKzB,EAAC,EAAc,QAAf,CAAA,SAAA,CACG,EACA,CACoB,CAAA,CAAA,CAE3B,CC1EA,SAAS,EAA4B,CACnC,WACA,WAAY,EACZ,oBACmC,CACnC,GAAM,CACJ,YACA,OACA,WAAY,EACZ,iBAAkB,EAClB,SACE,EAA2B,EACzB,EAAa,GAAkB,EAcrC,OAZI,EACK,KAGL,EACK,EAAA,EAAA,CAAA,SAAG,GAAoB,CAA0B,CAAA,EAGtD,GAAS,KACJ,KAIP,EAAA,EAAA,CAAA,SACG,OAAO,GAAa,WAAa,EAAS,EAAa,EAAW,CAAI,EAAI,CAAI,EAAI,CACnF,CAAA,CAEN,CC5BA,SAAS,GAAkC,CACzC,SAC4F,CAG5F,MAAO,CACL,GAHqB,EAAwB,CAAE,OAAM,CAGrC,EAChB,KAAM,CACR,CACF,CCXA,SAAS,EAA+B,CACtC,WACA,iBACA,qBACA,gBACA,oBACA,WACA,mBAAmB,EAAC,GAAD,CAAmB,CAAA,EACtC,YACA,QACA,OACA,cACsC,CACtC,IAAM,EAAgB,GAAwB,CAAE,MAAO,CAAE,YAAW,QAAO,MAAK,CAAE,CAAC,EAE/E,EACF,EAAC,EAAc,SAAf,CAAkC,WAA0B,gBAAiB,CAAA,EAsB/E,OAnBI,EACF,EACE,EAAC,EAAc,SAAf,CACqB,oBACT,WACM,gBACjB,CAAA,GAEM,GAAsB,KAC/B,EACE,EAAC,EAAc,SAAf,CACsB,qBACL,gBACL,WACM,gBACjB,CAAA,GAKH,EAAC,EAAc,QAAf,CAAA,SAAA,CACG,EACD,EAAC,EAAc,KAAf,CAAsC,mBAA8B,aACjE,UACiB,CAAA,CACC,CAAA,CAAA,CAE3B,CCpDA,SAAS,GAAgB,CAAE,OAAM,gBAAe,GAAG,GAA2C,CAC5F,GAAM,CAAE,QAAS,EAAQ,EACnB,EAAuC,CAC3C,gBAAiB,IAAS,OAAS,QAAU,QAC7C,OAAQ,GACR,aAAc,EACd,QAAS,EACT,YAAa,UACf,EACM,EAAmB,EACrB,CAAE,GAAG,EAAsB,GAAG,CAAc,EAC5C,CAAE,GAAG,CAAqB,EAC9B,OACE,EAAC,EAAD,CAAK,GAAI,CAAE,aAAc,EAAG,OAAQ,GAAK,QAAS,CAAE,WAClD,EAAC,GAAD,CAAc,GAAI,EAAmB,KAAM,GAAY,GAAQ,EAAE,WAAjE,CACE,EAAC,EAAD,CAAY,QAAQ,cAAK,MAAgB,CAAA,EACzC,EAAC,EAAD,CACE,GAAI,CACF,OAAQ,GACR,aAAc,GACd,YAAa,UACf,WAEA,EAAC,GAAD,CAAa,CAAA,CACV,CAAA,EACL,EAAC,KAAD,CAAK,CAAA,EACL,EAAC,EAAD,CAAY,QAAQ,cAAK,QAAkB,CAAA,EAC3C,EAAC,EAAD,CAAK,GAAI,WAAT,CACE,EAAC,GAAD,CAAc,CAAA,EACd,EAAC,GAAD,CAAY,CAAA,CACT,GACO,GACX,CAAA,CAET,CCvCA,SAAS,GAAY,CAAE,WAA6B,CAClD,OACE,EAAC,GAAD,CAAA,SACG,GAAW,GAER,EAAC,GAAD,CAAA,SACE,EAAC,GAAD,CAAW,CAAA,CACF,EAFK,CAEL,EAEZ,CAAO,CACF,CAAA,CAEd,CCpBA,MAAM,GAAiB,ECsBvB,SAAS,GAAa,CACpB,WACA,OAAQ,EAAS,EACjB,iBAAiB,OACjB,YAAa,EACb,aAAa,EAAC,GAAD,CAAgB,CAAA,EAC7B,eAAe,EAAC,EAAD,CAAkB,CAAA,EACjC,SACA,WACoB,CACpB,GAAM,CAAC,EAAe,GAAoB,EAA6B,IAAI,EACrE,EAAiB,MACd,CAAC,CAAC,EACR,CAAC,CAAa,CAAC,EAEZ,EAAuC,CAC3C,GAAG,EACH,QAAU,GAAwC,CAChD,EAAiB,EAAM,aAAa,CACtC,EACA,gBAAiB,EAAiB,gBAAkB,IAAA,GACpD,gBAAiB,OACjB,gBAAiB,CACnB,EAcA,OAZI,IAAW,IACb,EAAY,QAAU,EAAiB,EAAa,GAGtD,MAAgB,CACV,GAAkB,EACpB,EAAO,EACE,CAAC,GAAkB,GAC5B,EAAQ,CAEZ,EAAG,CAAC,EAAgB,EAAQ,CAAO,CAAC,EAGlC,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAQ,GAAI,WAAc,CAAuB,CAAA,EACjD,EAAC,EAAD,CACE,GAAG,gBACH,SAAU,EACV,KAAM,EACN,YAAe,CACb,EAAiB,IAAI,CACvB,WAEC,OAAO,GAAa,WACnB,EAAC,EAAD,CAAA,SACG,MAAe,CACd,EAAiB,IAAI,CACvB,CAAC,CACE,CAAA,EAEL,CAEE,CAAA,CACH,CAAA,CAAA,CAET,CClEA,MAAM,GAAsB,EAA4D,IAAA,EAAS,EAKjG,SAAgBC,EAA+C,CAC7D,SAAS,IACqB,CAAC,EAA0D,CACzF,IAAM,EAAU,EAAI,EAAmB,EACvC,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,0BACA,kFACF,EAEF,OAAO,CACT,CAGA,SAAgB,GAAuD,CACrE,SAAS,IACqB,CAAC,EAAkE,CACjG,OAAOA,EAAgB,CAAE,QAAO,CAAC,CAInC,CC7BA,SAASC,GAAa,CAAE,WAAU,UAAS,GAAG,GAAgC,CAC5E,GAAM,CAAE,gBAAe,iBAAgB,aAAc,GAAwB,EAE7E,OACE,EAAC,EAAD,CACE,SAAU,EACV,KAAM,EACN,SAAU,EAAmB,IAAW,CACjC,EAAM,kBACT,EAAU,EAER,GACF,EAAQ,EAAO,CAAM,CAEzB,EACA,GAAI,EAEH,UACG,CAAA,CAEV,CCHA,SAASC,GAAoE,CAC3E,YACA,WACA,MACA,UACA,GAAG,GACoC,CACvC,GAAM,CAAE,aAAcC,EAAgB,EAEtC,OACE,EAAC,EAAD,CACa,YACN,MACL,GAAI,EACJ,QAAU,GAAU,CACd,GACF,EAAQ,CAAK,EAEX,GAAM,kBAGV,EAAU,CACZ,EAEC,UACO,CAAA,CAEd,CCpDA,MAAa,EAAkBC,EAczB,GAAgBC,GCdhB,GAAmBC,GCDzB,IAAA,GAAe,GCQf,SAAS,GAAyB,CAChC,MACA,OACA,WACA,UACA,GAAG,GAC6B,CAChC,GAAM,CAAE,aAAc,EAAgB,EAEtC,OACE,EAAC,EAAD,CACE,UAAW,GACL,OACD,MACL,GAAI,EACJ,QAAU,GAAU,CACb,EAAM,kBACT,EAAU,EAER,GACF,EAAQ,CAAK,CAEjB,EAEC,UACO,CAAA,CAEd,CCTA,SAAS,EAAa,CACpB,KACA,YAAYC,EACZ,WACA,MACA,GAAG,GACiB,CACpB,OACE,EAAC,EAAD,CAAoB,YAAe,KAAS,MAAK,GAAI,EAClD,UACM,CAAA,CAEb,CC9BA,SAAS,GAAyB,CAChC,KACA,MACA,WACA,UACA,GAAG,GAC6B,CAChC,GAAM,CAAE,aAAc,EAAgB,EAEtC,OACE,EAAC,EAAD,CACE,UAAW,EACP,KACC,MACL,GAAI,EACJ,QAAU,GAAU,CACb,EAAM,kBACT,EAAU,EAER,GACF,EAAQ,CAAK,CAEjB,EAEC,UACO,CAAA,CAEd,CCZA,SAAS,GAAgB,CACvB,KAAM,EAAO,GACb,SACA,UACA,YACA,YACuB,CACvB,GAAM,CAAC,EAAe,GAAoB,EAAyB,IAAI,EACjE,EAAgB,CAAC,CAAC,EAClB,EAAY,EAAM,EAExB,SAAS,EAAW,EAAmD,CACrE,EAAiB,EAAM,aAAa,EAChC,GACF,EAAO,CAEX,CAEA,SAAS,GAAc,CACrB,EAAiB,IAAI,EACjB,GACF,EAAQ,CAEZ,CAEA,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,YAAW,EAAgB,EAAY,IAAA,GACvC,gBAAc,OACd,aAAc,EACd,aAAc,EACd,GAAI,CACL,CAAA,EACD,EAAC,GAAD,CACE,GAAI,EACJ,cAAA,GACA,kBAAA,GACA,UAAW,CACT,KAAM,CACJ,oBAAqB,GACrB,iBAAkB,GAClB,oBAAqB,EACvB,CACF,EACA,GAAI,CAAE,cAAe,MAAO,EAC5B,KAAM,EACN,SAAU,EACV,aAAc,CACZ,SAAU,SACV,WAAY,MACd,EACA,gBAAiB,CACf,SAAU,MACV,WAAY,MACd,EACA,QAAS,EACT,oBAAA,GAEC,UACM,CAAA,CACN,CAAA,CAAA,CAET,CCjFA,SAAS,GAAqB,CAAE,WAAU,GAAG,GAAkD,CAC7F,OACE,EAAC,EAAD,CAAgB,UAAW,EAAc,GAAI,EAC1C,UACa,CAAA,CAEpB,CCbA,MAAM,GAAS,EC0Cf,SAAS,GAA8B,CACrC,SACoF,CACpF,MAAO,CACL,SAAU,CAAE,cAER,EAAC,EAAD,CACE,UAAW,EAAM,UACjB,MAAO,EAAM,MACb,KAAM,SAAU,EAAQ,EAAM,KAAO,EAAM,eAE1C,UACoB,CAAA,EAG3B,MAAO,EACP,KAAM,EACN,QAAS,EACT,SAAU,EACV,SAAU,CACZ,CACF,CC7DA,MAAM,GAAa,ECgBb,GAAc,ECOd,GAAiB,ECCvB,SAAS,GAAiB,CAAE,WAAU,YAAmC,CACvE,GAAM,CAAC,EAAO,GAAY,EAAiB,EAAE,EAC7C,OACE,EAAA,EAAA,CAAA,SAAA,CACE,EAAC,EAAD,CAAK,GAAI,CAAE,cAAe,CAAE,EAAI,UAAc,CAAA,EAC9C,EAAC,GAAD,CAAO,GAAI,CAAE,SAAU,QAAS,OAAQ,EAAG,KAAM,EAAG,MAAO,CAAE,WAC3D,EAAC,GAAD,CACE,WAAA,GACO,QACP,UAAW,EAAG,IAAU,CACtB,EAAS,CAAK,CAChB,WAEC,EAAS,IAAK,GACN,EAAC,GAAD,CAAyC,GAAI,EAAM,UAAW,CAAO,EAAxC,EAAK,KAAmC,CAC7E,CACe,CAAA,CACb,CAAA,CACP,CAAA,CAAA,CAEN,CC3BA,SAAS,GAAY,EAAyB,CAC5C,MAAO,CACL,MAAO,IACP,WAAY,EAAM,YAAY,OAAO,QAAS,CAC5C,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,cACvC,CAAC,EACD,UAAW,QACb,CACF,CAEA,SAAS,GAAY,EAAyB,CAC5C,MAAO,CACL,WAAY,EAAM,YAAY,OAAO,QAAS,CAC5C,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,aACvC,CAAC,EACD,UAAW,SACX,MAAO,QAAQ,EAAM,QAAQ,CAAC,EAAE,UAC/B,EAAM,YAAY,GAAG,IAAI,GAAI,CAC5B,MAAO,QAAQ,EAAM,QAAQ,CAAC,EAAE,QAClC,CACF,CACF,CAEA,MAAM,GAAe,EAAO,KAAK,GAAG,CAAE,YAC7B,CACL,QAAS,OACT,WAAY,SACZ,eAAgB,WAChB,QAAS,EAAM,QAAQ,EAAG,CAAC,EAE3B,GAAG,EAAM,OAAO,OAClB,EACD,EAMK,GAAS,EAAO,GAAW,CAC/B,kBAAoB,GACX,IAAS,MAEpB,CAAC,GAAgB,CAAE,YACV,CACL,OAAQ,EAAM,OAAO,OAAS,EAC9B,WAAY,EAAM,YAAY,OAAO,CAAC,QAAS,QAAQ,EAAG,CACxD,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,aACvC,CAAC,EACD,SAAU,CACR,CACE,OAAQ,CAAE,UACD,EAET,MAAO,CACL,WAAY,IACZ,MAAO,qBACP,WAAY,EAAM,YAAY,OAAO,CAAC,QAAS,QAAQ,EAAG,CACxD,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,cACvC,CAAC,CACH,CACF,CACF,CACF,EACD,EAEK,GAAS,EAAO,GAAW,CAC/B,kBAAoB,GACX,IAAS,MAEpB,CAAC,GAAG,CAAE,YACG,CACL,MAAO,IACP,WAAY,EACZ,WAAY,SACZ,UAAW,aACX,SAAU,CACR,CACE,OAAQ,CAAE,UACD,EAET,MAAO,CACL,GAAG,GAAY,CAAK,EACpB,qBAAsB,GAAY,CAAK,CACzC,CACF,EACA,CACE,OAAQ,CAAE,UACD,CAAC,EAEV,MAAO,CACL,GAAG,GAAY,CAAK,EACpB,qBAAsB,GAAY,CAAK,CACzC,CACF,CACF,CACF,EACD,EAkCD,SAAS,GAAiB,CAAE,QAAO,WAAU,WAAU,kBAAyC,CAC9F,IAAM,EAAQ,GAAS,EACjB,CAAC,EAAM,GAAW,EAAS,EAAI,EAC/B,EAAW,GAAY,EAE7B,SAAS,GAAmB,CAC1B,EAAQ,EAAI,CACd,CAEA,SAAS,GAAoB,CAC3B,EAAQ,EAAK,CACf,CAEA,OACE,EAAC,EAAD,CAAK,GAAI,CAAE,QAAS,MAAO,WAA3B,CACE,EAAC,EAAD,CAAc,CAAA,EACd,EAAC,GAAD,CAAQ,SAAS,QAAc,gBAC7B,EAAC,GAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,MAAM,UACN,aAAW,cACX,QAAS,EACT,KAAK,QACL,GAAI,CACF,CACE,YAAa,CACf,EACA,GAAQ,CAAE,QAAS,MAAO,CAC5B,WAEA,EAAC,GAAD,CAAS,CAAA,CACC,CAAA,EACZ,EAAC,EAAD,CAAY,QAAQ,KAAK,OAAA,GAAO,UAAU,eACvC,CACS,CAAA,EACX,CACM,CAAA,CAAA,CACH,CAAA,EACR,EAAC,GAAD,CAAQ,QAAQ,YAAkB,gBAAlC,CACE,EAAC,GAAD,CAAA,SACE,EAAC,EAAD,CAAY,QAAS,WAClB,EAAM,YAAc,MAAQ,EAAC,GAAD,CAAiB,CAAA,EAAI,EAAC,GAAD,CAAgB,CAAA,CACxD,CAAA,CACA,CAAA,EACd,EAAC,EAAD,CAAU,CAAA,EACT,EAAS,IAAK,GAEX,EAACC,EAAD,CAAA,SAAA,CACE,EAAC,GAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAY,QAAS,EAAO,KAAO,KAAM,GAAI,CAAE,YAAa,EAAO,EAAI,CAAE,WACtE,EAAO,EAAK,SAAW,EAAS,EAAK,SAAU,CAAC,CACvC,CAAA,EACX,EAAK,QAAQ,IAAK,GAEf,EAAC,GAAD,CAA0B,eAAA,GAAe,GAAI,CAAE,QAAS,OAAQ,WAC9D,EAAC,EAAD,CACE,GAAI,CACF,CACE,UAAW,GACX,GAAI,GACN,EACA,EACI,CACE,eAAgB,SAClB,EACA,CACE,eAAgB,QAClB,CACN,EACA,UAAW,EACX,GAAI,EAAO,GACX,SAAU,EAAS,WAAa,EAAO,YAhBzC,CAkBE,EAAC,GAAD,CACE,GAAI,CACF,CACE,SAAU,EACV,eAAgB,QAClB,EACA,EACI,CACE,GAAI,CACN,EACA,CACE,GAAI,MACN,CACN,WAEC,EAAO,KACN,EAAO,KACJ,EAED,KADF,EAAC,EAAD,CAAA,SAAa,EAAS,EAAO,MAAO,CAAC,CAAc,CAAA,CAEzC,CAAA,EACd,EAAC,GAAD,CACE,QAAS,EAAO,MAChB,GAAI,CACF,EACI,CACE,QAAS,CACX,EACA,CACE,QAAS,CACX,CACN,CACD,CAAA,CACa,GACR,EArDK,EAAO,EAqDZ,CAEb,CACG,CAAA,CAAA,EACN,EAAC,EAAD,CAAU,CAAA,CACF,CAAA,EAjEK,EAAK,QAiEV,CAEb,CACK,IACR,EAAC,EAAD,CAAK,UAAU,OAAO,GAAI,CAAE,SAAU,EAAG,EAAG,CAAE,WAA9C,CACE,EAAC,GAAD,CAAe,CAAA,EACd,CACE,GACF,GAET,CC9QA,SAAS,GAAY,CAAE,OAAM,KAAI,GAAG,GAAqC,CACvE,OACE,EAAA,EAAA,CAAA,SACG,EAAK,MAAM;CAAI,EAAE,KAAK,EAAM,IAEzB,EAAC,EAAD,CAAwB,GAAI,CAAE,OAAQ,EAAG,GAAG,CAAG,EAAG,GAAI,WACnD,CACS,EAFK,CAEL,CAEf,CACD,CAAA,CAEN,CCfA,MAAM,GAAgB,ECStB,SAAS,GAAa,CAAE,eAAc,QAAO,GAAG,GAAkC,CAChF,GAAM,CACJ,UAAW,CAAE,SAAU,EAAc,UAAS,iBAC5C,GAAe,EAEnB,OACE,EAACC,EAAD,CACE,MAAM,UACN,SAAU,EAAY,UAAa,GAAgB,CAAC,GAAY,EAChE,QAAS,EACT,KAAK,SACL,QAAQ,YACR,GAAI,WAEH,CACK,CAAA,CAEZ,CCtBA,SAAS,GAAuB,EAAkB,EAAgB,IAAgB,CAChF,GAAM,CAAC,EAAgB,GAAqB,EAAoB,CAAK,EAWrE,OATA,MAAgB,CACd,IAAM,EAAU,eAAiB,CAC/B,EAAkB,CAAK,CACzB,EAAG,CAAK,EACR,UAAa,CACX,aAAa,CAAO,CACtB,CACF,EAAG,CAAC,EAAO,CAAK,CAAC,EAEV,CACT,CCZA,SAAS,GACP,EACkD,CAClD,GAAM,CAAC,EAAM,GAAW,MAA0B,CAChD,IAAM,EAAkB,OAAO,SAAS,KAAK,QAAQ,IAAK,EAAE,EAC5D,OAAQ,GAAqB,IAAS,GAAK,EAAc,CAC3D,CAAC,EACK,EAAoB,MAAkB,CAC1C,IAAM,EAAkB,OAAO,SAAS,KAAK,QAAQ,IAAK,EAAE,EAC5D,EAAS,GAAqB,IAAS,GAAK,EAAc,CAAI,CAChE,EAAG,CAAC,EAAS,CAAW,CAAC,EAmBzB,OAjBA,OACE,OAAO,iBAAiB,aAAc,CAAiB,MAC1C,CACX,OAAO,oBAAoB,aAAc,CAAiB,CAC5D,GACC,CAAC,CAAiB,CAAC,EAYf,CAAC,EAVW,EAChB,GAAmE,CAClE,IAAM,EAAe,OAAO,GAAY,WAAa,EAAQ,CAAI,EAAI,EACjE,IAAiB,IACnB,OAAO,SAAS,KAAO,EAE3B,EACA,CAAC,CAAI,CAGgB,CAAC,CAC1B"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/root/components/Artwork.tsx","../src/root/components/CollapsibleItem.tsx","../src/root/components/ExternalLink.tsx","../src/root/components/Page.tsx","../src/root/components/SkeletonRow.tsx","../src/root/components/SwitchWithIcons.tsx","../src/root/hooks/useDebounce.ts","../src/root/hooks/useHash.ts","../src/root/hooks/useIsLargeScreen.ts"],"sourcesContent":["import Box from \"@mui/material/Box\";\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Chip from \"@mui/material/Chip\";\nimport Divider from \"@mui/material/Divider\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface ContainerProps {\n containerLabel: string;\n chipLabels: Array<string>;\n}\n\nfunction Container({ containerLabel, chipLabels }: ContainerProps) {\n return (\n <Card\n sx={{\n width: 320,\n height: 420,\n backgroundColor: \"rgba(255,255,255,0.07)\",\n backdropFilter: \"blur(8px)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n boxShadow: \"0 10px 40px rgba(0,0,0,0.35)\",\n }}\n >\n <CardContent>\n <Typography variant=\"h6\" gutterBottom sx={{ color: \"#f8fafc\" }}>\n {containerLabel}\n </Typography>\n\n <Stack spacing={1}>\n {chipLabels.map((label) => {\n return (\n <Chip\n key={label}\n label={label}\n sx={{\n backgroundColor: \"rgba(255,255,255,0.11)\",\n color: \"rgba(255,255,255,0.88)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n }}\n />\n );\n })}\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nfunction Connector() {\n return (\n <Box\n sx={{\n width: 120,\n height: 6,\n borderRadius: 3,\n background: \"linear-gradient(90deg, #f43f5e, #a78bfa, #22d3ee)\",\n boxShadow: \"0 0 24px rgba(167,139,250,0.55)\",\n }}\n />\n );\n}\n\n/**\n * The artwork associated with the package's theme song, _An Interface For You And I_.\n *\n * Listen to it here: https://youtu.be/Nq-fX9Ljf4I\n */\nfunction Artwork() {\n return (\n <Card\n sx={{\n width: 1000,\n height: 1000,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n p: 4,\n background:\n \"radial-gradient(circle at 20% 10%, rgba(167,139,250,0.35) 0%, rgba(167,139,250,0.12) 35%, rgba(0,0,0,0) 55%), linear-gradient(135deg, #3a3380 0%, #1d2e5f 40%, #2d3f55 100%)\",\n color: \"white\",\n }}\n elevation={0}\n >\n <CardHeader\n title=\"An Interface For You And I\"\n sx={{\n color: \"#f8fafc\",\n textAlign: \"center\",\n \"& .MuiCardHeader-title\": {\n fontSize: 40,\n fontWeight: 600,\n letterSpacing: 2,\n },\n }}\n />\n\n <Divider sx={{ borderColor: \"rgba(255,255,255,0.2)\" }} />\n\n <CardContent sx={{ flex: 1, display: \"flex\", alignItems: \"center\" }}>\n <Stack\n direction=\"row\"\n spacing={4}\n sx={{ width: \"100%\", justifyContent: \"center\", alignItems: \"center\" }}\n >\n <Container\n containerLabel=\"You\"\n chipLabels={[\"state\", \"context\", \"input\", \"event\", \"focus\", \"value\", \"history\"]}\n />\n <Connector />\n <Container\n containerLabel=\"I\"\n chipLabels={[\"render\", \"effect\", \"response\", \"update\", \"history\", \"layout\", \"provider\"]}\n />\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nexport default Artwork;\n","import type { CollapseProps } from \"@mui/material/Collapse\";\nimport type { SxProps } from \"@mui/material/styles\";\nimport type { ElementType, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport ButtonBase from \"@mui/material/ButtonBase\";\nimport Collapse from \"@mui/material/Collapse\";\nimport { useEffect, useState } from \"react\";\nimport { MdArrowDropDown, MdArrowDropUp } from \"react-icons/md\";\n\nexport interface CollapsibleItemProps {\n /** Whether the item should initially be open or not. */\n isInitiallyOpen?: boolean;\n /** A callback function to execute when the item is open. */\n onOpen?: () => void;\n /** A callback function to execute when the item is closed. */\n onClose?: () => void;\n /** The components to render when the item is open. */\n children: ReactNode;\n /** Styling for the button. */\n buttonStyles?: SxProps;\n /** The children to pass to the button. */\n buttonContents: ReactNode;\n /** The specific button component to use. */\n buttonComponent?: ElementType;\n /** The icon to show next to the button when open. */\n openIcon?: ReactNode;\n /** The icon to show next to the button when closed. */\n closedIcon?: ReactNode;\n /** Props to pass to collapse. */\n collapseProps?: Omit<CollapseProps, \"in\">;\n /**\n * Whether or not to use the default button styling.\n *\n * Defaults to `true` if `buttonComponent` is `ButtonBase`,\n * otherwise defaults to `false`.\n */\n useDefaultStyling?: boolean;\n}\n\n/**\n * Shows a display area that can be opened to show the children components, or hidden away.\n */\nfunction CollapsibleItem({\n isInitiallyOpen,\n onOpen,\n onClose,\n children,\n buttonStyles,\n buttonContents,\n buttonComponent: ButtonComponent = ButtonBase,\n collapseProps,\n openIcon = <MdArrowDropUp />,\n closedIcon = <MdArrowDropDown />,\n useDefaultStyling = ButtonComponent === ButtonBase,\n}: CollapsibleItemProps) {\n const [isItemOpen, setIsItemOpen] = useState<boolean>(Boolean(isInitiallyOpen));\n\n useEffect(() => {\n if (isItemOpen && onOpen) {\n onOpen();\n } else if (!isItemOpen && onClose) {\n onClose();\n }\n }, [isItemOpen, onOpen, onClose]);\n\n return (\n <Box>\n <ButtonComponent\n onClick={() => {\n setIsItemOpen((previouslyOpen) => {\n return !previouslyOpen;\n });\n }}\n sx={\n useDefaultStyling\n ? {\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n paddingY: 1.5,\n paddingX: 2,\n textAlign: \"center\",\n \"&:hover\":\n ButtonComponent === ButtonBase ? { backgroundColor: \"action.hover\" } : null,\n ...buttonStyles,\n }\n : buttonStyles\n }\n aria-expanded={isItemOpen}\n >\n {buttonContents}\n {isItemOpen ? openIcon : closedIcon}\n </ButtonComponent>\n <Collapse in={isItemOpen} {...collapseProps}>\n {children}\n </Collapse>\n </Box>\n );\n}\n\nexport default CollapsibleItem;\n","import type { LinkProps } from \"@mui/material/Link\";\nimport type { ReactNode, Ref } from \"react\";\n\nimport MUILink from \"@mui/material/Link\";\n\nexport interface ExternalLinkProps extends Omit<LinkProps, \"to\" | \"target\" | \"rel\"> {\n /** The URL of the place you want to navigate to. */\n href: `https://${string}` | `http://${string}` | (string & {});\n to?: never;\n /** The readable content to display on the link. */\n children: ReactNode;\n /** An optional ref to allow it to be used with polymorphic components. */\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A stylised link that is best used when you want to navigate to a different domain.\n *\n * Opens the destination in a new tab and applies recommended security defaults automatically.\n */\nfunction ExternalLink({ href, children, ref, ...linkProps }: ExternalLinkProps) {\n return (\n <MUILink\n component=\"a\"\n href={href}\n ref={ref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {...linkProps}\n >\n {children}\n </MUILink>\n );\n}\n\nexport default ExternalLink;\n","import type { ReactNode } from \"react\";\n\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Divider from \"@mui/material/Divider\";\nimport Typography from \"@mui/material/Typography\";\n\nexport interface PageProps {\n /** The Page title to show */\n title: ReactNode;\n /** The subtitle to show under the Page title */\n subtitle?: ReactNode;\n /** The actions to show in the page header */\n action?: ReactNode;\n /** The actual page contents */\n children: ReactNode;\n /** Disable the inner padding of the Page contents. */\n disablePadding?: boolean;\n /** Optional tabs to display in the header. */\n tabs?: ReactNode;\n}\n\n/** Renders a pre-styled Page that can be used to structure pages throughout your React apps. */\nfunction Page({ title, subtitle, action, children, tabs, disablePadding }: PageProps) {\n return (\n <Card>\n <CardHeader\n title={\n <>\n {typeof title === \"string\" ? <Typography variant=\"h6\">{title}</Typography> : title}\n {subtitle ? (\n typeof subtitle === \"string\" ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {subtitle}\n </Typography>\n ) : (\n subtitle\n )\n ) : null}\n </>\n }\n action={action}\n />\n {tabs}\n <Divider />\n {disablePadding ? children : <CardContent>{children}</CardContent>}\n </Card>\n );\n}\n\nexport default Page;\n","import { fillArray } from \"@alextheman/utility\";\nimport Skeleton from \"@mui/material/Skeleton\";\nimport TableCell from \"@mui/material/TableCell\";\nimport TableRow from \"@mui/material/TableRow\";\n\nexport interface SkeletonRowProps {\n /** The number of columns the SkeletonRow should display. */\n columns: number;\n}\n\n/** Renders the skeleton of a table row. Often helpful to represent the loading state of the data in your table. */\nfunction SkeletonRow({ columns }: SkeletonRowProps) {\n return (\n <TableRow>\n {fillArray((index) => {\n return (\n <TableCell key={index}>\n <Skeleton />\n </TableCell>\n );\n }, columns)}\n </TableRow>\n );\n}\n\nexport default SkeletonRow;\n","import type { CommonProps } from \"@mui/material/OverridableComponent\";\nimport type { SwitchProps } from \"@mui/material/Switch\";\nimport type { ComponentType, CSSProperties } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport { styled } from \"@mui/material/styles\";\nimport Switch from \"@mui/material/Switch\";\n\nexport interface SwitchWithIconsProps extends Omit<SwitchProps, \"icon\" | \"checkedIcon\"> {\n /** The icon to show when the switch is in a checked state. */\n checkedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when checked. */\n checkedIconStyles?: CommonProps[\"style\"];\n /** The icon to show when the switch is in an unchecked state. */\n uncheckedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when unchecked. */\n uncheckedIconStyles?: CommonProps[\"style\"];\n}\n\nconst StyledSwitch = styled(Switch)(() => {\n return {\n padding: 8,\n \"& .MuiSwitch-track\": {\n borderRadius: 11,\n \"&::before, &::after\": {\n content: '\"\"',\n position: \"absolute\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n fontSize: 16,\n width: 28,\n height: 28,\n },\n },\n };\n});\n\n/** Renders a switch with your provided icons. */\nfunction SwitchWithIcons({\n checkedIcon: CheckedIcon,\n checkedIconStyles,\n uncheckedIcon: UncheckedIcon,\n uncheckedIconStyles,\n ...switchProps\n}: SwitchWithIconsProps) {\n const boxSx = {\n borderRadius: \"50%\",\n borderColor: \"white\",\n backgroundColor: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 0.25,\n };\n const defaultIconStyles = { color: \"black\", maxWidth: 16.5, maxHeight: 16.5 };\n return (\n <StyledSwitch\n checkedIcon={\n <Box sx={boxSx}>\n <CheckedIcon style={{ ...defaultIconStyles, ...checkedIconStyles }} />\n </Box>\n }\n icon={\n <Box sx={boxSx}>\n <UncheckedIcon style={{ ...defaultIconStyles, ...uncheckedIconStyles }} />\n </Box>\n }\n {...switchProps}\n />\n );\n}\n\nexport default SwitchWithIcons;\n","import { useEffect, useState } from \"react\";\n\n/**\n * Assign a variable a given value after a given amount of milliseconds.\n *\n * @template ValueType The type of the value to set.\n *\n * @param value - The value to assign.\n * @param delay - The amount of milliseconds to wait before assigning the value.\n *\n * @returns The input value after a given number of seconds.\n */\nfunction useDebounce<ValueType>(value: ValueType, delay: number = 500): ValueType {\n const [debouncedValue, setDebouncedValue] = useState<ValueType>(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n\nexport default useDebounce;\n","import type { Dispatch, SetStateAction } from \"react\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Stores changes to the window hash as React state.\n *\n * @template StateType - The type of the hash state.\n *\n * @param initialHash - The initial value of the hash.\n *\n * @returns A tuple containing the hash state, and a updater function to set the hash state.\n */\nfunction useHash<StateType extends string>(\n initialHash: StateType | undefined,\n): [StateType, Dispatch<SetStateAction<StateType>>] {\n const [hash, setHash] = useState<StateType>(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n return !initialHash ? hash : hash === \"\" ? initialHash : hash;\n });\n const hashChangeHandler = useCallback(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n setHash(!initialHash ? hash : hash === \"\" ? initialHash : hash);\n }, [setHash, initialHash]);\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", hashChangeHandler);\n return () => {\n window.removeEventListener(\"hashchange\", hashChangeHandler);\n };\n }, [hashChangeHandler]);\n\n const updateHash = useCallback(\n (newHash: StateType | ((previousState: StateType) => StateType)) => {\n const resolvedHash = typeof newHash === \"function\" ? newHash(hash) : newHash;\n if (resolvedHash !== hash) {\n window.location.hash = resolvedHash;\n }\n },\n [hash],\n );\n\n return [hash, updateHash];\n}\n\nexport default useHash;\n","import useMediaQuery from \"@mui/material/useMediaQuery\";\n\n/**\n * Determines if the screen size can be considered large.\n *\n * @returns `true` if the screen size is considered large, and `false` otherwise.\n */\nfunction useIsLargeScreen(): boolean {\n const isLargeScreen = useMediaQuery((theme) => {\n return theme.breakpoints.up(\"md\");\n });\n\n return isLargeScreen;\n}\n\nexport default useIsLargeScreen;\n"],"mappings":"23BAcA,SAAS,EAAU,CAAE,iBAAgB,cAA8B,CACjE,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,IACR,gBAAiB,yBACjB,eAAgB,YAChB,OAAQ,mCACR,UAAW,8BACb,WAEA,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAY,QAAQ,KAAK,aAAA,GAAa,GAAI,CAAE,MAAO,SAAU,WAC1D,CACS,CAAA,EAEZ,EAAC,EAAD,CAAO,QAAS,WACb,EAAW,IAAK,GAEb,EAAC,EAAD,CAES,QACP,GAAI,CACF,gBAAiB,yBACjB,MAAO,yBACP,OAAQ,kCACV,CACD,EAPM,CAON,CAEJ,CACI,CAAA,CACI,CAAA,CAAA,CACT,CAAA,CAEV,CAEA,SAAS,GAAY,CACnB,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,EACR,aAAc,EACd,WAAY,oDACZ,UAAW,iCACb,CACD,CAAA,CAEL,CAOA,SAAS,GAAU,CACjB,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,IACR,QAAS,OACT,cAAe,SACf,eAAgB,gBAChB,EAAG,EACH,WACE,+KACF,MAAO,OACT,EACA,UAAW,WAZb,CAcE,EAAC,EAAD,CACE,MAAM,6BACN,GAAI,CACF,MAAO,UACP,UAAW,SACX,yBAA0B,CACxB,SAAU,GACV,WAAY,IACZ,cAAe,CACjB,CACF,CACD,CAAA,EAED,EAAC,EAAD,CAAS,GAAI,CAAE,YAAa,uBAAwB,CAAI,CAAA,EAExD,EAAC,EAAD,CAAa,GAAI,CAAE,KAAM,EAAG,QAAS,OAAQ,WAAY,QAAS,WAChE,EAAC,EAAD,CACE,UAAU,MACV,QAAS,EACT,GAAI,CAAE,MAAO,OAAQ,eAAgB,SAAU,WAAY,QAAS,WAHtE,CAKE,EAAC,EAAD,CACE,eAAe,MACf,WAAY,CAAC,QAAS,UAAW,QAAS,QAAS,QAAS,QAAS,SAAS,CAC/E,CAAA,EACD,EAAC,EAAD,CAAY,CAAA,EACZ,EAAC,EAAD,CACE,eAAe,IACf,WAAY,CAAC,SAAU,SAAU,WAAY,SAAU,UAAW,SAAU,UAAU,CACvF,CAAA,CACI,GACI,CAAA,CACT,GAEV,CC7EA,SAAS,EAAgB,CACvB,kBACA,SACA,UACA,WACA,eACA,iBACA,gBAAiB,EAAkB,EACnC,gBACA,WAAW,EAAC,EAAD,CAAgB,CAAA,EAC3B,aAAa,EAAC,EAAD,CAAkB,CAAA,EAC/B,oBAAoB,IAAoB,GACjB,CACvB,GAAM,CAAC,EAAY,GAAiB,EAAkB,EAAQ,CAAgB,EAU9E,OARA,MAAgB,CACV,GAAc,EAChB,EAAO,EACE,CAAC,GAAc,GACxB,EAAQ,CAEZ,EAAG,CAAC,EAAY,EAAQ,CAAO,CAAC,EAG9B,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,YAAe,CACb,EAAe,GACN,CAAC,CACT,CACH,EACA,GACE,EACI,CACE,MAAO,OACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,SAAU,IACV,SAAU,EACV,UAAW,SACX,UACE,IAAoB,EAAa,CAAE,gBAAiB,cAAe,EAAI,KACzE,GAAG,CACL,EACA,EAEN,gBAAe,WAtBjB,CAwBG,EACA,EAAa,EAAW,CACV,IACjB,EAAC,EAAD,CAAU,GAAI,EAAY,GAAI,EAC3B,UACO,CAAA,CACP,CAAA,CAAA,CAET,CChFA,SAAS,EAAa,CAAE,OAAM,WAAU,MAAK,GAAG,GAAgC,CAC9E,OACE,EAAC,EAAD,CACE,UAAU,IACJ,OACD,MACL,OAAO,SACP,IAAI,sBACJ,GAAI,EAEH,UACM,CAAA,CAEb,CCTA,SAAS,EAAK,CAAE,QAAO,WAAU,SAAQ,WAAU,OAAM,kBAA6B,CACpF,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,MACE,EAAA,EAAA,CAAA,SAAA,CACG,OAAO,GAAU,SAAW,EAAC,EAAD,CAAY,QAAQ,cAAM,CAAkB,CAAA,EAAI,EAC5E,EACC,OAAO,GAAa,SAClB,EAAC,EAAD,CAAY,QAAQ,QAAQ,MAAM,0BAC/B,CACS,CAAA,EAEZ,EAEA,IACJ,CAAA,CAAA,EAEI,QACT,CAAA,EACA,EACD,EAAC,EAAD,CAAU,CAAA,EACT,EAAiB,EAAW,EAAC,EAAD,CAAc,UAAsB,CAAA,CAC7D,CAAA,CAAA,CAEV,CCtCA,SAAS,EAAY,CAAE,WAA6B,CAClD,OACE,EAAC,EAAD,CAAA,SACG,EAAW,GAER,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAW,CAAA,CACF,EAFK,CAEL,EAEZ,CAAO,CACF,CAAA,CAEd,CCJA,MAAM,EAAe,EAAO,CAAM,OACzB,CACL,QAAS,EACT,qBAAsB,CACpB,aAAc,GACd,sBAAuB,CACrB,QAAS,KACT,SAAU,WACV,IAAK,MACL,UAAW,mBACX,SAAU,GACV,MAAO,GACP,OAAQ,EACV,CACF,CACF,EACD,EAGD,SAAS,EAAgB,CACvB,YAAa,EACb,oBACA,cAAe,EACf,sBACA,GAAG,GACoB,CACvB,IAAM,EAAQ,CACZ,aAAc,MACd,YAAa,QACb,gBAAiB,QACjB,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,QAAS,GACX,EACM,EAAoB,CAAE,MAAO,QAAS,SAAU,KAAM,UAAW,IAAK,EAC5E,OACE,EAAC,EAAD,CACE,YACE,EAAC,EAAD,CAAK,GAAI,WACP,EAAC,EAAD,CAAa,MAAO,CAAE,GAAG,EAAmB,GAAG,CAAkB,CAAI,CAAA,CAClE,CAAA,EAEP,KACE,EAAC,EAAD,CAAK,GAAI,WACP,EAAC,EAAD,CAAe,MAAO,CAAE,GAAG,EAAmB,GAAG,CAAoB,CAAI,CAAA,CACtE,CAAA,EAEP,GAAI,CACL,CAAA,CAEL,CC1DA,SAAS,EAAuB,EAAkB,EAAgB,IAAgB,CAChF,GAAM,CAAC,EAAgB,GAAqB,EAAoB,CAAK,EAWrE,OATA,MAAgB,CACd,IAAM,EAAU,eAAiB,CAC/B,EAAkB,CAAK,CACzB,EAAG,CAAK,EACR,UAAa,CACX,aAAa,CAAO,CACtB,CACF,EAAG,CAAC,EAAO,CAAK,CAAC,EAEV,CACT,CCZA,SAAS,EACP,EACkD,CAClD,GAAM,CAAC,EAAM,GAAW,MAA0B,CAChD,IAAM,EAAkB,OAAO,SAAS,KAAK,QAAQ,IAAK,EAAE,EAC5D,OAAQ,GAAqB,IAAS,GAAK,EAAc,CAC3D,CAAC,EACK,EAAoB,MAAkB,CAC1C,IAAM,EAAkB,OAAO,SAAS,KAAK,QAAQ,IAAK,EAAE,EAC5D,EAAS,GAAqB,IAAS,GAAK,EAAc,CAAI,CAChE,EAAG,CAAC,EAAS,CAAW,CAAC,EAmBzB,OAjBA,OACE,OAAO,iBAAiB,aAAc,CAAiB,MAC1C,CACX,OAAO,oBAAoB,aAAc,CAAiB,CAC5D,GACC,CAAC,CAAiB,CAAC,EAYf,CAAC,EAVW,EAChB,GAAmE,CAClE,IAAM,EAAe,OAAO,GAAY,WAAa,EAAQ,CAAI,EAAI,EACjE,IAAiB,IACnB,OAAO,SAAS,KAAO,EAE3B,EACA,CAAC,CAAI,CAGgB,CAAC,CAC1B,CCpCA,SAAS,GAA4B,CAKnC,OAJsB,EAAe,GAC5B,EAAM,YAAY,GAAG,IAAI,CAGf,CACrB"}
@@ -0,0 +1,170 @@
1
+ import { LinkProps } from "@mui/material/Link";
2
+ import { RouterProps, SwitchProps as SwitchProps$1, useLocation } from "wouter";
3
+ import { ElementType, JSX, ReactNode, Ref } from "react";
4
+
5
+ //#region src/routing/ErrorPage.d.ts
6
+ interface ErrorPageProps {
7
+ /** The page title. */
8
+ title: string;
9
+ /** The page content. */
10
+ children: ReactNode;
11
+ }
12
+ /** Renders a simple page layout for displaying errors. */
13
+ declare function ErrorPage({
14
+ title,
15
+ children
16
+ }: ErrorPageProps): import("react/jsx-runtime").JSX.Element;
17
+ //#endregion
18
+ //#region src/routing/InternalLink.d.ts
19
+ interface InternalLinkProps extends Omit<LinkProps, "href" | "component"> {
20
+ /** The path to navigate to */
21
+ to: `/${string}` | `~/${string}` | (string & {});
22
+ /**
23
+ * An optional component to provide to override the current component.
24
+ *
25
+ * Note that the provided component must:
26
+ * - accept a `to` prop
27
+ * - correctly handle the forwarded `ref`
28
+ * - render a valid anchor element (or equivalent) for proper accessibility
29
+ */
30
+ component?: ElementType;
31
+ href?: never;
32
+ /** The readable content to display on the link. */
33
+ children: ReactNode;
34
+ /** An optional ref to allow it to be used with polymorphic components. */
35
+ ref?: Ref<HTMLAnchorElement>;
36
+ }
37
+ /**
38
+ * A stylised link for navigating within your application.
39
+ *
40
+ * Uses the app router for client-side navigation and opens the destination in the same tab.
41
+ *
42
+ * Defaults to a Wouter implementation but can be overridden via the `component` prop.
43
+ */
44
+ declare function InternalLink({
45
+ to,
46
+ component,
47
+ children,
48
+ ref,
49
+ ...linkProps
50
+ }: InternalLinkProps): import("react/jsx-runtime").JSX.Element;
51
+ //#endregion
52
+ //#region src/routing/MemoryRouter.d.ts
53
+ /**
54
+ * A router that can be used with Wouter that stores all entries in memory. Works similarly to the `MemoryRouter` from `react-router-dom`.
55
+ *
56
+ * Note that it also contains the same absolute routing behaviour found in the base `Router` component from `@alextheman/components/v7`.
57
+ */
58
+ declare function MemoryRouter({
59
+ children,
60
+ ...routerProps
61
+ }: Omit<RouterProps, "hook" | "hrefs">): import("react/jsx-runtime").JSX.Element;
62
+ //#endregion
63
+ //#region src/routing/NavigationBottom.d.ts
64
+ interface NavItemBottom {
65
+ /** The label to display on the nav item. */
66
+ label: string;
67
+ /** An icon to display alongside the nav item. */
68
+ icon?: JSX.Element;
69
+ /** Where in your app the nav item should navigate to. */
70
+ to: string;
71
+ /** The value associated with the nav item (defaults to the `to` value). */
72
+ value?: string;
73
+ }
74
+ interface NavigationBottomProps {
75
+ /** Children to display above the nav bar. */
76
+ children: ReactNode;
77
+ /** An array of nav items to show. */
78
+ navItems: Array<NavItemBottom>;
79
+ }
80
+ /** Renders a navigation bar at the bottom of the screen. Especially helpful for common navigation options in a mobile app. */
81
+ declare function NavigationBottom({
82
+ children,
83
+ navItems
84
+ }: NavigationBottomProps): import("react/jsx-runtime").JSX.Element;
85
+ //#endregion
86
+ //#region src/routing/NavigationDrawer.d.ts
87
+ interface NavMenuItemOptions {
88
+ /** The label to display on the nav item option. */
89
+ label: string;
90
+ /** Where in your app the nav item option should navigate to. */
91
+ to: string;
92
+ /** An icon to display alongside the nav item option. */
93
+ icon?: ReactNode;
94
+ }
95
+ interface NavMenuItem {
96
+ /** The category to display all the nav item options under. */
97
+ category: string;
98
+ /** An array of nav options to display under the chosen category. */
99
+ options: Array<NavMenuItemOptions>;
100
+ }
101
+ interface NavigationDrawerProps {
102
+ /** The title to display at the top of the wrapper. */
103
+ title: string;
104
+ /** An array of nav items to show. */
105
+ navItems: Array<NavMenuItem>;
106
+ /** Any extra elements to add to the header. */
107
+ headerElements?: ReactNode;
108
+ /** Children to display within the wrapper. */
109
+ children: ReactNode;
110
+ }
111
+ /** Renders a collapsable drawer to help with navigation. Best used as the main means of navigation on desktop apps. */
112
+ declare function NavigationDrawer({
113
+ title,
114
+ navItems,
115
+ children,
116
+ headerElements
117
+ }: NavigationDrawerProps): import("react/jsx-runtime").JSX.Element;
118
+ //#endregion
119
+ //#region src/routing/Router.d.ts
120
+ /**
121
+ * An app Router that integrates with Wouter and handles nested routing behaviour.
122
+ *
123
+ * If you use a Wouter Link within a nested Route with Wouter, navigation can behave unexpectedly as it ends up resolving relative to the nested router's base URL. For example:
124
+ *
125
+ * ```tsx
126
+ * <Route path="/users" nest>
127
+ * <Link to="/users/sign-in"> // Navigates to `/users/users/sign-in` (it appends the `to` prop to the `path` prop in the Route)
128
+ * View user details
129
+ * </Link>
130
+ * </Route>
131
+ * ```
132
+ *
133
+ * This can be surprising, especially when re-using page logic across routes, where you don't want links to rely on implicit nested routing behaviour. This router deals with the above so that, for as long as you define your nested routes in this Router component, the Link example above would navigate to `/users/sign-in` instead. That is, it uses the `to` prop as an absolute path rather than appending it to the parent Route path.
134
+ *
135
+ * This effectively makes all navigation behave as if paths are absolute (relative to the application's base URL), regardless of nested routing structure.
136
+ */
137
+ declare function Router({
138
+ children,
139
+ hook,
140
+ ...routerProps
141
+ }: Omit<RouterProps, "hrefs">): import("react/jsx-runtime").JSX.Element;
142
+ //#endregion
143
+ //#region src/routing/Switch.d.ts
144
+ interface SwitchProps extends SwitchProps$1 {
145
+ /** The content to render if no routes match. */
146
+ fallback?: ReactNode;
147
+ }
148
+ /**
149
+ * A wrapper around Wouter's Switch that adds a fallback route.
150
+ *
151
+ * This ensures that any unmatched routes in the Switch always shows something rather than just showing an empty page.
152
+ */
153
+ declare function Switch({
154
+ children,
155
+ fallback,
156
+ ...switchProps
157
+ }: SwitchProps): import("react/jsx-runtime").JSX.Element;
158
+ //#endregion
159
+ //#region src/routing/useAbsoluteLocation.d.ts
160
+ /**
161
+ * Returns the current app location as an absolute app-relative path, along with a function to set it.
162
+ *
163
+ * Unlike Wouter's default nested router behaviour, this hook always resolves locations relative to the application's root router, even when called within nested routers.
164
+ *
165
+ * @returns A tuple containing the current absolute app location and a function to navigate to a new location.
166
+ */
167
+ declare function useAbsoluteLocation(...args: Parameters<typeof useLocation>): ReturnType<typeof useLocation>;
168
+ //#endregion
169
+ export { ErrorPage, type ErrorPageProps, InternalLink, type InternalLinkProps, MemoryRouter, type NavItemBottom, type NavMenuItem, NavigationBottom, type NavigationBottomProps, NavigationDrawer, type NavigationDrawerProps, Router, Switch, type SwitchProps, useAbsoluteLocation };
170
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ import e from"@mui/material/Alert";import t from"@mui/material/AlertTitle";import n from"@mui/material/Container";import{Fragment as r,jsx as i,jsxs as a}from"react/jsx-runtime";import o from"@mui/material/Link";import{Link as s,Route as c,Router as l,Switch as u,useLocation as d,useRouter as f}from"wouter";import{memoryLocation as p}from"wouter/memory-location";import{escapeRegexPattern as m,truncate as h}from"@alextheman/utility";import{useBrowserLocation as g}from"wouter/use-browser-location";import _ from"@mui/material/BottomNavigation";import v from"@mui/material/BottomNavigationAction";import y from"@mui/material/Box";import b from"@mui/material/Paper";import x from"@mui/material/AppBar";import S from"@mui/material/CssBaseline";import C from"@mui/material/Divider";import w from"@mui/material/Drawer";import T from"@mui/material/IconButton";import E from"@mui/material/List";import D from"@mui/material/ListItem";import O from"@mui/material/ListItemButton";import k from"@mui/material/ListItemIcon";import A from"@mui/material/ListItemText";import{styled as j,useTheme as M}from"@mui/material/styles";import N from"@mui/material/Toolbar";import P from"@mui/material/Typography";import{Fragment as F,useState as I}from"react";import{MdChevronLeft as L,MdChevronRight as R,MdMenu as z}from"react-icons/md";function B({title:r,children:o}){return i(n,{maxWidth:`sm`,children:a(e,{severity:`error`,children:[i(t,{children:r}),o]})})}function V({to:e,component:t=s,children:n,ref:r,...a}){return i(o,{component:t,to:e,ref:r,...a,children:n})}function H(e,t){return e.replace(RegExp(`^${m(t.base)}`),``)}function U(e=g){return t=>{let[n,r]=e(t);return[n,(...[e,...n])=>r(H(e,t),...n)]}}function W({children:e,hook:t,...n}){return i(l,{...n,hook:U(t),hrefs:(e,t)=>H(e,t),children:e})}function G({children:e,...t}){let{hook:n}=p({path:`/`});return i(W,{...t,hook:n,children:e})}function K(e,t){return`${t.base}/${e}`.replace(/\/+/g,`/`)}function q(...e){let t=f(),[n,r]=d(...e);return[K(n,t),r]}function J({children:e,navItems:t}){let[n]=q();return a(r,{children:[i(y,{sx:{paddingBottom:7},children:e}),i(b,{sx:{position:`fixed`,bottom:0,left:0,right:0},children:i(_,{showLabels:!0,value:n,children:t.map(e=>i(v,{value:e.value??e.to,...e,component:V},e.to))})})]})}function Y(e){return{width:240,transition:e.transitions.create(`width`,{easing:e.transitions.easing.sharp,duration:e.transitions.duration.enteringScreen}),overflowX:`hidden`}}function X(e){return{transition:e.transitions.create(`width`,{easing:e.transitions.easing.sharp,duration:e.transitions.duration.leavingScreen}),overflowX:`hidden`,width:`calc(${e.spacing(7)} + 1px)`,[e.breakpoints.up(`sm`)]:{width:`calc(${e.spacing(8)} + 1px)`}}}const Z=j(`div`)(({theme:e})=>({display:`flex`,alignItems:`center`,justifyContent:`flex-end`,padding:e.spacing(0,1),...e.mixins.toolbar})),Q=j(x,{shouldForwardProp:e=>e!==`open`})(({theme:e})=>({zIndex:e.zIndex.drawer+1,transition:e.transitions.create([`width`,`margin`],{easing:e.transitions.easing.sharp,duration:e.transitions.duration.leavingScreen}),variants:[{props:({open:e})=>e,style:{marginLeft:240,width:`calc(100% - 240px)`,transition:e.transitions.create([`width`,`margin`],{easing:e.transitions.easing.sharp,duration:e.transitions.duration.enteringScreen})}}]})),$=j(w,{shouldForwardProp:e=>e!==`open`})(({theme:e})=>({width:240,flexShrink:0,whiteSpace:`nowrap`,boxSizing:`border-box`,variants:[{props:({open:e})=>e,style:{...Y(e),"& .MuiDrawer-paper":Y(e)}},{props:({open:e})=>!e,style:{...X(e),"& .MuiDrawer-paper":X(e)}}]}));function ee({title:e,navItems:t,children:n,headerElements:r}){let o=M(),[s,c]=I(!0),[l]=q();function u(){c(!0)}function d(){c(!1)}return a(y,{sx:{display:`flex`},children:[i(S,{}),i(Q,{position:`fixed`,open:s,children:a(N,{children:[i(T,{color:`inherit`,"aria-label":`open drawer`,onClick:u,edge:`start`,sx:[{marginRight:5},s&&{display:`none`}],children:i(z,{})}),i(P,{variant:`h6`,noWrap:!0,component:`div`,children:e}),i(y,{sx:{marginLeft:`auto`},children:r})]})}),a($,{variant:`permanent`,open:s,children:[i(Z,{children:i(T,{onClick:d,children:o.direction===`rtl`?i(R,{}):i(L,{})})}),i(C,{}),t.map(e=>a(F,{children:[a(E,{children:[i(P,{variant:s?`h5`:`h6`,sx:{paddingLeft:s?2:1},children:s?e.category:h(e.category,4)}),e.options.map(e=>i(D,{disablePadding:!0,sx:{display:`block`},children:a(O,{sx:[{minHeight:48,px:2.5},s?{justifyContent:`initial`}:{justifyContent:`center`}],component:V,to:e.to,selected:l===e.to,children:[i(k,{sx:[{minWidth:0,justifyContent:`center`},s?{mr:3}:{mr:`auto`}],children:e.icon?e.icon:s?null:i(P,{children:h(e.label,4)})}),i(A,{primary:e.label,sx:[s?{opacity:1}:{opacity:0}]})]})},e.to))]}),i(C,{})]},e.category))]}),a(y,{component:`main`,sx:{flexGrow:1,p:3},children:[i(Z,{}),n]})]})}function te({children:e,fallback:t=a(B,{title:`Page Not Found`,children:[`This page is not available. Please click `,i(V,{to:`/`,children:`here`}),` to return to the homepage.`]}),...n}){return a(u,{...n,children:[e,i(c,{children:t})]})}export{B as ErrorPage,V as InternalLink,G as MemoryRouter,J as NavigationBottom,ee as NavigationDrawer,W as Router,te as Switch,q as useAbsoluteLocation};
2
+ //# sourceMappingURL=index.js.map