@atproto/oauth-provider-ui 0.1.1 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/oauth-provider-ui",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "description": "Sign-in & Sign-up UI for the @atproto/oauth-provider",
6
6
  "homepage": "https://atproto.com",
@@ -26,7 +26,7 @@
26
26
  "hydration-data.d.ts"
27
27
  ],
28
28
  "optionalDependencies": {
29
- "@atproto/oauth-provider-api": "0.1.0"
29
+ "@atproto/oauth-provider-api": "0.1.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@hcaptcha/react-hcaptcha": "^1.11.2",
@@ -49,8 +49,8 @@
49
49
  "vite": "^6.2.0",
50
50
  "@atproto-labs/fetch": "0.2.2",
51
51
  "@atproto-labs/rollup-plugin-bundle-manifest": "0.2.0",
52
- "@atproto/oauth-types": "0.2.5",
53
- "@atproto/oauth-provider-api": "0.1.0"
52
+ "@atproto/oauth-provider-api": "0.1.1",
53
+ "@atproto/oauth-types": "0.2.6"
54
54
  },
55
55
  "scripts": {
56
56
  "i18n:extract": "lingui extract --clean",
@@ -1,3 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["index-CHPoD7Rp.js","error-view-MVy7C9l0.js","error-view-CRGNTAn2.css"])))=>i.map(i=>d[i]);
2
- import{r as l,j as e,c as I,L as Ce,A as Ee,u as R,U as Re,T as m,M as Le,a as ae,E as Ie,b as Pe,d as Ae,e as Te,f as pe,g as ie,h as le,S as $e,I as He,i as Ve,C as xe,k as fe,l as Fe,X as Ue,_ as Oe,m as Be,n as qe,o as Me,p as Xe}from"./error-view-MVy7C9l0.js";const ge=l.createContext(null),ce={didCatch:!1,error:null};class Ke extends l.Component{constructor(s){super(s),this.resetErrorBoundary=this.resetErrorBoundary.bind(this),this.state=ce}static getDerivedStateFromError(s){return{didCatch:!0,error:s}}resetErrorBoundary(){const{error:s}=this.state;if(s!==null){for(var n,a,r=arguments.length,i=new Array(r),o=0;o<r;o++)i[o]=arguments[o];(n=(a=this.props).onReset)===null||n===void 0||n.call(a,{args:i,reason:"imperative-api"}),this.setState(ce)}}componentDidCatch(s,n){var a,r;(a=(r=this.props).onError)===null||a===void 0||a.call(r,s,n)}componentDidUpdate(s,n){const{didCatch:a}=this.state,{resetKeys:r}=this.props;if(a&&n.error!==null&&De(s.resetKeys,r)){var i,o;(i=(o=this.props).onReset)===null||i===void 0||i.call(o,{next:r,prev:s.resetKeys,reason:"keys"}),this.setState(ce)}}render(){const{children:s,fallbackRender:n,FallbackComponent:a,fallback:r}=this.props,{didCatch:i,error:o}=this.state;let d=s;if(i){const c={error:o,resetErrorBoundary:this.resetErrorBoundary};if(typeof n=="function")d=n(c);else if(a)d=l.createElement(a,c);else if(r!==void 0)d=r;else throw o}return l.createElement(ge.Provider,{value:{didCatch:i,error:o,resetErrorBoundary:this.resetErrorBoundary}},d)}}function De(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],s=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[];return t.length!==s.length||t.some((n,a)=>!Object.is(n,s[a]))}function Ge(t){if(t==null||typeof t.didCatch!="boolean"||typeof t.resetErrorBoundary!="function")throw new Error("ErrorBoundaryContext not found")}function Ze(){const t=l.useContext(ge);Ge(t);const[s,n]=l.useState({error:null,hasError:!1}),a=l.useMemo(()=>({resetBoundary:()=>{t.resetErrorBoundary(),n({error:null,hasError:!1})},showBoundary:r=>n({error:r,hasError:!0})}),[t.resetErrorBoundary]);if(s.hasError)throw s.error;return a}function T({children:t,title:s,subtitle:n,className:a,...r}){return e.jsxs("div",{...r,className:I(a,"flex flex-col items-center","md:flex md:flex-row md:items-center md:justify-stretch","min-w-screen min-h-screen","bg-white text-slate-900","dark:bg-slate-900 dark:text-slate-100"),children:[s&&e.jsx("title",{children:s}),e.jsxs("div",{className:I("px-6 pt-4","w-full","md:max-w-lg","flex flex-row items-start","md:flex-col md:items-end","md:self-stretch","md:max-w-fix md:w-1/2 md:p-4","md:text-right","md:dark:border-r md:dark:border-slate-700","md:bg-slate-100 md:dark:bg-slate-800"),children:[e.jsxs("div",{className:"grid grow content-center md:justify-items-end",children:[s&&e.jsx("h1",{className:"text-primary text-xl font-semibold md:my-4 md:text-2xl lg:text-5xl",children:s},"title"),n&&e.jsx("p",{className:"hidden max-w-xs text-slate-600 md:block dark:text-slate-400",children:n},"subtitle")]}),e.jsx(Ce,{className:"m-1 md:m-2"},"localeSelector")]}),e.jsx("main",{className:"w-full p-6 md:max-w-3xl md:px-12",children:t})]})}function ze(t,s,n){if(!t)return[s];const a=t.findIndex(n);return a===-1?[...t,s]:[...t.slice(0,a),s,...t.slice(a+1)]}function q(t,s){const{showBoundary:n}=Ze();return l.useCallback(async(...a)=>{try{return await t(...a)}catch(r){throw r instanceof Re&&n(r),r}},s.concat(n))}function We({sessions:t=[],onRedirected:s}){const[n]=l.useState(()=>new Ee),[a,r]=l.useState(t),{i18n:i,_:o}=R(),{locale:d}=i,c=l.useCallback(b=>{r(p=>{var y;return b===(((y=p.find(k=>k.selected))==null?void 0:y.account.sub)||null)?p:p.map(k=>({...k,selected:k.account.sub===b}))})},[r]),x=l.useCallback(({account:b,ephemeralToken:p,consentRequired:y=!0,selected:k=!0,loginRequired:N=!1})=>{const C={account:b,ephemeralToken:p,selected:k,loginRequired:N,consentRequired:y};r(P=>ze(P,C,L=>L.account.sub===b.sub).map(L=>!k||L===C||!L.selected?L:{...L,selected:!1}))},[r]),u=l.useCallback(b=>{window.location.href=String(b),s&&setTimeout(s)},[s]),j=q(async(b,p)=>{const y=await n.fetch("POST","/sign-in",{...b,locale:d},{signal:p});x(y)},[n,d,x]),f=q(async(b,p)=>{await n.fetch("POST","/reset-password-request",{...b,locale:d},{signal:p})},[n,d]),h=q(async(b,p)=>{await n.fetch("POST","/reset-password-confirm",b,{signal:p})},[n]),w=q(async(b,p)=>{await n.fetch("POST","/verify-handle-availability",b,{signal:p})},[n]),_=q(async(b,p)=>{const y=await n.fetch("POST","/sign-up",{...b,locale:d},{signal:p});x(y)},[n,d,x]),g=q(async b=>{var k;const p=(k=a.find(N=>N.account.sub===b))==null?void 0:k.ephemeralToken,{url:y}=await n.fetch("POST","/accept",{sub:b},{bearer:p});u(y)},[n,a,u]),v=q(async()=>{const{url:b}=await n.fetch("POST","/reject",{});u(b)},[n,u]);return{sessions:a,selectSub:c,doSignIn:j,doInitiatePasswordReset:f,doConfirmResetPassword:h,doValidateNewHandle:w,doSignUp:_,doAccept:g,doReject:v}}function D(t,s){return l.useCallback(()=>t(s),[t,s])}function A({color:t="grey",transparent:s=!1,loading:n=void 0,square:a=!1,children:r,className:i,type:o="button",role:d="Button",disabled:c=!1,...x}){return e.jsx("button",{role:d,type:o,disabled:c||n===!0,...x,className:I("cursor-pointer touch-manipulation overflow-hidden truncate rounded-md tracking-wide",a?"p-2":"px-6 py-2",t==="primary"?I("accent-slate-100",s?"text-primary bg-transparent":"bg-primary text-primary-contrast"):t==="grey"?I("accent-primary","text-slate-600 dark:text-slate-300","hover:bg-gray-200 dark:hover:bg-gray-700",s?"bg-transparent":"bg-gray-100 dark:bg-gray-800"):void 0,"disabled:opacity-50",i),children:r})}function ue({actions:t,cancel:s,append:n,children:a,prepend:r,disabled:i,inert:o=i,...d}){return e.jsxs("form",{...d,inert:o,className:"flex flex-col space-y-4",children:[r&&e.jsx("div",{children:r},"prepend"),e.jsx("div",{className:"space-y-4",children:a},"children"),n&&e.jsx("div",{children:n},"append"),(t||s)&&e.jsxs("div",{className:"flex flex-row-reverse flex-wrap items-center justify-end space-x-2 space-x-reverse",children:[t,e.jsx("div",{className:"flex-auto"}),s]},"buttons")]})}function Ye({account:t,...s}){return e.jsx("b",{...s,children:t.preferred_username||t.email||t.sub})}function Je({url:t,proto:s=!1,host:n=!0,path:a=!1,query:r=!1,hash:i=!1,as:o="span",...d}){const c=l.useMemo(()=>t instanceof URL?t:new URL(t),[t]);return e.jsxs(o,{...d,children:[s&&e.jsx(z,{value:`${c.protocol}//`,...s===!0?null:s}),n&&e.jsx(z,{value:c.host,...n===!0?{faded:!1,bold:!0}:n}),a&&e.jsx(z,{value:c.pathname,...a===!0?null:a}),r&&e.jsx(z,{value:c.search,...r===!0?null:r}),i&&e.jsx(z,{value:c.hash,...i===!0?null:i})]})}function z({value:t,faded:s=!0,bold:n=!1}){const a=n?"b":"span";return e.jsx(a,{className:s?"opacity-50":"",children:t})}function Qe({clientId:t,clientMetadata:s,clientTrusted:n,...a}){const r=l.useMemo(()=>{try{return new URL(t)}catch{return null}},[t]);if(n&&s.client_name)return e.jsx("span",{...a,children:s.client_name});if((r==null?void 0:r.protocol)==="http:")return e.jsx("span",{...a,children:e.jsx(m,{id:"eYNzrj"})});if((r==null?void 0:r.protocol)==="https:"){const i=r.protocol==="https:"&&r.pathname==="/oauth-client-metadata.json"&&!r.port&&!r.search;return e.jsx(Je,{...a,url:r,proto:!i,host:!0,path:!i,query:!i,hash:!1})}return e.jsx("span",{...a,children:t})}function et({clientId:t,clientMetadata:s,clientTrusted:n,account:a,scopeDetails:r,onAccept:i,onReject:o,onBack:d,...c}){const{i18n:x,_:u}=R();return e.jsxs(ue,{...c,onSubmit:j=>{j.preventDefault(),i()},cancel:d&&e.jsx(A,{onClick:d,children:"Back"}),actions:e.jsxs(e.Fragment,{children:[e.jsx(A,{type:"submit",color:"primary",children:e.jsx(m,{id:"yIVrHZ"})}),e.jsx(A,{onClick:o,children:e.jsx(m,{id:"54JiGG"})})]}),children:[n&&s.logo_uri&&e.jsx("div",{className:"flex items-center justify-center",children:e.jsx("img",{crossOrigin:"anonymous",src:s.logo_uri,alt:s.client_name,className:"h-16 w-16 rounded-full"})},"logo"),e.jsx("p",{children:e.jsx(m,{id:"BVbdlE",components:{0:e.jsx(Qe,{clientId:t,clientMetadata:s,clientTrusted:n}),1:e.jsx(Ye,{account:a})}})}),e.jsx("p",{children:e.jsx(m,{id:"/aj5l4",components:{0:e.jsx("b",{}),1:e.jsx("a",{role:"link",href:s.tos_uri,rel:"nofollow noopener",target:"_blank",className:"text-primary underline"}),2:e.jsx("a",{role:"link",href:s.policy_uri,rel:"nofollow noopener",target:"_blank",className:"text-primary underline"})}})}),r!=null&&r.length?e.jsx("ul",{className:"list-inside list-disc","aria-label":x._({id:"c7cY3z"}),children:r.map(({scope:j,description:f})=>e.jsx("li",{children:f?e.jsx(Le,{value:f}):e.jsx(tt,{scope:j})},j))},"scopes"):null]})}function tt({scope:t}){switch(t){case"atproto":return e.jsx(m,{id:"BWM1dL"});case"transition:generic":return e.jsx(m,{id:"myiH7A"});case"transition:chat.bsky":return e.jsx(m,{id:"kJrqQq"});default:return t}}function st({clientId:t,clientMetadata:s,clientTrusted:n,account:a,scopeDetails:r,onAccept:i,onReject:o,onBack:d,title:c,subtitle:x=e.jsx(m,{id:"QdVx1C",values:{0:a.preferred_username||a.email||a.sub},components:{0:e.jsx("b",{className:"text-slate-800 dark:text-slate-200"})}}),...u}){const{i18n:j,_:f}=R();return e.jsx(T,{...u,title:c??j._({id:"yIVrHZ"}),subtitle:x,children:e.jsx(et,{clientId:t,clientMetadata:s,clientTrusted:n,account:a,scopeDetails:r,onBack:d,onAccept:i,onReject:o})})}const oe=l.createContext({disabled:!1});oe.displayName="FieldsetContext";function U({label:t,children:s,disabled:n,...a}){const r=ae({prefix:"fieldset-"}),i=l.useMemo(()=>({disabled:n??!1,labelId:t?r:void 0}),[n,t,r]);return e.jsxs("fieldset",{...a,"aria-labelledby":r,disabled:n,children:[t&&e.jsx("legend",{id:r,className:"mb-1 text-sm font-medium text-slate-600 dark:text-slate-400",children:t},"title"),e.jsx("div",{className:"flex flex-col space-y-4",children:e.jsx(oe,{value:i,children:s})})]})}function nt(t,{ref:s,onLoading:n,onError:a}={}){const[r,i]=l.useState(!1),[o,d]=l.useState(),c=l.useCallback(h=>{d(h),a==null||a(h)},[a]),x=l.useCallback(h=>{i(h),n==null||n(h)},[n]),u=l.useRef(null),j=l.useRef(null);l.useEffect(()=>(j.current=()=>{var h;(h=u.current)==null||h.abort(),u.current=null,c(void 0),x(!1)},()=>{j.current=null}),[c,x]),l.useImperativeHandle(s,()=>({reset:()=>{var h;return(h=j.current)==null?void 0:h.call(j)}}),[]),l.useEffect(()=>()=>{var h;(h=u.current)==null||h.abort(),u.current=null},[]);const f=l.useCallback(async()=>{var _;(_=u.current)==null||_.abort(),x(!0),c(void 0);const h=new AbortController,{signal:w}=h;u.current=h;try{await t(w)}catch(g){h===u.current?c(g instanceof Error?g:new Error(String(g))):rt(w,g)||console.warn("Async action error after abort",g)}finally{h===u.current&&(u.current=null,x(!1)),h.abort()}},[t,x,c]);return{loading:r,error:o,run:f}}function rt(t,s){return t.aborted&&(t.reason===s||t.reason===(s==null?void 0:s.cause)||s instanceof DOMException&&s.name==="AbortError")}const at=({error:t})=>e.jsx(Ie,{error:t});function G({invalid:t,disabled:s,onSubmit:n,submitLabel:a,onCancel:r=void 0,cancelLabel:i,errorRender:o=at,ref:d,onLoading:c,onError:x,children:u,...j}){const{run:f,loading:h,error:w}=nt(n,{ref:d,onError:x,onLoading:c}),_=l.useCallback(g=>{g.preventDefault(),g.currentTarget.reportValidity()&&!s&&!t&&f()},[s,t,f]);return e.jsx(ue,{...j,onSubmit:_,disabled:s||h,prepend:w!=null?o({error:w}):void 0,cancel:r&&e.jsx(A,{onClick:r,children:i||e.jsx(m,{id:"dEgA5A"})}),actions:e.jsx(A,{color:"primary",type:"submit",loading:h,disabled:s,children:a||e.jsx(m,{id:"hQRttt"})}),children:u})}const V=8,it=/(\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/,J=/[A-Z]/,Q=/[a-z]/,ee=/[0-9]/,te=/[^a-zA-Z0-9]/;var K=function(t){return t[t.weak=1]="weak",t[t.moderate=2]="moderate",t[t.strong=3]="strong",t[t.extra=4]="extra",t}({});function ye(t){return t.length<V?1:t.length>=V+12?4:t.length>=V+8?H(t,[te])||H(t,[J,Q,ee],2)?4:3:t.length>=V&&H(t,[it])?3:t.length>=V+6?H(t,[te])||H(t,[J,Q,ee],2)?3:2:t.length>=V+4?H(t,[te])||H(t,[J,Q,ee],2)?2:1:t.length>=V&&(H(t,[te])||H(t,[J,Q,ee]))?2:1}function H(t,s,n=s.length){if(n<1||n>s.length)throw new TypeError("Invalid regexpsCountToMatch");for(const a of s)if(a.test(t)&&(n--,n===0))return!0;return!1}function lt({password:t,...s}){const{i18n:n,_:a}=R(),r=ye(t);return e.jsx("span",{...s,"aria-label":n._({id:"osAB4a"}),children:r===K.extra?e.jsx(m,{id:"/Ltc/k"}):r===K.strong?e.jsx(m,{id:"LLx/nr"}):r===K.moderate?e.jsx(m,{id:"dvYuhh"}):t?e.jsx(m,{id:"9ls/Vs"}):e.jsx(m,{id:"VU3Nrn"})})}function ot({password:t,className:s,...n}){const{i18n:a,_:r}=R(),i=t?ye(t):0,o="bg-gray-300 dark:bg-slate-500",d=i===K.extra||i===K.strong?"bg-success":i===K.moderate?"bg-warning":"bg-error";return e.jsx("div",{...n,className:I("flex h-1 w-full space-x-2",s),role:"meter","aria-label":a._({id:"xfNKwI"}),"aria-valuemin":0,"aria-valuemax":K.extra,"aria-valuenow":i,children:Array.from({length:4},(c,x)=>e.jsx("div",{className:`h-1 w-1/4 rounded-sm ${i>x?d:o}`},x))})}function ct(t,s){typeof t=="function"?t(s):t&&(t.current=s)}function B(t){return s=>{for(const n of t)n&&ct(n,s)}}function dt({visible:t,toggleVisible:s,onClick:n,...a}){const{i18n:r,_:i}=R();return e.jsx(A,{...a,square:!0,onClick:o=>{n==null||n(o),o.defaultPrevented||s()},"aria-label":t?r._({id:"vLyv1R"}):r._({id:"huXYDE"}),children:t?e.jsx(Pe,{className:"w-5","aria-hidden":!0}):e.jsx(Ae,{className:"w-5","aria-hidden":!0})})}function ne({icon:t,append:s,bellow:n,className:a,children:r,onFocus:i,onBlur:o,...d}){const[c,x]=l.useState(!1);return e.jsxs("div",{...d,onFocus:u=>{i==null||i(u),u.defaultPrevented||x(!0)},onBlur:u=>{o==null||o(u),u.defaultPrevented||x(!1)},className:I("min-h-12","max-w-full","overflow-hidden","rounded-lg",a),children:[e.jsxs("div",{className:I("px-1","min-h-12 w-full","flex items-center justify-stretch","rounded-lg",n?"rounded-bl-none rounded-br-none":void 0,"outline-hidden","border-2 border-solid border-transparent","focus:border-primary has-focus:border-primary","hover:border-gray-400 hover:focus:border-gray-400","dark:hover:border-gray-500 dark:hover:focus:border-gray-500","has-focus:bg-slate-200 bg-gray-100 focus:bg-slate-200","dark:has-focus:bg-slate-700 dark:bg-slate-800 dark:focus:bg-slate-700","text-slate-600 dark:text-slate-300","accent-primary"),children:[t&&e.jsx("div",{className:I("shrink-0 grow-0","mx-1",c?"text-primary":"text-slate-500"),children:t}),r,e.jsx("div",{className:"ml-1 flex shrink-0 grow-0 items-center",children:s})]}),n&&e.jsx("div",{className:I("space-x-2 px-3 py-2","flex flex-row items-center gap-1","rounded-br-2 rounded-bl-2","bg-gray-200 dark:bg-slate-700","text-gray-700 dark:text-gray-300","text-sm italic"),children:n})]})}function Z({icon:t,append:s,bellow:n,className:a,onFocus:r,onBlur:i,ref:o,disabled:d,title:c,"aria-label":x=c,"aria-labelledby":u,placeholder:j=x,...f}){const h=l.useContext(oe),w=l.useRef(null),_=l.useRef(!1);return e.jsx(ne,{icon:t,append:s,bellow:n,className:I("cursor-text",a),tabIndex:-1,onClick:g=>{var v;w.current!==g.target&&(g.preventDefault(),g.stopPropagation(),(v=w.current)==null||v.focus())},onMouseDown:g=>{_.current&&g.target!==w.current&&(g.preventDefault(),g.stopPropagation())},children:e.jsx("input",{...f,disabled:d??h.disabled,title:c,placeholder:j,"aria-label":x,"aria-labelledby":u??h.labelId,ref:B([o,w]),className:"outline-hidden w-full text-ellipsis bg-transparent bg-clip-padding text-base text-inherit dark:placeholder-gray-500",onFocus:g=>{r==null||r(g),g.defaultPrevented||(_.current=!0)},onBlur:g=>{i==null||i(g),g.defaultPrevented||(_.current=!1)}})})}function _e({autoHide:t=!0,onBlur:s,onChange:n,append:a,autoComplete:r="current-password",icon:i=e.jsx(Te,{className:"w-5"}),value:o,defaultValue:d=o,ref:c,title:x,dir:u="auto",autoCapitalize:j="none",autoCorrect:f="off",spellCheck:h="false",...w}){const{i18n:_,_:g}=R(),v=l.useRef(null),[b,p]=l.useState(!1),[y,k]=l.useState(typeof d=="string"?d:""),N=l.useCallback(C=>{n==null||n(C),k(C.target.value)},[n]);return e.jsx(Z,{...w,title:x??_._({id:"8ZsakT"}),ref:B([c,v]),dir:u,autoCapitalize:j,autoCorrect:f,spellCheck:h,icon:i,onBlur:t?C=>{s==null||s(C),C.defaultPrevented||p(!1)}:s,value:y,onChange:N,type:b?"text":"password",autoComplete:r,append:e.jsxs(e.Fragment,{children:[e.jsx(dt,{className:"m-1",visible:b,toggleVisible:()=>{var C;p(P=>!P),(C=v.current)==null||C.focus()}}),a]})})}function we({password:t="",onPassword:s,onChange:n,autoComplete:a="new-password",minLength:r=V,...i}){const{i18n:o,_:d}=R(),[c,x]=l.useState(t),u=l.useCallback(j=>{const{value:f}=j.target;n==null||n(j),!j.defaultPrevented&&(x(f),s==null||s(j.target.validity.valid?f:void 0))},[n,s]);return e.jsx(_e,{...i,placeholder:o._({id:"3tOlz6"}),"aria-label":o._({id:"0StR7t"}),title:o._({id:"5CqSPX",values:{MIN_PASSWORD_LENGTH:V}}),minLength:r,onChange:u,value:c,autoComplete:a,bellow:e.jsxs(e.Fragment,{children:[e.jsx(ot,{password:c}),e.jsx(lt,{className:"grow-1 min-w-max text-xs text-gray-500 dark:text-gray-400",password:c})]})})}const ut="XXXXX-XXXXX";function ve({example:t=ut,onToken:s,icon:n=e.jsx(pe,{className:"w-5"}),title:a=t,onChange:r,value:i,defaultValue:o=i,...d}){const{i18n:c,_:x}=R(),[u,j]=l.useState(typeof o=="string"?o:"");return e.jsx(Z,{...d,type:"text",autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:"false",minLength:11,maxLength:11,dir:"auto",icon:n,pattern:"^[A-Z2-7]{5}-[A-Z2-7]{5}$",placeholder:c._({id:"0hTJM+",values:{example:t}}),title:a,value:u,onChange:f=>{const{value:h,selectionEnd:w,selectionStart:_}=f.currentTarget,g=me(h);f.currentTarget.value=g;const v=w??_;if(v!=null){const b=me(h.slice(0,v));f.currentTarget.selectionStart=f.currentTarget.selectionEnd=b.length}j(g),r==null||r(f),f.isDefaultPrevented()||s==null||s(g.length===11?g:null)}})}function me(t){const s=t.toUpperCase().replaceAll(/[^A-Z2-7]/g,"");return s.length<=5?s:`${s.slice(0,5)}-${s.slice(5,10)}`}function xt({onSubmit:t,invalid:s,...n}){const a=ae({prefix:"reset-pwd-email-"}),r=l.useRef(null),[i,o]=l.useState(null),[d,c]=l.useState(void 0);return e.jsxs(G,{...n,onSubmit:x=>{if(i&&d)return t({token:i,password:d},x)},invalid:s||!i||!d,children:[e.jsx(ie,{role:"info",children:e.jsx("p",{id:a,className:"text-md",children:e.jsx(m,{id:"imRJNy"})})}),e.jsx(U,{label:e.jsx(m,{id:"vJgYMA"}),children:e.jsx(ve,{name:"code","aria-labelledby":a,enterKeyHint:"next",required:!0,autoFocus:!0,onToken:x=>{var u;o(x),x&&((u=r.current)==null||u.focus())}})}),e.jsx(U,{label:e.jsx(m,{id:"/nT6AE"}),children:e.jsx(we,{ref:r,name:"password",enterKeyHint:"done",required:!0,password:d,onPassword:c})})]})}function ke({onEmail:t,autoCapitalize:s="none",autoComplete:n="email",autoCorrect:a="off",dir:r="auto",icon:i=e.jsx(le,{className:"w-5"}),onBlur:o,onChange:d,pattern:c="^[^@]+@[^@]+\\.[^@]+$",spellCheck:x="false",value:u,defaultValue:j=u,title:f,...h}){const{i18n:w,_}=R(),[g,v]=l.useState(typeof j=="string"?j:""),b=l.useCallback(p=>{const y=p.target.value.toLowerCase();v(y),d==null||d(p),t==null||t(p.target.validity.valid?y:void 0)},[d,t]);return e.jsx(Z,{...h,title:f??w._({id:"ATGYL1"}),type:"email",autoCapitalize:s,autoCorrect:a,dir:r,spellCheck:x,icon:i,pattern:c,autoComplete:n,value:g,onChange:b,onBlur:o})}function ft({emailDefault:t,onSubmit:s,invalid:n,ref:a,...r}){const{i18n:i,_:o}=R(),d=ae({prefix:"reset-pwd-email-"}),[c,x]=l.useState(t),u=l.useRef(null),j=l.useCallback(f=>{if(c)return s({email:c},f)},[c,s]);return e.jsx(G,{...r,ref:B([a,u]),invalid:n||!c,onSubmit:j,children:e.jsxs(U,{label:e.jsx(m,{id:"ATGYL1"}),children:[e.jsx(ke,{name:"email",placeholder:i._({id:"xRPn3U"}),"aria-labelledby":d,title:i._({id:"ATGYL1"}),required:!0,autoFocus:!0,value:c,onEmail:f=>{var h;(h=u.current)==null||h.reset(),x(f)}}),e.jsx(ie,{role:"info",children:e.jsx("p",{id:d,className:"",children:e.jsx(m,{id:"cHrOqs"})})})]})})}function mt({emailDefault:t,onresetPasswordRequest:s,onResetPasswordConfirm:n,onBack:a,...r}){const{i18n:i,_:o}=R(),[d,c]=l.useState(0);if(d===0)return e.jsxs(T,{...r,title:r.title||i._({id:"dn8X5t"}),subtitle:r.subtitle||e.jsx(m,{id:"Esfg1M"}),children:[e.jsx(ft,{emailDefault:t,submitLabel:e.jsx(m,{id:"hXzOVo"}),onSubmit:async(x,u)=>{await s(x,u),u.aborted||c(1)},cancelLabel:e.jsx(m,{id:"iH8pgl"}),onCancel:a}),e.jsx("hr",{className:"my-5 border-gray-300 dark:border-gray-700"}),e.jsx("center",{children:e.jsx(A,{transparent:!0,onClick:()=>c(1),children:e.jsx(m,{id:"FTT4a4"})})})]});if(d===1)return e.jsx(T,{...r,title:r.title||i._({id:"KbS2K9"}),subtitle:r.subtitle||e.jsx(m,{id:"xg/UcZ"}),children:e.jsx(xt,{submitLabel:e.jsx(m,{id:"hXzOVo"}),onSubmit:async(x,u)=>{await n(x,u),u.aborted||c(2)},cancelLabel:e.jsx(m,{id:"iH8pgl"}),onCancel:a})});if(d===2)return e.jsx(T,{...r,title:r.title||i._({id:"fSy6T1"}),subtitle:r.subtitle||e.jsx(m,{id:"+qGdcW"}),children:e.jsxs("center",{children:[e.jsx("h2",{className:"pb-2 text-xl font-bold",children:e.jsx(m,{id:"DKeVgZ"})}),e.jsx("p",{className:"pb-4",children:e.jsx(m,{id:"67nRLM"})}),e.jsx(A,{color:"primary",onClick:a,children:e.jsx(m,{id:"UaXeX3"})})]})});throw new Error(`Invalid view: ${d}`)}function ht({className:t,children:s,id:n,ref:a,disabled:r,title:i,"aria-label":o=i,"aria-labelledby":d,...c}){const x=ae("input-checkbox-"),u=l.useRef(null),j=l.useRef(null),f=l.useContext(oe),h=n??x;return e.jsx(ne,{className:I("cursor-pointer",t),icon:e.jsx("input",{...c,disabled:r??f.disabled,title:i,"aria-label":o,"aria-labelledby":s?void 0:d??f.labelId,ref:B([a,j]),id:h,className:"accent-primary outline-hidden",type:"checkbox"}),tabIndex:-1,onClick:({target:w})=>{var _;w!==u.current&&w!==j.current&&((_=j.current)==null||_.click())},children:s&&e.jsx("label",{ref:u,htmlFor:h,className:"block w-full cursor-pointer select-none leading-[1.6]",children:s})})}function se({usernameDefault:t="",usernameReadonly:s=!1,rememberDefault:n=!1,onSubmit:a,onBack:r,onForgotPassword:i,ref:o,invalid:d,children:c,...x}){const{i18n:u,_:j}=R(),[f,h]=l.useState(t),[w,_]=l.useState(""),[g,v]=l.useState(n),[b,p]=l.useState(null),[y,k]=l.useState(null),[N,C]=l.useState(!1),P=l.useRef(null),L=l.useCallback(()=>{p(null),k(null)},[p,k]),O=l.useCallback(()=>{var E;L(),(E=P.current)==null||E.reset()},[L,P]),S=l.useCallback(async E=>{try{await a({username:f,password:w,remember:g,...y?{[y.type]:b}:{}},E)}catch($){if(E.aborted)return;if($ instanceof $e){k($);return}throw $ instanceof He&&L(),$}},[f,w,g,y,b,a]);return e.jsxs(G,{...x,ref:B([o,P]),onLoading:C,onCancel:r,cancelLabel:u._({id:"iH8pgl"}),append:c,invalid:d||!f||!w||y!=null&&!b,submitLabel:y?u._({id:"7VpPHA"}):u._({id:"5lWFkC"}),onSubmit:S,children:[e.jsx(U,{disabled:N,label:e.jsx(m,{id:"sJGljQ"}),children:e.jsx(Z,{icon:e.jsx(le,{className:"w-5"}),name:"username",type:"text",title:u._({id:"nZx9mr"}),autoCapitalize:"none",autoCorrect:"off",autoComplete:"username",spellCheck:"false",dir:"auto",enterKeyHint:"next",required:!0,readOnly:s,disabled:s,autoFocus:!0,value:f,onChange:E=>{O(),h(E.target.value)}})}),e.jsx(U,{disabled:N,label:e.jsx(m,{id:"8ZsakT"}),children:e.jsx(_e,{name:"password",onChange:E=>{O(),_(E.target.value)},append:i&&e.jsx(A,{className:"text-sm",type:"button",onClick:()=>{i(f!=null&&f.includes("@")?f:void 0)},"aria-label":u._({id:"slOprG"}),children:e.jsx(m,{id:"F4OP4y"})}),enterKeyHint:y?"next":"done",disabled:N,required:!0})}),e.jsxs(ie,{role:"status",children:[e.jsx("p",{className:"text-md text-primary pb-1 font-bold",children:e.jsx(m,{id:"r6y+jM"})}),e.jsx("p",{className:"text-sm",children:e.jsx(m,{id:"+Z2ZNt"})})]}),e.jsx(ht,{name:"remember",title:u._({id:"1TxdLU"}),enterKeyHint:y?"next":"done",checked:g,onChange:E=>v(E.target.checked),children:e.jsx(m,{id:"1TxdLU"})}),y&&e.jsx(U,{disabled:N,label:e.jsx(m,{id:"4blS0m"}),children:e.jsxs("div",{children:[e.jsx(ve,{title:u._({id:"ioZOzk"}),enterKeyHint:"done",required:!0,autoFocus:!0,value:b??"",onToken:p}),e.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:e.jsx(m,{id:"B+Yy3b",values:{0:y.hint}})})]})},"2fa")]})}function jt({src:t,alt:s}){const[n,a]=l.useState(!1);return l.useEffect(()=>{a(!1)},[t]),t&&!n?e.jsx("img",{"aria-hidden":!0,crossOrigin:"anonymous",src:t,alt:s,className:"-ml-1 h-6 w-6 rounded-full",onError:()=>a(!0)}):e.jsx("div",{"aria-hidden":!0,className:"bg-primary border-primary h-6 w-6 overflow-hidden rounded-full border-2 border-solid text-white",children:e.jsx(Ve,{className:"-mx-1 -mb-1"})})}function bt({accounts:t,onAccount:s,onOther:n=void 0,onBack:a,children:r,...i}){const{i18n:o,_:d}=R();return e.jsxs(ue,{...i,append:r,actions:null,cancel:a&&e.jsx(A,{onClick:a,children:e.jsx(m,{id:"iH8pgl"})}),children:[e.jsx("p",{className:"text-sm font-medium text-slate-600 dark:text-slate-400",children:e.jsx(m,{id:"FT1MVS"})}),t.map(c=>{const[x,u]=[c.name,c.preferred_username,c.email,c.sub].filter(Boolean);return e.jsx(ne,{tabIndex:0,onKeyDown:j=>{(j.key==="Enter"||j.key===" ")&&s(c)},onClick:()=>s(c),role:"button","aria-label":o._({id:"N9o7n5",values:{0:c.name}}),icon:e.jsx(jt,{src:c.picture,alt:x}),append:e.jsx(xe,{"aria-hidden":!0,className:"h-4"}),children:e.jsxs("span",{className:"flex flex-wrap items-center",children:[e.jsx("span",{className:"mr-2 truncate font-medium","arial-label":o._({id:"6YtxFj"}),children:x}),u&&e.jsx("span",{className:"truncate text-sm text-neutral-500 dark:text-neutral-400","arial-label":o._({id:"sJGljQ"}),children:u})]})},c.sub)}),n&&e.jsx(ne,{tabIndex:0,onKeyDown:c=>{(c.key==="Enter"||c.key===" ")&&n()},onClick:n,"aria-label":o._({id:"cR9UpQ"}),role:"button",append:e.jsx(xe,{"aria-hidden":!0,className:"h-4"}),icon:e.jsx(le,{"aria-hidden":!0,className:"h-4"}),children:e.jsx("span",{className:"truncate text-slate-700 dark:text-slate-400",children:e.jsx(m,{id:"+TaG50"})})},"other")]})}function pt({loginHint:t,sessions:s,selectSub:n,onSignIn:a,onForgotPassword:r,onBack:i,title:o,subtitle:d,...c}){const{i18n:x,_:u}=R(),j=l.useMemo(()=>s.find(g=>g.selected),[s]),f=l.useCallback(()=>n(null),[n]),h=l.useMemo(()=>s.map(g=>g.account),[s]),[w,_]=l.useState(s.length===0);return o??(o=x._({id:"5lWFkC"})),l.useEffect(()=>{j&&_(!1)},[j]),j?j.loginRequired?e.jsx(T,{...c,title:o,subtitle:d??e.jsx(m,{id:"HaGV2g"}),children:e.jsx(se,{onSubmit:a,onForgotPassword:r,onBack:f,usernameDefault:j.account.preferred_username||j.account.sub,usernameReadonly:!0,rememberDefault:!0})}):null:t?e.jsx(T,{...c,title:o,subtitle:d??e.jsx(m,{id:"NgaR6B"}),children:e.jsx(se,{onSubmit:a,onForgotPassword:r,onBack:i,usernameDefault:t,usernameReadonly:!0})}):s.length===0?e.jsx(T,{...c,title:o,subtitle:d??e.jsx(m,{id:"T0KLp4"}),children:e.jsx(se,{onSubmit:a,onForgotPassword:r,onBack:i})}):w?e.jsx(T,{...c,title:o,subtitle:d??e.jsx(m,{id:"T0KLp4"}),children:e.jsx(se,{onSubmit:a,onForgotPassword:r,onBack:()=>_(!1)})}):e.jsx(T,{...c,title:o,subtitle:d??e.jsx(m,{id:"o3dwub"}),children:e.jsx(bt,{accounts:h,onAccount:g=>n(g.sub),onOther:()=>_(!0),onBack:i})})}const F=t=>t!=null&&t!==!1,gt=t=>F(t)&&t.invalid===!0,yt=t=>!F(t)||t.invalid===!1;function _t(t){const s=t.findIndex(F),n=t.findLastIndex(F),a=t.findIndex(gt),[r,i]=l.useState(s),o=l.useCallback(p=>p!==-1&&t[p]?(i(p),!0):!1,[t.map(F).join()]),d=t.findLastIndex((p,y)=>F(p)&&y<r),c=t.findIndex((p,y)=>F(p)&&y>r),x=l.useCallback(()=>o(s),[o,s]),u=l.useCallback(()=>o(n),[o,n]),j=l.useCallback(()=>o(d),[o,d]),f=l.useCallback(()=>o(c),[o,c]),h=l.useCallback(()=>o(a),[o,a]),w=r+1+t.reduce((p,y,k)=>k>=r||F(y)?p:p-1,0),_=t.filter(F).length,g=t.every(yt),v=r===-1||!t[r]?void 0:t[r],b=r===-1;return l.useEffect(()=>{b&&x()},[b]),{current:v,currentPosition:w,count:_,completed:g,atFirst:w===1,atLast:w===_,toFirst:x,toLast:u,toPrev:j,toNext:f,toRequired:h}}function wt({prevLabel:t,nextLabel:s,onBack:n,backLabel:a,onDone:r,doneLabel:i,steps:o,className:d,...c}){var N,C;const{atFirst:x,atLast:u,count:j,current:f,currentPosition:h,completed:w,toNext:_,toPrev:g,toRequired:v}=_t(o),b=l.useCallback(()=>{_()||v()},[_,v]),p={current:!0,invalid:f?f.invalid:!1,prevLabel:x&&a||t||e.jsx(m,{id:"iH8pgl"}),prev:x?n:g,nextLabel:u&&i||s||e.jsx(m,{id:"hXzOVo"}),next:u&&w?r:b},y=(N=f==null?void 0:f.titleRender)==null?void 0:N.call(f,p),k=(C=f==null?void 0:f.contentRender)==null?void 0:C.call(f,p);return e.jsxs("div",{className:I(d,"flex flex-col"),...c,children:[e.jsx("p",{className:"text-slate-500 dark:text-slate-400",children:e.jsx(m,{id:"BEx8rG",values:{currentPosition:h,count:j}})}),y&&e.jsx("h2",{className:"mb-4 text-xl font-medium",children:y}),k]})}function vt({links:t,className:s,...n}){const a=t==null?void 0:t.find(r=>r.rel==="help");return a?e.jsx("p",{...n,className:I("rounded-md bg-slate-100 p-3 text-sm text-slate-800 dark:bg-slate-800 dark:text-slate-400",s),children:e.jsx(m,{id:"87VTIH",components:{0:e.jsx("a",{role:"link",href:a.href,rel:a.rel,target:"_blank",className:"text-primary"})}})}):null}function kt({inviteCodeRequired:t=!0,credentials:s,onCredentials:n,onNext:a,nextLabel:r,onPrev:i,prevLabel:o,children:d,ref:c,invalid:x,...u}){const{i18n:j,_:f}=R(),[h,w]=l.useState(s==null?void 0:s.email),[_,g]=l.useState(s==null?void 0:s.password),[v,b]=l.useState(s==null?void 0:s.inviteCode),p=l.useRef(null),y=()=>{var N;return(N=p.current)==null?void 0:N.reset()},k=l.useMemo(()=>h&&_&&(!t||v)?{email:h,password:_,inviteCode:t?v:void 0}:void 0,[h,_,v,t]);return l.useEffect(()=>{n==null||n(k)},[k,n]),e.jsxs(G,{...u,ref:B([c,p]),invalid:x||!k,onCancel:i,cancelLabel:o,onSubmit:a,submitLabel:r,append:d,children:[t&&e.jsx(U,{label:e.jsx(m,{id:"6KlkHI"}),children:e.jsx(Z,{icon:e.jsx(pe,{className:"w-5"}),autoFocus:!0,name:"inviteCode",title:j._({id:"6KlkHI"}),placeholder:j._({id:"jxqcgY"}),required:!0,value:v||"",onChange:N=>{b(N.target.value||void 0),y()},enterKeyHint:"next"})}),e.jsx(U,{label:e.jsx(m,{id:"O3oNi5"}),children:e.jsx(ke,{autoFocus:!t,name:"email",enterKeyHint:"next",required:!0,defaultValue:h,onEmail:N=>{w(N),y()}})}),e.jsx(U,{label:e.jsx(m,{id:"8ZsakT"}),children:e.jsx(we,{name:"password",enterKeyHint:"next",required:!0,password:_,onPassword:N=>{g(N),y()}})})]})}function de({links:t,className:s,...n}){const a=t==null?void 0:t.find(i=>i.rel==="terms-of-service"),r=t==null?void 0:t.find(i=>i.rel==="privacy-policy");return e.jsx("p",{className:I("text-sm text-slate-500 dark:text-slate-400",s),...n,children:e.jsx(m,{id:"mBUXx0",values:{0:a?e.jsx(fe,{className:"text-primary underline",link:a,children:e.jsx(m,{id:"xowcRf"})}):e.jsx(m,{id:"xowcRf"}),1:r?e.jsx(fe,{className:"text-primary underline",link:r,children:e.jsx(m,{id:"LcET2C"})}):e.jsx(m,{id:"LcET2C"})}})})}const St=18,Se=3,Ne=30,Nt=t=>Se+t.length<=Ne&&t.startsWith(".")&&!t.endsWith(".");function Ct(t){const s=Se,n=Math.min(St,Ne-t.length),a=l.useCallback(r=>{const i=r.length>=s&&r.length<=n,o=/^[a-z0-9][a-z0-9-]+[a-z0-9]$/g.test(r);return{validLength:i,validCharset:o,valid:i&&o}},[n,s]);return{minLength:s,maxLength:n,validateSegment:a}}function Et({domains:t,onNext:s,nextLabel:n,onPrev:a,prevLabel:r,handle:i,onHandle:o,invalid:d,children:c,ref:x,...u}){const{i18n:j,_:f}=R(),h=t.filter(Nt),w=l.useRef(null),[_,g]=l.useState(()=>{const S=h.findIndex(E=>i==null?void 0:i.endsWith(E));return S===-1?0:S}),[v,b]=l.useState(()=>(i==null?void 0:i.split(".")[0])||"");l.useEffect(()=>{g(S=>Math.min(S,h.length-1))},[h.length]);const p=h[_]||h[0]||null,{minLength:y,maxLength:k,validateSegment:N}=Ct(p),C=N(v),P=p&&C.valid?`${v}${p}`:void 0;l.useEffect(()=>{var S;(S=w.current)==null||S.reset(),o==null||o(P)},[o,P]);const L=l.useRef(null),O=`@${v}${p}`;return e.jsxs(G,{...u,ref:B([x,w]),onCancel:a,cancelLabel:r,onSubmit:s,submitLabel:n,invalid:d||!P,append:c,children:[e.jsxs("div",{children:[e.jsx(he,{hasValue:!!v,valid:C.validLength,children:e.jsx(m,{id:"4Rgp24",values:{minLength:y,maxLength:k}})}),e.jsx(he,{hasValue:!!v,valid:C.validCharset,children:e.jsx(m,{id:"yDlXDJ"})})]}),e.jsx(Z,{ref:L,icon:e.jsx(le,{className:"w-5"}),name:"handle",type:"text",title:j._({id:"LX2sHe"}),pattern:"[a-z0-9][a-z0-9\\-]+[a-z0-9]",minLength:y,maxLength:k,autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",dir:"auto",enterKeyHint:"done",autoFocus:!0,required:!0,value:v,onChange:S=>{const E=S.target.value.toLowerCase(),$=S.target.selectionStart,W=S.target.selectionEnd;S.target.value=E,S.target.setSelectionRange($,W),b(E)},append:h.length>1&&e.jsx("select",{onClick:S=>S.stopPropagation(),onMouseDown:S=>S.stopPropagation(),value:_,"aria-label":j._({id:"HB+TbB"}),onChange:S=>{var E;g(Number(S.target.value)),(E=L.current)==null||E.focus()},className:I("block w-full","text-sm","rounded-lg p-2","bg-white dark:bg-slate-600"),children:h.map((S,E)=>e.jsx("option",{value:E,children:S},S))}),bellow:e.jsx(m,{id:"r/b/p8",values:{0:v.length?e.jsx("strong",{className:"text-gray-800 dark:text-gray-200",children:O}):e.jsx("span",{"aria-hidden":!0,className:"w-24 rounded-md bg-gray-300 p-2 dark:bg-slate-600"})}})}),e.jsx(ie,{role:"status",children:e.jsx("p",{className:"text-md",children:e.jsx(m,{id:"B9VwbO"})})})]})}function he({valid:t,hasValue:s,children:n,className:a,...r}){const{i18n:i,_:o}=R();return e.jsxs("div",{...r,className:I("flex flex-row items-center gap-2",a),children:[s?e.jsx(e.Fragment,{children:t?e.jsx(Fe,{className:"text-success inline-block h-4 w-4",title:i._({id:"nfagfM"})}):e.jsx(Ue,{className:"text-error inline-block h-4 w-4",title:i._({id:"JHB/Ky"})})}):e.jsx("div",{"aria-hidden":!0,className:"flex h-4 w-4 items-center justify-center",children:e.jsx("div",{className:"h-2 w-2 rounded-full bg-gray-300 dark:bg-slate-600"})}),e.jsx("div",{className:"text-sm",children:n})]})}const M=typeof window>"u"?null:window.matchMedia("(prefers-color-scheme: dark)");function Rt(){const[t,s]=l.useState(M!=null&&M.matches?"dark":"light");return l.useEffect(()=>{if(!M)return;const n=()=>{s(M.matches?"dark":"light")};return M.addEventListener("change",n),()=>{M.removeEventListener("change",n)}},[]),t}const Lt=l.lazy(()=>Oe(()=>import("./index-CHPoD7Rp.js"),__vite__mapDeps([0,1,2])));function It({siteKey:t,token:s,onToken:n,prevLabel:a,onPrev:r,nextLabel:i,onNext:o,ref:d,invalid:c,children:x,...u}){const j=l.useRef(null),f=Rt(),[h,w]=l.useState(s),_=l.useCallback(()=>{var b;(b=j.current)==null||b.execute()},[]),g=l.useCallback((b,p)=>{w(b),n(b,p)},[n]),v=l.useCallback(b=>{if(h)return o(b);if(j.current)j.current.execute();else throw new Error("Unable to load hCaptcha")},[h,o]);return e.jsx(G,{...u,cancelLabel:a,onCancel:r,submitLabel:i,onSubmit:v,append:x,invalid:c||!h,children:e.jsx(Lt,{theme:f,sitekey:t,onLoad:_,onVerify:g,ref:B([d,j])})})}function Pt({customizationData:{availableUserDomains:t=[],hcaptchaSiteKey:s=void 0,inviteCodeRequired:n=!0,links:a}={},onValidateNewHandle:r,onDone:i,onBack:o,...d}){const{i18n:c,_:x}=R(),[u,j]=l.useState(void 0),[f,h]=l.useState(void 0),[w,_]=l.useState(void 0),g=s==null?void 0:w||!1,v=l.useCallback(b=>{if(u&&f&&g!==!1)return i({...u,handle:f,hcaptchaToken:g},b)},[u,f,g,i]);return e.jsxs(T,{...d,title:d.title??c._({id:"IS0nrP"}),subtitle:d.subtitle??e.jsx(m,{id:"qjBGxf"}),children:[e.jsx(wt,{doneLabel:e.jsx(m,{id:"e+RpCP"}),onBack:o,onDone:v,steps:[{invalid:!f,titleRender:()=>e.jsx(m,{id:"khEQ02"}),contentRender:({prev:b,prevLabel:p,next:y,nextLabel:k,invalid:N})=>e.jsx(Et,{className:"grow",invalid:N,domains:t,handle:f,onHandle:h,prevLabel:p,onPrev:b,nextLabel:k,onNext:async C=>{if(f&&await r({handle:f},C),!C.aborted)return y(C)},children:e.jsx(de,{links:a})})},{invalid:!u,titleRender:()=>e.jsx(m,{id:"gdRnT7"}),contentRender:({prev:b,prevLabel:p,next:y,nextLabel:k,invalid:N})=>e.jsx(kt,{className:"grow",invalid:N,prevLabel:p,onPrev:b,nextLabel:k,onNext:y,inviteCodeRequired:n,credentials:u,onCredentials:j,children:e.jsx(de,{links:a})})},s!=null&&{invalid:g===!1,titleRender:()=>e.jsx(m,{id:"aIar4b"}),contentRender:({prev:b,prevLabel:p,next:y,nextLabel:k,invalid:N})=>e.jsx(It,{className:"grow",invalid:N,siteKey:s,token:w,onToken:_,prevLabel:p,onPrev:b,nextLabel:k,onNext:y,children:e.jsx(de,{links:a})})}]}),e.jsx(vt,{className:"mt-4",links:a})]})}function At({onSignUp:t,onSignIn:s,onCancel:n,...a}){const{i18n:r,_:i}=R();return e.jsxs(Be,{...a,title:a.title??r._({id:"OX6vme"}),children:[t&&e.jsx(A,{className:"m-1 w-60 min-w-min max-w-full",color:s?"primary":void 0,onClick:t,children:e.jsx(m,{id:"mpt9T+"})}),s&&e.jsx(A,{className:"m-1 w-60 min-w-min max-w-full",color:t?void 0:"primary",onClick:s,children:e.jsx(m,{id:"5lWFkC"})}),n&&e.jsx(A,{className:"m-1 w-60 min-w-min max-w-full",onClick:n,children:e.jsx(m,{id:"dEgA5A"})})]})}function Tt({authorizeData:t,sessions:s,customizationData:n,...a}){var W;const{i18n:r,_:i}=R(),o=(t==null?void 0:t.loginHint)!=null,d=o?2:0,[c,x]=l.useState(d),u=D(x,5),j=D(x,2),f=D(x,3),h=D(x,1),w=D(x,4),_=D(x,0),[g,v]=l.useState(void 0),{sessions:b,selectSub:p,doValidateNewHandle:y,doSignUp:k,doSignIn:N,doInitiatePasswordReset:C,doConfirmResetPassword:P,doAccept:L,doReject:O}=We({sessions:s,onRedirected:u}),S=b.find(Y=>Y.selected&&!Y.loginRequired);l.useEffect(()=>{S&&(S.consentRequired?w():L(S.account.sub))},[S,L,w]);const E=!!((W=n==null?void 0:n.availableUserDomains)!=null&&W.length)&&!t.loginHint,$=c===1&&!E||c===4&&!S;if(l.useEffect(()=>{$&&_()},[$,_]),c===0)return e.jsx(At,{...a,customizationData:n,onSignIn:j,onSignUp:E?h:void 0,onCancel:()=>O()});if(c===1)return e.jsx(Pt,{...a,customizationData:n,onValidateNewHandle:y,onBack:_,onDone:k});if(c===3)return e.jsx(mt,{...a,emailDefault:g,onresetPasswordRequest:C,onResetPasswordConfirm:P,onBack:o?j:_});if(c===2)return e.jsx(pt,{...a,loginHint:t.loginHint,sessions:b,selectSub:p,onSignIn:N,onBack:o?()=>O():_,onForgotPassword:Y=>{f(),v(Y)}});if(c===4)return S?e.jsx(st,{...a,clientId:t.clientId,clientMetadata:t.clientMetadata,clientTrusted:t.clientTrusted,account:S.account,scopeDetails:t.scopeDetails,onAccept:()=>L(S.account.sub),onReject:()=>O(),onBack:o?void 0:()=>{p(null),x(b.length?2:0)}}):null;if(c===5)return e.jsx(T,{...a,title:a.title??r._({id:"UCOd1e"}),children:e.jsx(m,{id:"qq6QQ5"})});throw new Error("Unexpected application state")}const{__authorizeData:re,__sessions:$t,__customizationData:je}=window,X=new URL(window.location.href);X.pathname==="/oauth/authorize"&&!X.searchParams.has("request_uri")&&(X.search="",X.searchParams.set("client_id",re.clientId),X.searchParams.set("request_uri",re.requestUri),window.history.replaceState(history.state,"",X.pathname+X.search));const Ht=document.getElementById("root");var be;qe.createRoot(Ht).render(e.jsx(l.StrictMode,{children:e.jsx(Me,{userLocales:(be=re.uiLocales)==null?void 0:be.split(" "),children:e.jsx(Ke,{fallbackRender:({error:t})=>e.jsx(Xe,{error:t,customizationData:je}),children:e.jsx(Tt,{customizationData:je,authorizeData:re,sessions:$t})})})}));
3
- //# sourceMappingURL=authorization-page-Cms-rcBA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"mappings":";yQAGA,MAAMA,GAAuBC,EAAa,cAAC,IAAI,EAEzCC,GAAe,CACnB,SAAU,GACV,MAAO,IACT,EACA,MAAMC,WAAsBC,WAAU,CACpC,YAAYC,EAAO,CACjB,MAAMA,CAAK,EACX,KAAK,mBAAqB,KAAK,mBAAmB,KAAK,IAAI,EAC3D,KAAK,MAAQH,EACjB,CACE,OAAO,yBAAyBI,EAAO,CACrC,MAAO,CACL,SAAU,GACV,MAAAA,CACD,CACL,CACE,oBAAqB,CACnB,KAAM,CACJ,MAAAA,CACD,EAAG,KAAK,MACT,GAAIA,IAAU,KAAM,CAElB,QADIC,EAAqBC,EAChBC,EAAO,UAAU,OAAQC,EAAO,IAAI,MAAMD,CAAI,EAAGE,EAAO,EAAGA,EAAOF,EAAME,IAC/ED,EAAKC,CAAI,EAAI,UAAUA,CAAI,GAE5BJ,GAAuBC,EAAc,KAAK,OAAO,WAAa,MAAQD,IAAwB,QAAkBA,EAAoB,KAAKC,EAAa,CACrJ,KAAAE,EACA,OAAQ,gBAChB,CAAO,EACD,KAAK,SAASR,EAAY,CAChC,CACA,CACE,kBAAkBI,EAAOM,EAAM,CAC7B,IAAIC,EAAqBC,GACxBD,GAAuBC,EAAe,KAAK,OAAO,WAAa,MAAQD,IAAwB,QAAkBA,EAAoB,KAAKC,EAAcR,EAAOM,CAAI,CACxK,CACE,mBAAmBG,EAAWC,EAAW,CACvC,KAAM,CACJ,SAAAC,CACD,EAAG,KAAK,MACH,CACJ,UAAAC,CACD,EAAG,KAAK,MAOT,GAAID,GAAYD,EAAU,QAAU,MAAQG,GAAgBJ,EAAU,UAAWG,CAAS,EAAG,CAC3F,IAAIE,EAAsBC,GACzBD,GAAwBC,EAAe,KAAK,OAAO,WAAa,MAAQD,IAAyB,QAAkBA,EAAqB,KAAKC,EAAc,CAC1J,KAAMH,EACN,KAAMH,EAAU,UAChB,OAAQ,MAChB,CAAO,EACD,KAAK,SAASb,EAAY,CAChC,CACA,CACE,QAAS,CACP,KAAM,CACJ,SAAAoB,EACA,eAAAC,EACA,kBAAAC,EACA,SAAAC,CACD,EAAG,KAAK,MACH,CACJ,SAAAR,EACA,MAAAX,CACD,EAAG,KAAK,MACT,IAAIoB,EAAgBJ,EACpB,GAAIL,EAAU,CACZ,MAAMZ,EAAQ,CACZ,MAAAC,EACA,mBAAoB,KAAK,kBAC1B,EACD,GAAI,OAAOiB,GAAmB,WAC5BG,EAAgBH,EAAelB,CAAK,UAC3BmB,EACTE,EAAgBC,gBAAcH,EAAmBnB,CAAK,UAC7CoB,IAAa,OACtBC,EAAgBD,MAEhB,OAAMnB,CAEd,CACI,OAAOqB,EAAa,cAAC3B,GAAqB,SAAU,CAClD,MAAO,CACL,SAAAiB,EACA,MAAAX,EACA,mBAAoB,KAAK,kBACjC,CACK,EAAEoB,CAAa,CACpB,CACA,CACA,SAASP,IAAkB,CACzB,IAAIS,EAAI,UAAU,OAAS,GAAK,UAAU,CAAC,IAAM,OAAY,UAAU,CAAC,EAAI,CAAE,EAC1EC,EAAI,UAAU,OAAS,GAAK,UAAU,CAAC,IAAM,OAAY,UAAU,CAAC,EAAI,CAAE,EAC9E,OAAOD,EAAE,SAAWC,EAAE,QAAUD,EAAE,KAAK,CAACE,EAAMC,IAAU,CAAC,OAAO,GAAGD,EAAMD,EAAEE,CAAK,CAAC,CAAC,CACpF,CAEA,SAASC,GAA2BC,EAAO,CACzC,GAAIA,GAAS,MAAQ,OAAOA,EAAM,UAAa,WAAa,OAAOA,EAAM,oBAAuB,WAC9F,MAAM,IAAI,MAAM,gCAAgC,CAEpD,CAEA,SAASC,IAAmB,CAC1B,MAAMC,EAAUC,EAAU,WAACpC,EAAoB,EAC/CgC,GAA2BG,CAAO,EAClC,KAAM,CAACE,EAAOC,CAAQ,EAAIC,WAAS,CACjC,MAAO,KACP,SAAU,EACd,CAAG,EACKC,EAAWC,UAAQ,KAAO,CAC9B,cAAe,IAAM,CACnBN,EAAQ,mBAAoB,EAC5BG,EAAS,CACP,MAAO,KACP,SAAU,EAClB,CAAO,CACF,EACD,aAAchC,GAASgC,EAAS,CAC9B,MAAAhC,EACA,SAAU,EACX,EACL,GAAM,CAAC6B,EAAQ,kBAAkB,CAAC,EAChC,GAAIE,EAAM,SACR,MAAMA,EAAM,MAEd,OAAOG,CACT,CC1HO,SAASE,EAAgB,CAC9BpB,WACAqB,QACAC,WAGAC,YACA,GAAGxC,CACkB,GACrB,cACGyC,OACE,GAAGzC,EACJwC,UAAWE,EACTF,EACA,6BACA,yDACA,4BACA,0BACA,mDAGDF,SAAUA,SAAOA,oBAEjBG,OACCD,UAAWE,EACT,YACA,SACA,cACA,4BACA,2BACA,kBACA,+BACA,gBACA,4CACA,yDAGDD,OAAID,UAAU,0DACZF,SACEK,MAECH,UAAU,qEAETF,YAHG,SAOPC,SACEK,KAECJ,UAAU,8DAETD,YAHG,qBAQTM,IAAoCL,UAAU,cAA3B,2BAGrBM,QAAKN,UAAU,mCAAoCvB,eAG1D,CC7EgB8B,YACdC,EACAvB,EACAwB,EAAkE,CAE9D,IAACD,EAAY,OAACvB,CAAK,EACjByB,QAAMF,EAAIG,UAAUF,GAC1B,OAAOC,IAAQ,GACX,CAAIF,KAAKvB,GACT,IAAIuB,EAAII,MAAM,EAAGF,GAAMzB,KAASuB,EAAII,MAAMF,EAAM,EAAG,CACzD,CCaA,SAASG,EAA8CC,EAAOC,EAAe,CACrE,MAAEC,cAAY,EAAK3B,KAElB4B,qBACL,SAAUpD,KACJ,IACK,aAAMiD,EAAMjD,YACZJ,EAAO,CACVA,mBAAiByD,IAAwBF,EAAavD,GACpDA,EACR,EAEFsD,EAAKI,OAAOH,GAEhB,CAMO,SAASI,GAAO,CACrBC,SAAUC,EAAe,CAAE,EAC3BC,gBAID,CACC,KAAM,CAACC,GAAO9B,WAAS,IAAM,IAAI+B,IAC3B,CAACJ,EAAUK,CAAY,EAC3BhC,WAAsC4B,GAElC,CAAEK,OAASC,SACX,CAAEC,UAAWF,EAEbG,EAAYb,cACfc,IACCL,EAAaL,UACXU,cAASV,IAASW,KAAMC,GAAMA,EAAEC,QAAQ,IAA/Bb,cAAkCc,QAAQJ,MAAO,MACtDV,EACAA,EAASe,IAAKH,IAAO,CAAE,GAAGA,EAAGC,SAAUD,EAAEE,QAAQJ,MAAQA,GAAI,KAGrE,CAACL,EAAY,EAGTW,EAAgBpB,cACpB,CAAC,CACCkB,UACAG,iBAGAC,kBAAkB,GAGlBL,WAAW,GAGXM,gBAAgB,MACiC,CACjD,MAAMC,EAA4B,CAChCN,UACAG,iBACAJ,WACAM,gBACAD,iBACF,EAEAb,EAAaL,GACXd,GAAOc,EAAUoB,EAAUR,GAAMA,EAAEE,QAAQJ,MAAQI,EAAQJ,GAAG,EAAEK,IAG7DH,GACC,CAACC,GAAYD,IAAMQ,GAAW,CAACR,EAAEC,SAC7BD,EACA,CAAE,GAAGA,EAAGC,SAAU,GAAM,IAIpC,CAACR,EAAY,EAGTgB,EAAkBzB,cACrB0B,IAOQC,gBAASC,KAAOC,OAAOH,GAC1BpB,cAAyBA,IAE/B,CAACA,EAAa,EAGVwB,EAAWlC,EACf,MAAOmC,EAAmCC,KACxC,MAAMC,EAAW,MAAM1B,EAAI2B,MACzB,OACA,WACA,CAAE,GAAGH,EAAMnB,UACX,CAAEoB,SAAO,EAEXZ,EAAca,IAEhB,CAAC1B,EAAKK,EAAQQ,EAAc,EAGxBe,EAA0BvC,EAC9B,MACEmC,EACAC,KAEMzB,QAAI2B,MACR,OACA,0BACA,CAAE,GAAGH,EAAMnB,UACX,CAAEoB,SAAO,GAGb,CAACzB,EAAKK,EAAO,EAGTwB,EAAyBxC,EAC7B,MAAOmC,EAAiCC,KACtC,MAAMzB,EAAI2B,MAAM,OAAQ,0BAA2BH,EAAM,CAAEC,SAAO,GAEpE,CAACzB,EAAI,EAGD8B,EAAsBzC,EAC1B,MAAOmC,EAAqCC,KAC1C,MAAMzB,EAAI2B,MAAM,OAAQ,8BAA+BH,EAAM,CAAEC,SAAO,GAExE,CAACzB,EAAI,EAGD+B,EAAW1C,EACf,MAAOmC,EAAmCC,KACxC,MAAMC,EAAW,MAAM1B,EAAI2B,MACzB,OACA,WACA,CAAE,GAAGH,EAAMnB,UACX,CAAEoB,SAAO,EAEXZ,EAAca,IAEhB,CAAC1B,EAAKK,EAAQQ,EAAc,EAGxBmB,EAAW3C,EACf,MAAOkB,UAGC0B,SAASpC,IAASW,KAAMC,GAAMA,EAAEE,QAAQJ,MAAQA,CAAMO,IAA7CjB,cAA6CiB,eACtD,CAAEK,KAAK,EAAG,MAAMnB,EAAI2B,MAAM,OAAQ,UAAW,CAAEpB,OAAO,CAAE0B,SAAO,EACrEf,EAAgBC,IAElB,CAACnB,EAAKH,EAAUqB,EAAgB,EAG5BgB,EAAW7C,EAAgB,UACzB,MAAE8B,OAAQ,MAAMnB,EAAI2B,MAAM,OAAQ,UAAW,EAAC,EACpDT,EAAgBC,IACf,CAACnB,EAAKkB,EAAgB,EAElB,OACLrB,WACAS,YAEAiB,WACAK,0BACAC,yBACAC,sBACAC,WACAC,WACAE,UACF,CACF,CCvMgBC,WAAoBC,EAAuBxE,EAAQ,CACjE,OAAO6B,cAAY,IAAM2C,EAASxE,CAAQ,GAACwE,EAAUxE,EAAM,CAC7D,CCUO,SAASyE,EAAO,CACrBC,QAAQ,OACRC,cAAc,GACdC,UAAUC,OACVC,SAAS,GAGTzF,WACAuB,YACAmE,OAAO,SACPC,OAAO,SACPC,WAAW,GACX,GAAG7G,CACS,GACZ,aACG8G,UACCF,OACAD,OACAE,SAAUA,GAAYL,IAAY,GACjC,GAAGxG,EACJwC,UAAWE,EACT,sFACAgE,EAAS,MAAQ,YACjBJ,IAAU,UACN5D,EACE,mBACA6D,EACI,8BACA,oCAEND,IAAU,OACR5D,EACE,iBACA,qCACA,2CACA6D,EAAc,iBAAmB,8BAEnCE,SACN,sBACAjE,GAGDvB,YAGP,CC7CO,SAAS8F,GAAS,CACvBC,UACAC,SACAC,SACAjG,WACAkG,UACAN,WAGAO,QAAQP,EACR,GAAG7G,CACW,GACd,cACGqH,QAAM,GAAGrH,EAAOoH,QAAc5E,UAAU,oCACtC2E,SAAY1E,OAAmB0E,YAAX,iBAEpB1E,OAAmBD,UAAU,YAC3BvB,YADM,YAIRiG,SAAWzE,OAAkByE,YAAV,WAElBF,GAAWC,IACXK,EAAA,KAAC7E,OAECD,UAAU,+FAETwE,QACAvE,OAAID,UAAU,cACdyE,IALG,aAUd,CCrCO,SAASM,GAAkB,CAChC5C,UAGA,GAAG3E,CACoB,GACvB,aACGwB,KAAG,GAAGxB,EACJ2E,WAAQ6C,oBAAsB7C,EAAQ8C,OAAS9C,EAAQJ,KAG9D,CCJO,SAASmD,GAA2D,CACzEvC,MACAwC,QAAQ,GACRC,OAAO,GACPC,OAAO,GACPC,QAAQ,GACRC,OAAO,GACPC,GAAIC,EAAK,OAGT,GAAGjI,CACmD,GAChDkI,QAAS9F,UAAQ,IAAO+C,aAAegD,IAAMhD,EAAM,IAAIgD,IAAIhD,CAAO,GAACA,EAAI,EAE7E,cACG8C,GAAI,GAAGjI,YACL2H,SACES,GACCxG,MAAO,GAAGsG,EAAOG,QAAQ,KACxB,GAAIV,IAAU,GAAO,KAAOA,IAGhCC,SACEQ,GACCxG,MAAOsG,EAAON,KACb,GAAIA,IAAS,GAAO,CAAEU,MAAO,GAAOC,KAAM,IAASX,IAGvDC,SACEO,GACCxG,MAAOsG,EAAOM,SACb,GAAIX,IAAS,GAAO,KAAOA,IAG/BC,SACEM,GACCxG,MAAOsG,EAAOO,OACb,GAAIX,IAAU,GAAO,KAAOA,IAGhCC,SACEK,GAAcxG,MAAOsG,EAAOH,KAAO,GAAIA,IAAS,GAAO,KAAOA,MAIvE,CAEA,SAASK,EAAc,CACrBxG,QACA0G,QAAQ,GACRC,OAAO,IACqC,CACtCG,QAAOH,EAAO,IAAM,OAC1B,aAAQG,GAAKlG,UAAW8F,EAAQ,aAAe,GAAK1G,YACtD,CCzDO,SAAS+G,GAAW,CACzBC,WACAC,iBACAC,gBAGA,GAAGC,CACa,GACV5D,QAAM/C,UAAQ,KACd,IACK,WAAI+F,IAAIS,QACT,CACC,YACT,EACC,CAACA,EAAS,EAETE,MAAiBD,EAAeG,YAClC,aAAQC,QAAM,GAAGF,EAAQF,WAAeG,cAOtC7D,qBAAKkD,YAAa,QACpB,aACGY,QAAM,GAAGF,iBACRG,EAAA,iBAKF/D,qBAAKkD,YAAa,SAAU,CAGxBc,QACJhE,EAAIkD,WAAa,UACjBlD,EAAIqD,WAAa,+BACjB,CAACrD,EAAIiE,MACL,CAACjE,EAAIsD,OAEP,aACGf,IACE,GAAGqB,EACJ5D,MACAwC,MAAO,CAACwB,EACRvB,KAAM,GACNC,KAAM,CAACsB,EACPrB,MAAO,CAACqB,EACRpB,KAAM,KAKZ,aAAQkB,QAAM,GAAGF,EAAQH,YAC3B,CCzCO,SAASS,GAAW,CACzBT,WACAC,iBACAC,gBAEAnE,UACA2E,eAEAC,WACAC,WACAC,SAGA,GAAGzJ,CACa,GAChB,KAAM,CAAQoE,gBACd,cACG2C,IACE,GAAG/G,EACJ0J,SAAWC,IACTA,EAAMC,eAAc,EACpBL,GACF,EACAtC,OAAQwC,GAAUI,EAAA,IAACxD,GAAOyD,QAASL,EAAQ,kBAC3CzC,eACE+C,WAAA,iBACG1D,GAAOM,KAAK,SAASL,MAAM,yBAC1B4C,EAAA,uBAGD7C,GAAOyD,QAASN,iBACfN,EAAA,8BAKLJ,GAAiBD,EAAemB,UAC/BH,MAACpH,OAAeD,UAAU,mCACxB,eAACyH,OACCC,YAAY,YACZC,IAAKtB,EAAemB,SACpBI,IAAKvB,EAAeG,YACpBxG,UAAU,4BALL,cASVI,oBACCsG,EAAA,yBACGP,YACCC,WACAC,iBACAC,kBAGDvB,YAAkB5C,uBAKtB/B,oBACCsG,EAAA,yBAEG1H,gBAKAD,aACCqF,KAAK,OACLvB,KAAMwD,EAAewB,QACrBC,IAAI,oBACJC,OAAO,SACP/H,UAAU,2BAKXjB,aACCqF,KAAK,OACLvB,KAAMwD,EAAe2B,WACrBF,IAAI,oBACJC,OAAO,SACP/H,UAAU,gCAQf8G,WAAcmB,OACbZ,EAAA,IAACa,MACClI,UAAU,wBAEVmI,aAAUC,EAAA,0BAETtB,EAAa1E,IAAI,CAAC,CAAEiG,QAAOC,aAC1B,IAAAjB,EAAA,IAACkB,MACED,WACCjB,EAAA,IAACmB,IAAgBpJ,MAAOkJ,IAExBjB,EAAA,IAACoB,IAAiBJ,SAJbA,OAJP,QAaJ,SAGV,CAKA,SAASI,GAAiB,CAAEJ,SAA8B,CACxD,OAAQA,GACN,IAAK,UACH,aAAO3B,EAAA,eACT,IAAK,qBACH,aAAOA,EAAA,eACT,IAAK,uBACH,aAAOA,EAAA,eACT,QACS2B,SAEb,CChIO,SAASK,GAAW,CACzBtC,WACAC,iBACAC,gBACAnE,UACA2E,eACAC,WACAC,WACAC,SAGAnH,QACAC,iBACE2G,EAAA,qBAGKvE,IAAQ6C,oBAAsB7C,EAAQ8C,OAAS9C,EAAQJ,iBADzD/C,aAAEgB,UAAU,wCAKhB,EACD,GAAGxC,CACa,GAChB,KAAM,CAAQoE,gBAEd,aACG/B,GACE,GAAGrC,EACJsC,MAAOA,sBACPC,WAEA,eAAC8G,IACCT,WACAC,iBACAC,gBACAnE,UACA2E,eACAG,SACAF,WACAC,cAIR,CC5DO,MAAM2B,GAAsDvL,gBAAA,CACjEiH,SAAU,EACZ,CAAE,EACFsE,GAAgBC,YAAc,kBASvB,SAASC,EAAS,CACvBC,QACArK,WACA4F,WACA,GAAG7G,GACe,CAClB,MAAMuL,EAAUC,GAAgB,CAAEC,OAAQ,YAAY,EAEhDC,EAAetJ,UACnB,KAAO,CACLyE,SAAUA,GAAY,GACtB0E,QAASD,EAAQC,EAAU9E,SAE7B,CAACI,EAAUyE,EAAOC,EAAQ,EAG5B,cACGI,YAAU,GAAG3L,EAAO4L,kBAAiBL,EAAS1E,qBAC5CyE,SACEO,UACCC,GAAIP,EAEJ/I,UAAU,8DAET8I,YAHG,eAOP7I,OAAID,UAAU,0BACb,eAAC2I,IAAgBvJ,MAAO8J,EAAezK,iBAI/C,CCnCgB8K,YACdzI,EACA,CAAE0I,MAAKC,YAAWC,SAAgC,EAAG,GAAE,CAEvD,KAAM,CAAC1F,EAAS2F,CAAW,EAAGjK,WAAS,IACjC,CAACjC,EAAOmM,GAAYlK,aAEpBmK,EAAa5I,cAChBxD,IACCmM,EAASnM,GACTiM,WAAUjM,IAEZ,CAACiM,EAAQ,EAGLI,EAAe7I,cAClB+C,IACC2F,EAAW3F,GACXyF,WAAYzF,IAEd,CAACyF,EAAU,EAGPM,EAAgBC,SAAwB,MAExCC,EAAWD,SAAmB,MACpCE,YAAU,KACRD,EAASE,QAAU,YACjBJ,IAAcI,UAAdJ,QAAuBK,QACvBL,EAAcI,QAAU,KACxBN,EAAW5F,QACX6F,EAAa,GACf,EACO,KACLG,EAASE,QAAU,IACrB,GACC,CAACN,EAAYC,EAAa,EAE7BO,sBACEb,EACA,KAA8B,CAC5Bc,MAAO,IAAML,kBAASE,UAATF,sBACf,GACA,EAAE,EAIJC,YAAU,IACD,YACLH,IAAcI,UAAdJ,QAAuBK,QACvBL,EAAcI,QAAU,IAC1B,EACC,EAAE,EAECI,QAAMtJ,cAAY,iBAEtB8I,IAAcI,UAAdJ,QAAuBK,QAEvBN,EAAa,IACbD,EAAW5F,QAELuG,QAAa,IAAIC,gBACjB,CAAExH,UAAWuH,EAEnBT,EAAcI,QAAUK,EAEpB,IACF,MAAM1J,EAAGmC,SACFyH,EAAK,CACRF,IAAeT,EAAcI,QACpBO,eAAeC,MAAQD,EAAM,IAAIC,MAAM7H,OAAO4H,KAEpDE,GAAc3H,EAAQyH,CAAM,GACvBG,aAAK,iCAAkCH,EAEnD,QACQ,CACJF,IAAeT,EAAcI,UAC/BJ,EAAcI,QAAU,KACxBL,EAAa,KAGfU,EAAWJ,MAAK,EAClB,EACC,CAACtJ,EAAIgJ,EAAcD,EAAW,EAE1B,OACL7F,UACAvG,QACA8M,KACF,CACF,CAEA,SAASK,GAAc3H,EAAqByH,EAAY,CACtD,OACEzH,EAAO6H,UACN7H,EAAO8H,SAAWL,GACjBzH,EAAO8H,UAAWL,iBAAM,QACvBA,aAAeM,cAAgBN,EAAIO,OAAS,aAEnD,CCzGO,MAAMC,GAAkC,CAAC,CAAEzN,iBAC/C0N,IAAU1N,OACZ,GAqBM,SAAS2N,EAAc,CAC5BC,UACAhH,WAEA6C,WACAoE,cAEAC,WAAWtH,OACXuH,cAEAC,cAAcP,GAGd1B,MACAC,YACAC,UAGAjL,WACA,GAAGjB,CACgB,GACnB,KAAM,CAAE+M,MAAKvG,UAASvG,OAAK,EAAK8L,GAAerC,EAAU,CACvDsC,MACAE,UACAD,YACF,EAEMiC,EAAWzK,cACdkG,IACCA,EAAMC,eAAc,EAEfD,EAAMwE,cAAcC,kBAErB,CAACvH,GAAY,CAACgH,GAAcd,KAElC,CAAClG,EAAUgH,EAASd,EAAI,EAG1B,aACGhG,IACE,GAAG/G,EACJ0J,SAAUwE,EACVrH,SAAUA,GAAYL,EACtBW,QAASlH,GAAS,KAAOgO,EAAY,CAAEhO,OAAWwG,UAClDQ,OACE8G,GACElE,EAAA,IAACxD,GAAOyD,QAASiE,WACdC,GAAenE,EAAA,IAAAX,EAAA,iBAItBlC,cACGX,GACCC,MAAM,UACNK,KAAK,SACLH,UACAK,oBAECiH,GAAejE,EAAA,IAAAX,EAAA,iBAInBjI,YAGP,CCtGO,MAAMoN,EAAsB,EAE7BC,GACJ,sEACIC,EAAQ,QACRC,EAAQ,QACRC,GAAM,QACNC,GAAU,eAET,IAAAC,WAAKA,qGAKX,MAEM,SAASC,GAAoBC,EAAW,CACzCA,SAAIpE,OAAS4D,EACf,EAIEQ,EAAIpE,QAAU4D,EAAsB,GACtC,EAIEQ,EAAIpE,QAAU4D,EAAsB,EAClCS,EAAQD,EAAK,CAACH,GAAQ,GAGtBI,EAAQD,EAAK,CAACN,EAAOC,EAAOC,EAAI,EAAE,CAAI,EACxC,EAEF,EAIEI,EAAIpE,QAAU4D,GACZS,EAAQD,EAAK,CAACP,GAAM,EACtB,EAKAO,EAAIpE,QAAU4D,EAAsB,EAClCS,EAAQD,EAAK,CAACH,GAAQ,GAGtBI,EAAQD,EAAK,CAACN,EAAOC,EAAOC,EAAI,EAAE,CAAI,EACxC,EAGF,EAIEI,EAAIpE,QAAU4D,EAAsB,EAClCS,EAAQD,EAAK,CAACH,GAAQ,GAGtBI,EAAQD,EAAK,CAACN,EAAOC,EAAOC,EAAI,EAAE,CAAI,EACxC,EAIF,EAIEI,EAAIpE,QAAU4D,IACZS,EAAQD,EAAK,CAACH,GAAQ,GAGtBI,EAAQD,EAAK,CAACN,EAAOC,EAAOC,GAAI,GAClC,EAIJ,CACF,CAEA,SAASK,EACPD,EACAE,EACAC,EAA8BD,EAAQtE,OAAM,CAE5C,GAAIuE,EAAsB,GAAKA,EAAsBD,EAAQtE,OACrD,UAAIwE,UAAU,+BAEtB,UAAWC,KAAUH,EACfG,KAAOC,KAAKN,CAAM,IACpBG,IACIA,IAAwB,GAAU,SAGnC,QACT,CCrFO,SAASI,GAAsB,CACpCC,WAGA,GAAGrP,CACwB,GAC3B,KAAM,CAAQoE,gBACRkL,EAAWV,GAAoBS,GAErC,aACGpG,QAAM,GAAGjJ,EAAO2K,aAAUC,EAAA,0BACxB0E,IAAaX,EAAiBY,YAC7BrG,EAAA,eACEoG,IAAaX,EAAiBa,aAChCtG,EAAA,eACEoG,IAAaX,EAAiBc,eAChCvG,EAAA,eACEmG,EACFxF,EAAA,IAAAX,EAAA,aAEA,EAAAW,EAAA,IAAAX,EAAA,gBAIR,CCfO,SAASwG,GAAsB,CACpCL,WAGA7M,YACA,GAAGxC,CACwB,GAC3B,KAAM,CAAQoE,gBACRkL,EAAWD,EAAWT,GAAoBS,CAAY,IAEtDM,EAAU,gCACVrJ,EACJgJ,IAAaX,EAAiBY,OAASD,IAAaX,EAAiBa,OACjE,aACAF,IAAaX,EAAiBc,SAC5B,aACA,WAER,aACGhN,OACE,GAAGzC,EACJwC,UAAWE,EAAK,4BAA6BF,GAC7CoE,KAAK,QACL+D,aAAUC,EAAA,iBACVgF,gBAAe,EACfC,gBAAelB,EAAiBY,MAChCO,gBAAeR,EAEdS,eAAMC,KAAK,CAAEvF,OAAQ,CAAK,GAACwF,EAAGC,UAC5BzN,OAECD,UAAW,wBAAwB8M,EAAWY,EAAI5J,EAAQqJ,CAAS,EAD9DO,OAMf,CCvDgBC,YAAanE,EAAsBpK,EAAe,CAC5D,OAAOoK,GAAQ,WACjBA,EAAIpK,GACKoK,IACTA,EAAIW,QAAU/K,EAElB,CAEO,SAASwO,EAAaC,EAA8C,CACzE,OAAQzO,IACN,UAAWoK,KAAOqE,EACZrE,GAAeA,KAAKpK,EAE5B,CACF,CCAO,SAAS0O,GAAuB,CACrCC,UACAC,gBAGA1G,UACA,GAAG9J,CACyB,GAC5B,KAAM,CAAQoE,gBACd,aACGiC,GACE,GAAGrG,EACJ0G,OAAM,GACNoD,QAAUH,IACRG,WAAUH,GACLA,EAAM8G,kBAAkBD,GAC/B,EACA7F,aAAY4F,wCAEXA,WACC1G,EAAA,IAAC6G,IAAQlO,UAAU,MAAMmO,cAAW,KAEpC9G,EAAA,IAAC+G,IAAapO,UAAU,MAAMmO,cAAW,MAIjD,CC7BO,SAASE,GAAe,CAC7BC,OACA5J,SACA6J,SAGAvO,YACAvB,WACA+P,UACAC,SACA,GAAGjR,CACiB,GACpB,KAAM,CAACkR,EAAUC,CAAY,EAAGjP,WAAS,IAEzC,cACGO,OACE,GAAGzC,EACJgR,QAAUrH,IACRqH,WAAUrH,GACLA,EAAM8G,kBAAkBU,EAAY,GAC3C,EACAF,OAAStH,IACPsH,WAAStH,GACJA,EAAM8G,kBAAkBU,EAAY,GAC3C,EACA3O,UAAWE,EAET,WACA,aACA,kBAEA,aACAF,oBAGDC,OACCD,UAAWE,EAET,OACA,kBACA,oCAEA,aACAqO,EAAS,kCAAoCtK,OAC7C,iBACA,2CACA,gDACA,oDACA,8DAEA,wDACA,wEAEA,qCACA,4BAGDqK,SACErO,OACCD,UAAWE,EACT,kBACA,OACAwO,EAAW,eAAiB,kBAG7BJ,aAIJ7P,QAEAwB,OAAID,UAAU,yCAA0C0E,gBAE1D6J,SACEtO,OACCD,UAAWE,EAET,sBACA,mCAEA,4BAEA,gCAEA,mCACA,kBAGDqO,eAKX,CCzFO,SAASK,EAAU,CACxBN,OACA5J,SACA6J,SACAvO,YAGAwO,UACAC,SACAjF,MACAnF,WACAvE,QACA,aAAc+O,EAAY/O,EAC1B,kBAAmBgP,EACnBC,cAAcF,EACd,GAAGrR,CACY,GACTwR,QAAMzP,aAAWoJ,IAEjBsG,EAAWjF,SAAyB,MACpCkF,EAAalF,SAAO,IAE1B,aACGqE,IACCC,OACA5J,SACA6J,SACAvO,UAAWE,EAAK,cAAeF,GAC/BmP,SAAU,GACV7H,QAAUH,UACJ8H,EAAS9E,UAAYhD,EAAMY,SAC7BZ,EAAMC,eAAc,EACpBD,EAAMiI,gBAAe,GACrBH,IAAS9E,UAAT8E,QAAkBI,QAEtB,EACAC,YAAcnI,IACR+H,EAAW/E,SAAWhD,EAAMY,SAAWkH,EAAS9E,UAElDhD,EAAMC,eAAc,EACpBD,EAAMiI,gBAAe,EAEzB,EAEA,eAACG,SACE,GAAG/R,EACJ6G,SAAUA,GAAY2K,EAAI3K,SAC1BvE,QACAiP,cACA5G,aAAY0G,EACZzF,kBAAiB0F,GAAkBE,EAAIjG,QACvCS,IAAKoE,EAAU,CAACpE,EAAKyF,EAAS,EAC9BjP,UAAU,sHACVwO,QAAUrH,IACRqH,WAAUrH,GACLA,EAAM8G,mBAAkBiB,EAAW/E,QAAU,GACpD,EACAsE,OAAStH,IACPsH,WAAStH,GACJA,EAAM8G,mBAAkBiB,EAAW/E,QAAU,QAK5D,CClEO,SAASqF,GAAc,CAC5BC,WAAW,GAGXhB,SACAiB,WACAhL,SACAiL,eAAe,mBACfrB,aAAQsB,IAAS5P,UAAU,QAC3BZ,QACAyQ,eAAezQ,EACfoK,MACA1J,QACAgQ,MAAM,OACNC,iBAAiB,OACjBC,cAAc,MACdC,aAAa,QACb,GAAGzS,CACgB,GACnB,KAAM,CAAQoE,gBACRqN,EAAWjF,SAAyB,MACpC,CAAC+D,EAASmC,CAAW,EAAGxQ,WAAkB,IAC1C,CAACmN,EAAUsD,CAAY,EAAGzQ,WAC9B,OAAOmQ,GAAiB,SAAWA,EAAe,IAG9CO,EAAWnP,cACdkG,IACCuI,WAAWvI,GACCA,IAAMY,OAAO3I,KAAK,GAEhC,CAACsQ,EAAS,EAGZ,aACGd,GACE,GAAGpR,EACJsC,MAAOA,sBACP0J,IAAKoE,EAAU,CAACpE,EAAKyF,EAAS,EAC9Ba,MACAC,iBACAC,cACAC,aACA3B,OACAG,OACEgB,EACKtI,IACCsH,WAAStH,GACJA,EAAM8G,kBAAkBiC,EAAW,KAE1CzB,EAENrP,MAAOyN,EACP6C,SAAUU,EACVjM,KAAM4J,EAAU,OAAS,WACzB4B,eACAjL,cACE6C,WAAA,iBACGuG,IACC9N,UAAU,MACV+N,UACAC,cAAe,WACFkC,EAACG,GAAS,CAACA,IACtBpB,IAAS9E,UAAT8E,QAAkBI,QACpB,GAED3K,MAKX,CCtEO,SAAS4L,GAAiB,CAC/BzD,SAAU0D,EAAe,GACzBC,aAGAd,WACAC,eAAe,eACfc,YAAY5E,EACZ,GAAGrO,CACmB,GACtB,KAAM,CAAQoE,gBACR,CAACiL,EAAUsD,CAAY,EAAGzQ,WAAiB6Q,GAE3CH,EAAWnP,cACdkG,IACO,MAAE/H,SAAU+H,EAAMY,OACxB2H,WAAWvI,GACPA,GAAM8G,mBACVkC,EAAY/Q,GACZoR,WAAarJ,EAAMY,OAAO2I,SAASC,MAAQvR,EAAQ6E,UAErD,CAACyL,EAAUc,EAAW,EAGxB,aACGhB,IACE,GAAGhS,EACJuR,YAAW3G,EAAA,iBACXD,aAAUC,EAAA,iBACVtI,MAAKsI,EAAA,uBAA6ByD,yBAClC4E,YACAf,SAAUU,EACVhR,MAAOyN,EACP8C,eACApB,cACEhH,WAAA,iBACG2F,IAAsBL,mBACtBD,IACC5M,UAAU,4DACV6M,iBAMZ,CCnCO,MAAM+D,GAAmB,cAEzB,SAASC,GAAW,CACzBC,UAAUF,GACVG,UAGAzC,aAAQ0C,IAAUhR,UAAU,QAC5BF,QAAQgR,EACRpB,WACAtQ,QACAyQ,eAAezQ,EACf,GAAG5B,CACa,GAChB,KAAM,CAAQoE,gBACR,CAACqP,EAAOC,CAAS,EAAGxR,WACxB,OAAOmQ,GAAiB,SAAWA,EAAe,IAGpD,aACGjB,GACE,GAAGpR,EACJ2G,KAAK,OACL4L,eAAe,OACfC,YAAY,MACZL,aAAa,MACbM,WAAW,QACXQ,UAAW,GACXU,UAAW,GACXrB,IAAI,OACJxB,OACA8C,QAAQ,4BACRrC,YAAW3G,EAAA,uBAAiB0I,aAC5BhR,QACAV,MAAO6R,EACPvB,SAAWvI,IACT,KAAM,CAAE/H,QAAOiS,eAAcC,kBAAmBnK,EAAMwE,cAEhD4F,EAAaC,GAAIpS,GAEvB+H,EAAMwE,cAAcvM,MAAQmS,EAG5B,MAAME,EAAMJ,GAAgBC,EAC5B,GAAIG,GAAO,KAAM,CACf,MAAMC,EAAmBF,GAAIpS,EAAMwB,MAAM,EAAG6Q,IAC5CtK,EAAMwE,cAAc2F,eAClBnK,EAAMwE,cAAc0F,aAAeK,EAAiBzJ,OAGxDiJ,EAASK,GACT7B,WAAWvI,GAENA,EAAMwK,sBACTZ,WAAUQ,EAAWtJ,SAAW,GAAKsJ,EAAa,KACpD,CACF,EAGN,CAEA,SAASC,GAAIpS,EAAa,CACxB,MAAMwS,EAAaxS,EAAMyS,YAAcC,aAAW,aAAc,IAE5DF,SAAW3J,QAAU,EAAU2J,EAE5B,GAAGA,EAAWhR,MAAM,EAAG,MAAMgR,EAAWhR,MAAM,EAAG,EAAK,GAC/D,CC/DO,SAASmR,GAAyB,CACvC7K,WAGAmE,UACA,GAAG7N,CAC2B,GAC9B,MAAMwU,EAAchJ,GAAgB,CAAEC,OAAQ,mBAAmB,EAC3DgJ,EAAcjI,SAAyB,MAEvC,CAACiH,EAAOC,CAAS,EAAGxR,WAAwB,MAC5C,CAACmN,EAAUsD,CAAY,EAAGzQ,WAA6BuE,QAE7D,cACGmH,GACE,GAAG5N,EACJ0J,SAAWjE,IACLgO,MAASpE,EAAU,OAAO3F,EAAS,CAAE+J,QAAOpE,YAAY5J,EAC9D,EACAoI,QAASA,GAAW,CAAC4F,GAAS,CAACpE,kBAE9BqF,IAAW9N,KAAK,OACf,eAAChE,KAAEkJ,GAAI0I,EAAahS,UAAU,yBAC5B0G,EAAA,yBAOHmC,GAASC,YAAOpC,EAAA,eACf,eAACmK,IACC5F,KAAK,OACL7B,kBAAiB4I,EACjBG,aAAa,OACbC,SAAQ,GACRC,UAAW,GACXtB,QAAUE,UACRC,EAASD,GAELA,KAAmB9G,sBAASkF,oBAKrCxG,GAASC,YAAOpC,EAAA,eACf,eAAC4J,IACC9G,IAAKyI,EACLhH,KAAK,WACLkH,aAAa,OACbC,SAAQ,GACRvF,WACA2D,WAAYL,QAKtB,CC1EO,SAASmC,GAAkB,CAChCC,UAGAxC,iBAAiB,OACjBJ,eAAe,QACfK,cAAc,MACdF,MAAM,OACNxB,aAAQkE,IAAaxS,UAAU,MAAQ,EACvCyO,SACAiB,WACA0B,UAAU,wBACVnB,aAAa,QACb7Q,QACAyQ,eAAezQ,EACfU,QACA,GAAGtC,CACoB,GACvB,KAAM,CAAQoE,cACR,CAACqD,EAAOwN,CAAS,EAAG/S,WACxB,OAAOmQ,GAAiB,SAAWA,EAAe,IAG9CO,EAAWnP,cACdkG,IACC,MAAMlC,EAAQkC,EAAMY,OAAO3I,MAAMsT,YAAW,EAE5CD,EAASxN,GACTyK,WAAWvI,GACXoL,WAAUpL,EAAMY,OAAO2I,SAASC,MAAQ1L,EAAQhB,SAElD,CAACyL,EAAU6C,EAAQ,EAGrB,aACG3D,GACE,GAAGpR,EACJsC,MAAOA,sBACPqE,KAAK,QACL4L,iBACAC,cACAF,MACAG,aACA3B,OACA8C,UACAzB,eACAvQ,MAAO6F,EACPyK,SAAUU,EACV3B,UAGN,CCvCO,SAASkE,GAAyB,CACvCC,eACA1L,WAGAmE,UACA7B,MACA,GAAGhM,CAC2B,GAC9B,KAAM,CAAQoE,gBACRiR,EAAc7J,GAAgB,CAAEC,OAAQ,mBAAmB,EAC3D,CAAChE,EAAOwN,CAAS,EAAG/S,WAASkT,GAE7BE,EAAU9I,SAA8B,MAExC0B,EAAWzK,cACdgC,IACKgC,YAAciC,EAAS,CAAEjC,SAAShC,IAExC,CAACgC,EAAOiC,EAAS,EAGnB,aACGkE,GACE,GAAG5N,EACJgM,IAAKoE,EAAU,CAACpE,EAAKsJ,EAAQ,EAC7BzH,QAASA,GAAW,CAACpG,EACrBiC,SAAUwE,EAEV,gBAAC7C,GAASC,YAAOpC,EAAA,+BACd4L,IACCrH,KAAK,QACL8D,YAAW3G,EAAA,iBACXgB,kBAAiByJ,EACjB/S,MAAKsI,EAAA,iBACLgK,SAAQ,GACRC,UAAW,GACXjT,MAAO6F,EACPsN,QAAUtN,WACR6N,IAAQ3I,UAAR2I,QAAiBxI,QACjBmI,EAASxN,GACX,SAEDiN,IAAW9N,KAAK,OACf,eAAChE,KAAEkJ,GAAIuJ,EAAa7S,UAAU,kBAC5B0G,EAAA,uBASZ,CC3CO,SAASqM,GAAkB,CAChCH,eACAI,yBACAC,yBACAhM,SAGA,GAAGzJ,CACoB,GACvB,KAAM,CAAQoE,gBACR,CAACsR,EAAMC,GAAWzT,cAExB,GAAIwT,IAA4B,EAC9B,cACGrT,GACE,GAAGrC,EACJsC,MAAOtC,EAAMsC,OAAKsI,EAAA,iBAClBrI,SACEvC,EAAMuC,UAAYsH,MAAAX,EAAA,+BAGnBiM,IACCC,eACAtH,kBAAa5E,EAAA,eACbQ,SAAU,MAAOlE,EAAMC,KACf+P,QAAuBhQ,EAAMC,GAC9BA,EAAO6H,SAASqI,IACvB,EACA3H,kBAAa9E,EAAA,eACb6E,SAAUtE,UAEXmM,MAAGpT,UAAU,oDACbqT,UACC,eAACxP,GAAOE,YAAW,GAACuD,QAAS,IAAM6L,oBACjCzM,EAAA,sBAOV,GAAIwM,IAA4B,EAC9B,aACGrT,GACE,GAAGrC,EACJsC,MAAOtC,EAAMsC,OAAKsI,EAAA,iBAClBrI,SACEvC,EAAMuC,UACJsH,MAAAX,EAAA,eAIJ,eAACqL,IACCzG,kBAAa5E,EAAA,eACbQ,SAAU,MAAOlE,EAAMC,KACfgQ,QAAuBjQ,EAAMC,GAC9BA,EAAO6H,SAASqI,IACvB,EACA3H,kBAAa9E,EAAA,eACb6E,SAAUtE,MAMlB,GAAIiM,IAA+B,EACjC,aACGrT,GACE,GAAGrC,EACJsC,MAAOtC,EAAMsC,OAAKsI,EAAA,iBAClBrI,SACEvC,EAAMuC,UAAYsH,MAAAX,EAAA,eAGpB,gBAAC2M,0BACEC,MAAGtT,UAAU,wCACZ0G,EAAA,uBAEDtG,KAAEJ,UAAU,sBACX0G,EAAA,uBAED7C,GAAOC,MAAM,UAAUwD,QAASL,iBAC/BP,EAAA,sBAOV,MAAM,IAAIiE,MAAM,iBAAiBuI,CAAM,GACzC,CC9GO,SAASK,GAAc,CAC5BvT,YACAvB,WAGA6K,KACAE,MACAnF,WACAvE,QACA,aAAc+O,EAAY/O,EAC1B,kBAAmBgP,EACnB,GAAGtR,CACgB,GACbgW,QAAUxK,GAAgB,mBAC1ByK,EAAWzJ,SAAyB,MACpCiF,EAAWjF,SAAyB,MACpCgF,EAAMzP,aAAWoJ,IAEjB+K,EAAUpK,GAAMkK,EAEtB,aACGnF,IACCrO,UAAWE,EAAK,iBAAkBF,GAClCsO,WACGiB,SACE,GAAG/R,EACJ6G,SAAUA,GAAY2K,EAAI3K,SAC1BvE,QACAqI,aAAY0G,EACZzF,kBACE3K,EAEIwF,OACA6K,GAAkBE,EAAIjG,QAE5BS,IAAKoE,EAAU,CAACpE,EAAKyF,EAAS,EAC9B3F,GAAIoK,EACJ1T,UAAU,gCACVmE,KAAK,aAGTgL,SAAU,GACV7H,QAAS,CAAC,CAAES,YAAQ,OAEdA,IAAW0L,EAAStJ,SACpBpC,IAAWkH,EAAS9E,WAExB8E,IAAS9E,UAAT8E,QAAkB0E,QACpB,EAEClV,YACC4I,EAAA,IAACyB,SACCU,IAAKiK,EACLD,QAASE,EACT1T,UAAU,wDAETvB,cAKX,CCjCO,SAASmV,GAAW,CACzBC,kBAAkB,GAClBC,mBAAmB,GACnBC,kBAAkB,GAElB7M,WACAD,SACA+M,mBAGAxK,MACA6B,UACA5M,WACA,GAAGjB,CACa,GAChB,KAAM,CAAQoE,gBAER,CAACqS,EAAUC,CAAY,EAAGxU,WAAiBmU,GAC3C,CAAChH,EAAUsD,CAAY,EAAGzQ,WAAiB,IAC3C,CAACyU,EAAUC,CAAY,EAAG1U,WAAkBqU,GAC5C,CAACM,EAAKC,CAAO,EAAG5U,WAAwB,MAExC,CAAC6U,EAAcC,CAAgB,EACnC9U,WAAyD,MAErD,CAACsE,EAAS2F,CAAW,EAAGjK,WAAS,IAEjC+U,EAAUzK,SAA8B,MAExC0K,EAAoBzT,cAAY,KACpCqT,EAAO,MACPE,EAAgB,OACf,CAACF,EAAQE,EAAgB,EAEtBG,EAAa1T,cAAY,WAC7ByT,KACAD,IAAQtK,UAARsK,QAAiBnK,SAChB,CAACoK,EAAmBD,EAAQ,EAEzB/I,EAAWzK,cACf,MAAOgC,IACD,IACF,MAAMiE,EACJ,CACE+M,WACApH,WACAsH,WACA,GAAII,EAAe,CAAE,CAACA,EAAapQ,IAAI,EAAGkQ,GAAQ,IAEpDpR,SAEKyH,EAAK,CACZ,GAAIzH,EAAO6H,QAET,OAGF,GAAIJ,aAAekK,GAAyC,CAC1DJ,EAAgB9J,GAKhB,OAGF,MAAIA,aAAemK,IAGjBH,IAIIhK,EACR,EAEF,CAACuJ,EAAUpH,EAAUsH,EAAUI,EAAcF,EAAKnN,EAAS,EAG7D,cACGkE,GACE,GAAG5N,EACJgM,IAAKoE,EAAU,CAACpE,EAAKiL,EAAQ,EAC7BhL,UAAWE,EACX4B,SAAUtE,EACVuE,YAAWpD,EAAA,iBACX1D,OAAQjG,EACR4M,QACEA,GAAW,CAAC4I,GAAY,CAACpH,GAAa0H,GAAgB,MAAQ,CAACF,EAEjE/I,YAAaiJ,wCACbrN,SAAUwE,kBAET7C,GAASxE,SAAUL,EAAS8E,YAAOpC,EAAA,eAClC,eAACkI,GACCN,WAAOkE,IAAaxS,UAAU,QAC9BiL,KAAK,WACL9G,KAAK,OACLrE,MAAKsI,EAAA,iBACL2H,eAAe,OACfC,YAAY,MACZL,aAAa,WACbM,WAAW,QACXH,IAAI,OACJqC,aAAa,OACbC,SAAQ,GACR0C,SAAUhB,EACVzP,SAAUyP,EACVzB,UAAS,GACTjT,MAAO6U,EACPvE,SAAWvI,IACTwN,IACYxN,IAAMY,OAAO3I,KAAK,aAKnCyJ,GAASxE,SAAUL,EAAS8E,YAAOpC,EAAA,eAClC,eAAC8I,IACCvE,KAAK,WACLyE,SAAWvI,IACTwN,IACYxN,IAAMY,OAAO3I,KAAK,CAChC,EACAsF,OACEsP,GACE3M,EAAA,IAACxD,GACC7D,UAAU,UACVmE,KAAK,SACLmD,QAAS,KACP0M,EACEC,WAAUc,SAAS,KAAOd,EAAWhQ,OAEzC,EACAkE,aAAUC,EAAA,gCAEV1B,EAAA,iBAINyL,aAAcoC,EAAe,OAAS,OACtClQ,SAAUL,EACVoO,SAAQ,cAIXF,IAAW9N,KAAK,yBACdhE,KAAEJ,UAAU,qDACX0G,EAAA,uBAEDtG,KAAEJ,UAAU,yBACX0G,EAAA,0BAOH6M,IACCtI,KAAK,WACLnL,MAAKsI,EAAA,iBACL+J,aAAcoC,EAAe,OAAS,OACtCS,QAASb,EACTzE,SAAWvI,GAAUiN,EAAYjN,EAAMY,OAAOiN,OAAO,iBAErDtO,EAAA,iBAGD6N,SACE1L,GAECxE,SAAUL,EACV8E,YAAOpC,EAAA,eAEP,gBAACzG,uBACE4Q,IACC/Q,MAAKsI,EAAA,iBACL+J,aAAa,OACbC,SAAQ,GACRC,UAAW,GACXjT,MAAOiV,GAAO,GACdtD,QAASuD,UAGVlU,KAAEJ,UAAU,4DACX0G,EAAA,qBACc6N,IAAaU,cAhB3B,SAyBd,CCvOO,SAASC,GAAa,CAAEvN,MAAKC,OAAuB,CACzD,KAAM,CAACuN,EAASC,CAAW,EAAG1V,WAAS,IAEvCwK,mBAAU,KACRkL,EAAW,KACV,CAACzN,EAAI,EAEDA,GAAO,CAACwN,EACb9N,MAACI,OACC0G,cAAW,GACXzG,YAAY,YACZC,MACAC,MACA5H,UAAU,6BACV0J,QAAS,IAAM0L,EAAW,MAG5B/N,EAAA,IAACpH,OACCkO,cAAW,GACXnO,UAAU,kGAEV,eAACqV,IAAYrV,UAAU,iBAG7B,CCNO,SAASsV,GAAa,CAC3BC,WAEAC,YACAC,UAAUxR,OACVgD,SAGAxI,WACA,GAAGjB,CACe,GAClB,KAAM,CAAQoE,gBACd,cACG2C,IACE,GAAG/G,EACJkH,OAAQjG,EACR+F,QAAS,KACTC,OACEwC,GACEI,EAAA,IAACxD,GAAOyD,QAASL,iBACfP,EAAA,iCAKLtG,KAAEJ,UAAU,wEACX0G,EAAA,iBAGD6O,EAASnT,IAAKD,IACP,MAAC8I,EAAMyK,GAAc,CACzBvT,EAAQ8I,KACR9I,EAAQ6C,mBACR7C,EAAQ8C,MACR9C,EAAQJ,KACR4T,OAAOC,SAET,aACGvH,IACCc,SAAU,EAEV0G,UAAY1O,KACNA,EAAM2O,MAAQ,SAAW3O,EAAM2O,MAAQ,MACzCN,EAAUrT,EAEd,EACAmF,QAAS,IAAMkO,EAAUrT,GACzBiC,KAAK,SACL+D,aAAUC,EAAA,uBAAiBjG,IAAQ8I,QACnCqD,WAAO4G,IAAavN,IAAKxF,EAAQ4T,QAASnO,IAAKqD,IAC/CvG,aAASsR,IAAe7H,cAAW,GAACnO,UAAU,QAE9C,gBAACyG,QAAKzG,UAAU,8CACbyG,QAAKzG,UAAU,4BAA4BiW,cAAW7N,EAAA,iBACpD6C,aAEFyK,SACEjP,QACCzG,UAAU,0DACViW,cAAW7N,EAAA,iBAEVsN,iBArBFvT,EAAQJ,GAAG,EA2BtB,EAEC0T,SACEpH,IAECc,SAAU,EACV0G,UAAY1O,KACNA,EAAM2O,MAAQ,SAAW3O,EAAM2O,MAAQ,MAAKL,GAClD,EACAnO,QAASmO,EACTtN,aAAUC,EAAA,iBACVhE,KAAK,SACLM,aAASsR,IAAe7H,cAAW,GAACnO,UAAU,QAC9CsO,WAAOkE,IAAarE,cAAW,GAACnO,UAAU,QAE1C,eAACyG,QAAKzG,UAAU,6DACd0G,EAAA,kBAZE,WAkBd,CCxFO,SAASwP,GAAW,CACzBC,YACA9U,WACAS,YAEAsU,WACApC,mBACA/M,SAGAnH,QACAC,WACA,GAAGvC,CACa,GAChB,KAAM,CAAQoE,gBACRa,EAAU7C,UAAQ,IAAMyB,EAASW,KAAMC,GAAMA,EAAEC,QAAQ,EAAG,CAACb,EAAS,EACpEgV,EAAepV,cAAY,IAAMa,EAAU,IAAO,GAACA,EAAU,EAC7DyT,EAAW3V,UAAQ,IAAMyB,EAASe,IAAKH,GAAMA,EAAEE,OAAO,EAAG,CAACd,EAAS,EACnE,CAACiV,EAAgBC,GAAqB7W,EAAS2B,WAAS4G,SAAW,GAWzE,OATAnI,0BAEAoK,YAAU,KAIJzH,KAA2B,KAC9B,CAACA,EAAQ,EAERA,EAEGA,EAAQD,oBAGV3C,GACE,GAAGrC,EACJsC,QACAC,SAAUA,GAAYsH,EAAA,IAAAX,EAAA,eAEtB,eAACkN,IACC1M,SAAUkP,EACVpC,mBACA/M,OAAQoP,EACRxC,gBACEpR,EAAQN,QAAQ6C,oBAAsBvC,EAAQN,QAAQJ,IAExD+R,iBAAkB,GAClBC,gBAAiB,OAhBY,KAsBjCoC,QAECtW,GACE,GAAGrC,EACJsC,QACAC,SAAUA,GAAYsH,EAAA,IAAAX,EAAA,eAEtB,eAACkN,IACC1M,SAAUkP,EACVpC,mBACA/M,SACA4M,gBAAiBsC,EACjBrC,iBAAkB,OAMtBzS,EAAS4G,SAAW,QAEnBpI,GACE,GAAGrC,EACJsC,QACAC,SAAUA,GAAYsH,EAAA,IAAAX,EAAA,eAEtB,eAACkN,IACC1M,SAAUkP,EACVpC,mBACA/M,aAMJqP,QAECzW,GACE,GAAGrC,EACJsC,QACAC,SAAUA,GAAYsH,EAAA,IAAAX,EAAA,eAEtB,eAACkN,IACC1M,SAAUkP,EACVpC,mBACA/M,OAAQ,IAAMsP,EAAkB,cAOrC1W,GACE,GAAGrC,EACJsC,QACAC,SAAUA,GAAYsH,EAAA,IAAAX,EAAA,eAEtB,eAAC4O,IACCC,WACAC,UAAYzW,GAAM+C,EAAU/C,EAAEgD,GAAG,EACjC0T,QAAS,IAAMc,EAAkB,IACjCtP,YAIR,CCzIA,MAAMuP,EACJvU,GAC4CA,GAAK,MAAQA,IAAM,GAC3DwU,GACJxU,GAEAuU,EAAUvU,CAAMA,KAAEoJ,UAAY,GAC1BqL,GACJzU,GAEA,CAACuU,EAAUvU,CAAMA,KAAEoJ,UAAY,GAE1B,SAASsL,GACdC,EAAoC,CAE9BC,QAAWD,EAAMjW,UAAU6V,GAC3BM,EAAUF,EAAMG,cAAcP,GAC9BQ,EAAcJ,EAAMjW,UAAU8V,IAE9B,CAACQ,EAAYC,CAAc,EAAGxX,WAAiBmX,GAE/CM,EAAKlW,cACRP,GACKA,IAAQ,IAAMkW,EAAMlW,IACtBwW,EAAcxW,GACP,IAEA,GAGX,CAACkW,EAAMxU,IAAIoU,GAAWY,KAAI,EAAG,EAGzBC,EAAUT,EAAMG,cAAc,CAAC9U,EAAGyL,IAAM8I,EAAUvU,IAAMyL,EAAIuJ,GAC5DK,EAAUV,EAAMjW,UAAU,CAACsB,EAAGyL,IAAM8I,EAAUvU,IAAMyL,EAAIuJ,GAExDM,EAAUtW,cAAY,IAAMkW,EAAGN,CAAW,GAACM,EAAIN,EAAS,EACxDW,EAASvW,cAAY,IAAMkW,EAAGL,CAAU,GAACK,EAAIL,EAAQ,EACrDW,EAASxW,cAAY,IAAMkW,EAAGE,CAAU,GAACF,EAAIE,EAAQ,EACrDK,EAASzW,cAAY,IAAMkW,EAAGG,CAAU,GAACH,EAAIG,EAAQ,EACrDK,EAAa1W,cAAY,IAAMkW,EAAGH,CAAc,GAACG,EAAIH,EAAY,EAGjEY,EACJX,EAEA,EAGAL,EAAMiB,OACJ,CAACC,EAAK7V,EAAGyL,IAAOA,GAAKuJ,GAAcT,EAAUvU,GAAK6V,EAAMA,EAAM,EAC9D,GAGEC,EAAQnB,EAAMjB,OAAOa,GAAWvO,OAChC+P,EAAYpB,EAAMqB,MAAMvB,IAExBvM,EACJ8M,IAAe,IAAM,CAACL,EAAMK,GAAchT,OAAY2S,EAAMK,CAAW,EAGnEiB,EAASjB,IAAe,GAC9B/M,mBAAU,KACJgO,GAAQX,KACX,CAACW,EAAO,EAEJ,CACL/N,UACAyN,kBACAG,QACAC,YACAG,QAASP,IAAoB,EAC7BQ,OAAQR,IAAoBG,EAC5BR,UACAC,SACAC,SACAC,SACAC,YACF,CACF,CChCO,SAASU,GAAiC,CAC/CC,YACAC,YAEAtR,SACAuR,YAEAC,SACAC,YAEA9B,QACA5W,YAEA,GAAGxC,GACoB,SACvB,KAAM,CACJ2a,UACAC,SACAL,QACA5N,UACAyN,kBACAI,YACAN,SACAD,SACAE,cACEhB,GAAWC,GAGT+B,EAAS1X,cAAY,KAEpByW,EAAUC,QACd,CAACD,EAAQC,EAAW,EAEjB3U,EAAiC,CAErCmH,QAAS,GACTkB,QAASlB,EAAUA,EAAQkB,QAAU,GAErCiN,UAAYH,GAAWK,GAAcF,SAAa5R,EAAA,eAClD2J,KAAM8H,EAAUlR,EAASwQ,EAEzBc,UAAYH,GAAUM,GAAcH,SAAa7R,EAAA,eACjDkS,KAAMR,GAAUJ,EAAYS,EAASE,CACvC,EAEME,GAAY1O,mBAAS2O,cAAT3O,qBAAuBnH,GACnC+V,GAAc5O,mBAAS6O,gBAAT7O,qBAAyBnH,GAE7C,cACG/C,OAAID,UAAWE,EAAKF,EAAW,iBAAmB,GAAGxC,kBACnD4C,KAAEJ,UAAU,oDACX0G,EAAA,qBACQkR,kBAAqBG,aAI9Bc,SAAcvF,MAAGtT,UAAU,2BAA4B6Y,aAEvDE,IAGP,CCtGO,SAASE,GAAS,CACvBC,QAEAlZ,YACA,GAAGxC,GACW,CACd,MAAM2b,EAAWD,iBAAOlX,KAAMoX,GAAMA,EAAEtR,MAAQ,QAE1C,OAACqR,QAGF/Y,KACE,GAAG5C,EACJwC,UAAWE,EACT,2FACAF,kBAGF0G,EAAA,yBAEG3H,aACCqF,KAAK,OACLvB,KAAMsW,EAAStW,KACfiF,IAAKqR,EAASrR,IACdC,OAAO,SACP/H,UAAU,sBAjBI,IAwBxB,CCLO,SAASqZ,GAAkB,CAChCC,qBAAqB,GAErBC,YAAaC,EACbC,gBAEAd,SACAJ,YAEAmB,SACApB,YAGA7Z,WACA+K,MACA6B,UACA,GAAG7N,CACoB,GACvB,KAAM,CAAQoE,gBAER,CAACqD,EAAOwN,CAAS,EAAG/S,WAAS8Z,iBAAOvU,OACpC,CAAC4H,EAAUsD,CAAY,EAAGzQ,WAAS8Z,iBAAO3M,UAC1C,CAAC8M,EAAYC,CAAc,EAAGla,WAAS8Z,iBAAOG,YAE9ClF,EAAUzK,SAA8B,MACxC6P,EAAY,WAAMpF,WAAQtK,UAARsK,cAAiBnK,SAEnCiP,EAAc3Z,UAClB,IACEqF,GAAS4H,IAAa,CAACyM,GAAsBK,GACzC,CACE1U,QACA4H,WACA8M,WAAYL,EAAqBK,EAAa1V,QAEhDA,OACN,CAACgB,EAAO4H,EAAU8M,EAAYL,EAAmB,EAGnDpP,mBAAU,KACRuP,WAAgBF,IACf,CAACA,EAAaE,EAAc,SAG5BrO,GACE,GAAG5N,EACJgM,IAAKoE,EAAU,CAACpE,EAAKiL,EAAQ,EAC7BpJ,QAASA,GAAW,CAACkO,EACrBhO,SAAUmO,EACVlO,YAAa8M,EACbpR,SAAUyR,EACVrN,YAAaiN,EACb7T,OAAQjG,YAEP6a,SACEzQ,GAASC,YAAOpC,EAAA,eACf,eAACkI,GACCN,WAAO0C,IAAUhR,UAAU,QAC3BqS,UAAS,GACTpH,KAAK,aACLnL,MAAKsI,EAAA,iBACL2G,YAAW3G,EAAA,iBACXgK,SAAQ,GACRhT,MAAOua,GAAc,GACrBjK,SAAWvI,IACKA,IAAMY,OAAO3I,OAAS6E,QACpC4V,GACF,EACA1H,aAAa,iBAKlBtJ,GAASC,YAAOpC,EAAA,eACf,eAAC4L,IACCD,UAAW,CAACiH,EACZrO,KAAK,QACLkH,aAAa,OACbC,SAAQ,GACRvC,aAAc5K,EACdsN,QAAUtN,IACRwN,EAASxN,GACT4U,eAKLhR,GAASC,YAAOpC,EAAA,eACf,eAAC4J,IACCrF,KAAK,WACLkH,aAAa,OACbC,SAAQ,GACRvF,WACA2D,WAAapR,IACX+Q,EAAY/Q,GACZya,WAMZ,CC/HO,SAASC,GAAiB,CAC/BZ,QAGAlZ,YACA,GAAGuG,CACmB,GACtB,MAAMwT,EAAUb,iBAAOlX,KAAMoX,GAAMA,EAAEtR,MAAQ,oBACvCkS,EAASd,iBAAOlX,KAAMoX,GAAMA,EAAEtR,MAAQ,kBAE5C,aACG1H,KACCJ,UAAWE,EAAK,6CAA8CF,GAC7D,GAAGuG,iBAEJG,EAAA,qBAEGqT,IACC1S,EAAA,IAAC4S,IAAWja,UAAU,yBAAyBka,KAAMH,iBACnDrT,EAAA,eAGF,EAAAW,EAAA,IAAAX,EAAA,eAGDsT,IACC3S,EAAA,IAAC4S,IAAWja,UAAU,yBAAyBka,KAAMF,iBACnDtT,EAAA,eAGF,EAAAW,EAAA,IAAAX,EAAA,mBAMV,CC3BA,MAAMyT,GAAa,GAObC,GAAa,EAObC,GAAkB,GAGlBC,GAAiBC,GAGrBH,GAAaG,EAAOtS,QAAUoS,IAE9BE,EAAOC,WAAW,MAClB,CAACD,EAAOE,SAAS,KAEnB,SAASC,GAAoBH,EAAmB,CAC9C,MAAMI,EAASP,GACTQ,EAASC,KAAKC,IAAIX,GAAYE,GAAkBE,EAAOtS,MAAM,EAE7D8S,EAAkB9Z,cACrB+Z,IACC,MAAMC,EAAcD,EAAQ/S,QAAU0S,GAAUK,EAAQ/S,QAAU2S,EAC5DM,EAAe,gCAAgCvO,KAAKqO,GAEnD,OAAEC,cAAaC,eAAcvK,MAAOsK,GAAeC,CAAa,GAEzE,CAACN,EAAQD,EAAO,EAGX,OACLlK,UAAWkK,EACXxJ,UAAWyJ,EACXG,iBACF,CACF,CAqBO,SAASI,GAAiB,CAC/BC,QAASC,EAET1C,SACAJ,YAEAmB,SACApB,YAEAgD,OAAQC,EACRC,WAGAnQ,UACA5M,WACA+K,MACA,GAAGhM,CACmB,GACtB,KAAM,CAAQoE,gBACRwZ,EAAUC,EAAiB1F,OAAO2E,IAElC7F,EAAUzK,SAA8B,MAExC,CAACyR,EAAWC,CAAa,EAAGhc,WAAS,KACnCgB,QAAM0a,EAAQza,UAAWgb,GAAMJ,iBAAYd,SAASkB,IACnDjb,WAAQ,GAAK,EAAIA,EAC1B,EACM,CAACsa,EAASY,GAAclc,WAAS,KAAM6b,iBAAYM,MAAM,KAAK,KAAM,IAG1E3R,YAAU,KACKwR,EAACI,GAAMjB,KAAKC,IAAIgB,EAAGV,EAAQnT,OAAS,KAChD,CAACmT,EAAQnT,OAAO,EAEnB,MAAMsS,EAA6Ba,EAAQK,IAAcL,EAAQ,IAAM,KAEjE,CAAE3K,YAAWU,YAAW4J,iBAAe,EAAKL,GAAoBH,GAEhE7J,EAAWqK,EAAgBC,GAC3BM,EAASf,GAAU7J,EAASC,MAAQ,GAAGqK,IAAUT,IAAWtW,OAClEiG,YAAU,YAERuK,IAAQtK,UAARsK,QAAiBnK,QACjBkR,WAAWF,IACV,CAACE,EAAUF,EAAO,EAEfrM,QAAWjF,SAAyB,MAEpC+R,EAAU,IAAIf,IAAUT,CAAQ,GAEtC,cACGnP,GACE,GAAG5N,EACJgM,IAAKoE,EAAU,CAACpE,EAAKiL,EAAQ,EAC7BlJ,SAAUmO,EACVlO,YAAa8M,EACbpR,SAAUyR,EACVrN,YAAaiN,EACblN,QAASA,GAAW,CAACiQ,EACrB5W,OAAQjG,mBAEPwB,uBACE+b,IAAkBC,SAAU,CAAC,CAACjB,EAASrK,MAAOD,EAASuK,2BACtDvU,EAAA,qBACW+J,YAAgBU,uBAG5B6K,IAAkBC,SAAU,CAAC,CAACjB,EAASrK,MAAOD,EAASwK,4BACtDxU,EAAA,0BAIHkI,GACCpF,IAAKyF,EACLX,WAAOkE,IAAaxS,UAAU,QAC9BiL,KAAK,SACL9G,KAAK,OACLrE,MAAKsI,EAAA,iBACLgJ,QAAQ,+BACRX,YACAU,YACApB,eAAe,OACfC,YAAY,MACZL,aAAa,MACbG,IAAI,OACJqC,aAAa,OACbE,UAAS,GACTD,SAAQ,GACRhT,MAAO4b,EACPtL,SAAWvI,IACT,MAAM6T,EAAU7T,EAAMY,OAAO3I,MAAMsT,YAAW,EAGxCpB,EAAiBnK,EAAMY,OAAOuJ,eAC9BD,EAAelK,EAAMY,OAAOsJ,aAClClK,EAAMY,OAAO3I,MAAQ4b,EACfjT,SAAOmU,kBAAkB5K,EAAgBD,GAE/CuK,EAAWZ,EACb,EACAtW,OAEE0W,EAAQnT,OAAS,GACfZ,MAAC8U,UACC7U,QAAUH,GAAUA,EAAMiI,gBAAe,EACzCE,YAAcnI,GAAUA,EAAMiI,gBAAe,EAC7ChQ,MAAOqc,EACPtT,aAAUC,EAAA,iBACVsH,SAAWvI,UACTuU,EAAaU,OAAOjV,EAAMY,OAAO3I,KAAK,IACtC6P,IAAS9E,UAAT8E,QAAkBI,OACpB,EACArP,UAAWE,EACT,eACA,UACA,iBACA,8BAGDkb,WAAQhZ,IAAI,CAACmY,EAAQ7Z,UACnB2b,UAAoBjd,MAAOsB,EACzB6Z,UADUA,QAOrBhM,aACE7H,EAAA,uBAEGsU,EAAQ/S,OACPZ,MAAC2F,UAAOhN,UAAU,mCACf+b,aAGH1U,EAAA,IAACZ,QACC0H,cAAW,GACXnO,UAAU,iEAOnBkS,IAAW9N,KAAK,SACf,eAAChE,KAAEJ,UAAU,yBACX0G,EAAA,qBAQV,CAOA,SAASsV,GAAkB,CACzBrL,QACAsL,WAGAxd,WACAuB,YACA,GAAGxC,CACoB,GACvB,KAAM,CAAQoE,gBACd,cACG3B,OACE,GAAGzC,EACJwC,UAAWE,EAAK,mCAAoCF,aAEnDic,QACC1U,WAAA,CACGoJ,WACCtJ,EAAA,IAACiV,IACCtc,UAAU,oCACVF,MAAKsI,EAAA,mBAGPf,EAAA,IAACkV,IACCvc,UAAU,kCACVF,MAAKsI,EAAA,qBAKXf,EAAA,IAACpH,OAAIkO,cAAW,GAACnO,UAAU,2CACzB,eAACC,OAAID,UAAU,+DAGlBC,OAAID,UAAU,UAAWvB,eAGhC,CC5RA,MAAM6G,EACJ,OAAOkX,OAAW,IACd,KACAA,OAAOC,WAAW,gCAEjB,SAASC,KACR,MAACC,EAAOC,GAAYld,WACxB4F,WAAOgH,QAAU,OAAS,SAG5BpC,mBAAU,KACR,GAAI,CAAC5E,EAAO,OAEZ,MAAMuX,EAAW,KACNvX,IAAMgH,QAAU,OAAS,QACpC,EAEMwQ,0BAAiB,SAAUD,GAE1B,KACCE,sBAAoB,SAAUF,EACtC,CAIF,EAAG,EAAE,EAEEF,CACT,CCQA,MAAMK,GAAeC,OAAK,IAAMC,GAAA,WAAO,kDAEhC,SAASC,GAAmB,CACjCC,UAEAnM,MAAOoM,EACPtM,UAEAuH,YACAoB,SAEAnB,YACAI,SAEAnP,MAGA6B,UACA5M,WACA,GAAGjB,CACqB,GAClB8f,QAAatT,SAAiB,MAC9B2S,EAAQD,KACR,CAACzL,EAAOC,CAAS,EAAGxR,WAA6B2d,GAEjDE,EAAStc,cAAY,YAKzBqc,IAAWnT,UAAXmT,QAAoBE,SACtB,EAAG,EAAE,EAECC,EAAWxc,cACf,CAACgQ,EAAeyM,KACdxM,EAASD,GACTF,EAAQE,EAAOyM,IAEjB,CAAC3M,EAAQ,EAGLrF,EAAWzK,cACdgC,IACKgO,KAAc0H,SAAO1V,MAChBqa,EAAWnT,QAAoBA,UAAQqT,QAAO,MAClD,OAAM,IAAI7S,MAAM,4BAEvB,CAACsG,EAAO0H,EAAO,EAGjB,aACGvN,GACE,GAAG5N,EACJgO,YAAa8M,EACb/M,SAAUmO,EACVpO,YAAaiN,EACbrR,SAAUwE,EACVhH,OAAQjG,EACR4M,QAASA,GAAW,CAAC4F,EAErB,eAAC+L,IACCL,QACAgB,QAASP,EACTG,SACAE,WACAjU,IAAKoE,EAAU,CAACpE,EAAK8T,CAAW,MAIxC,CCrEO,SAASM,GAAW,CACzBC,kBAAmB,CACjBC,uBAAuB,GACvBC,kBAAkB9Z,OAClBqV,qBAAqB,GACrBJ,OAAK,EACH,CAAC,EAEL8E,sBACAvF,SACAxR,SAGA,GAAGzJ,CACa,GAChB,KAAM,CAAQoE,gBACR,CAAC2X,EAAa0E,CAAe,EAAGve,WAEpCuE,QACI,CAACqX,EAAQ4C,CAAU,EAAGxe,WAA6BuE,QACnD,CAACka,EAAUC,CAAY,EAAG1e,WAA6BuE,QAKvDoa,EAAgBN,GAAmB,KAAO9Z,OAAYka,GAAY,GAElEG,EAASrd,cACZgC,IACKsW,MAAe+B,GAAU+C,IAAkB,GAC7C,OAAO5F,EAAO,CAAE,GAAGc,EAAa+B,SAAQ+C,iBAAiBpb,EAC3D,EAEF,CAACsW,EAAa+B,EAAQ+C,EAAe5F,EAAO,EAG9C,cACG5Y,GACE,GAAGrC,EACJsC,MAAOtC,EAAMsC,OAAKsI,EAAA,iBAClBrI,SACEvC,EAAMuC,UAAYsH,MAAAX,EAAA,+BAGnB2R,IACCK,gBAAWhS,EAAA,eACXO,SACAwR,OAAQ6F,EACR1H,MAAO,CAKL,CACEvL,QAAS,CAACiQ,EACVxC,YAAa,IAAMzR,EAAA,IAAAX,EAAA,eACnBsS,cAAe,CAAC,CAAE3I,OAAMiI,YAAWM,OAAML,YAAWlN,aAClDhE,EAAA,IAAC8T,IACCnb,UAAU,OACVqL,UACA+P,QAAS0C,EACTxC,SACAE,SAAU0C,EACV5F,YACAoB,OAAQrJ,EACRkI,YACAI,OAAQ,MAAO1V,IAEb,GADIqY,SAAc0C,EAAoB,CAAE1C,UAAUrY,GAC9C,CAACA,EAAO6H,QAAS,OAAO8N,EAAK3V,EACnC,EAEA,eAAC6W,IAAiBZ,WAGxB,EACA,CACE7N,QAAS,CAACkO,EACVT,YAAa,IAAMzR,EAAA,IAAAX,EAAA,eACnBsS,cAAe,CAAC,CAAE3I,OAAMiI,YAAWM,OAAML,YAAWlN,aAClDhE,EAAA,IAACgS,IACCrZ,UAAU,OACVqL,UACAiN,YACAoB,OAAQrJ,EACRkI,YACAI,OAAQC,EACRU,qBACAC,cACAE,cAAewE,EAEf,eAACnE,IAAiBZ,WAGxB,EACA6E,GAAmB,MAAQ,CACzB1S,QAASgT,IAAkB,GAC3BvF,YAAa,IAAMzR,EAAA,IAAAX,EAAA,eACnBsS,cAAe,CAAC,CAAE3I,OAAMiI,YAAWM,OAAML,YAAWlN,aAClDhE,EAAA,IAAC8V,IACCnd,UAAU,OACVqL,UACA+R,QAASW,EACT9M,MAAOkN,EACPpN,QAASqN,EACT9F,YACAoB,OAAQrJ,EACRkI,YACAI,OAAQC,EAER,eAACkB,IAAiBZ,YAGxB,CACD,SAGFD,IAASjZ,UAAU,OAAOkZ,YAGjC,CC5IO,SAASqF,GAAY,CAC1BC,WACApI,WACA7K,WAGA,GAAG/N,CACe,GAClB,KAAM,CAAQoE,gBACd,cACG6c,IAAe,GAAGjhB,EAAOsC,MAAOtC,EAAMsC,OAAKsI,EAAA,2BACzCoW,SACE3a,GACC7D,UAAW,gCACX8D,MAAOsS,EAAW,UAAYnS,OAC9BqD,QAASkX,iBAET9X,EAAA,iBAIH0P,SACEvS,GACC7D,UAAW,gCACX8D,MAAO0a,EAAWva,OAAY,UAC9BqD,QAAS8O,iBAET1P,EAAA,iBAIH6E,SACE1H,GAAO7D,UAAU,gCAAgCsH,QAASiE,iBACzD7E,EAAA,mBAKV,CCpBO,SAASgY,GAAc,CAC5BC,gBACAtd,SAAUud,EACVf,oBAGA,GAAGrgB,CACgB,SACnB,KAAM,CAAQoE,gBAERid,GAAcF,iBAAexI,YAAa,KAE1C2I,EAAcD,MACd,CAAC3L,EAAMC,CAAQ,EAAGzT,WAAeof,GAEjCC,EAAWpb,EAAiBwP,KAC5B6L,EAAarb,EAAiBwP,KAC9B8L,EAAoBtb,EAAiBwP,KACrC+L,EAAavb,EAAiBwP,KAC9BgM,EAAaxb,EAAiBwP,KAC9BiM,EAAczb,EAAiBwP,KAE/B,CAACkM,EAAmBC,CAAqB,EAAG5f,WAEhDuE,QAEI,CACJ5C,WACAS,YACAwB,sBACAC,WACAR,WACAK,0BACAC,yBACAG,WACAE,UAAQ,EACNtC,GAAO,CACTC,SAAUud,EACVrd,aAAcwd,EAChB,EAGMtc,EAAUpB,EAASW,KAAMC,GAAMA,EAAEC,UAAY,CAACD,EAAEO,aAAa,EACnE0H,YAAU,KACJzH,IACEA,EAAQF,gBAAiB4c,IACxB3b,EAASf,EAAQN,QAAQJ,GAAG,EACnC,EACC,CAACU,EAASe,EAAU2b,EAAW,EAElC,MAAMI,EACJ3J,IAAQiI,mBAAmBC,uBAAnBD,QAAyC5V,SACjD,CAAC0W,EAAcxI,UAGXqJ,EACJtM,IAACA,GAAwB,CAACqM,GAAerM,OAAwB,CAACzQ,EAKpE,GAJAyH,YAAU,KACJsV,GAAaJ,KAChB,CAACI,EAAaJ,EAAY,EAEzBlM,IAAuB,EACzB,aACGqL,IACE,GAAG/gB,EACJqgB,oBACAzH,SAAU4I,EACVR,SAAUe,EAAYL,EAAajb,OACnCsH,SAAU,IAAM7H,MAKtB,GAAIwP,IAAsB,EACxB,aACG0K,IACE,GAAGpgB,EACJqgB,oBACAG,oBAAqB1a,EACrB2D,OAAQmY,EACR3G,OAAQlV,IAKd,GAAI2P,IAA6B,EAC/B,aACGH,IACE,GAAGvV,EACJoV,aAAcyM,EACdrM,uBAAwB5P,EACxB6P,uBAAwB5P,EACxB4D,OAAQ4X,EAAcG,EAAaI,IAKzC,GAAIlM,IAAsB,EACxB,aACGgD,IACE,GAAG1Y,EACJ2Y,UAAWwI,EAAcxI,UACzB9U,WACAS,YACAsU,SAAUrT,EACVkE,OAAQ4X,EAAc,IAAMnb,IAAa0b,EACzCpL,iBAAmB/O,IACjBga,IACAK,EAAqBra,GACvB,GAKN,GAAIiO,IAAsB,EAEpB,OAACzQ,QAGFiG,IACE,GAAGlL,EACJ4I,SAAUuY,EAAcvY,SACxBC,eAAgBsY,EAActY,eAC9BC,cAAeqY,EAAcrY,cAC7BnE,QAASM,EAAQN,QACjB2E,aAAc6X,EAAc7X,aAC5BC,SAAU,IAAMvD,EAASf,EAAQN,QAAQJ,GAAG,EAC5CiF,SAAU,IAAMtD,IAChBuD,OACE4X,EACI5a,OACA,KACEnC,EAAU,MACFT,IAAS4G,OAAM,KACzB,GAlBW,KAwBvB,GAAIiL,IAAoB,EACtB,aACGrT,GAAiB,GAAGrC,EAAOsC,MAAOtC,EAAMsC,OAAKsI,EAAA,gCAC5C1B,EAAA,iBAMA,UAAIiE,MAAM,+BAClB,CC/KA,KAAM,CACJ8U,gBAAiBd,GACjBe,WAAYre,GACZse,oBAAqB9B,IACnBrB,OAKE7Z,EAAM,IAAIgD,IAAI6W,OAAO5Z,SAASC,IAAI,EAEtCF,EAAIqD,WAAa,oBACjB,CAACrD,EAAIid,aAAaC,IAAI,aACtB,IACAld,EAAIsD,OAAS,GACbtD,EAAIid,aAAaE,IAAI,YAAanB,GAAcvY,QAAQ,EACxDzD,EAAIid,aAAaE,IAAI,cAAenB,GAAcoB,UAAU,EACrDC,eAAQC,aAAaD,QAAQxgB,MAAO,GAAImD,EAAIqD,SAAWrD,EAAIsD,MAAM,GAG1E,MAAMia,GAAYC,SAASC,eAAe,eAE1CC,cAAWH,IAAWI,OACpBjZ,MAACkZ,cACC,eAACC,IAAeC,aAAa9B,MAAc+B,YAAd/B,eAAyB9C,MAAM,KAC1D,eAACve,IACCoB,eAAgB,CAAC,CAAEjB,iBAChBkjB,IAAUljB,QAAcogB,uBAG3B,eAACa,IACCb,qBACAc,iBACAtd","names":["ErrorBoundaryContext","createContext","initialState","ErrorBoundary","Component","props","error","_this$props$onReset","_this$props","_len","args","_key","info","_this$props$onError","_this$props2","prevProps","prevState","didCatch","resetKeys","hasArrayChanged","_this$props$onReset2","_this$props3","children","fallbackRender","FallbackComponent","fallback","childToRender","createElement","a","b","item","index","assertErrorBoundaryContext","value","useErrorBoundary","context","useContext","state","setState","useState","memoized","useMemo","LayoutTitlePage","title","subtitle","className","div","clsx","h1","p","LocaleSelector","main","upsert","arr","predicate","idx","findIndex","slice","useSafeCallback","fn","deps","showBoundary","useCallback","UnknownRequestUriError","concat","useApi","sessions","sessionsInit","onRedirected","api","Api","setSessions","i18n","useLingui","locale","selectSub","sub","find","s","selected","account","map","upsertSession","ephemeralToken","consentRequired","loginRequired","session","performRedirect","url","location","href","String","doSignIn","data","signal","response","fetch","doInitiatePasswordReset","doConfirmResetPassword","doValidateNewHandle","doSignUp","doAccept","bearer","doReject","useBoundDispatch","dispatch","Button","color","transparent","loading","undefined","square","type","role","disabled","button","FormCard","actions","cancel","append","prepend","inert","form","_jsxs","AccountIdentifier","preferred_username","email","UrlViewer","proto","host","path","query","hash","as","As","urlObj","URL","UrlPartViewer","protocol","faded","bold","pathname","search","Comp","ClientName","clientId","clientMetadata","clientTrusted","attrs","client_name","span","Trans_","simplifiedView","port","AcceptForm","scopeDetails","onAccept","onReject","onBack","onSubmit","event","preventDefault","_jsx","onClick","_Fragment","logo_uri","img","crossOrigin","src","alt","tos_uri","rel","target","policy_uri","length","ul","aria-label","$__i18n","scope","description","li","MultiLangString","ScopeDescription","AcceptView","FieldsetContext","displayName","Fieldset","label","labelId","useRandomString","prefix","contextValue","fieldset","aria-labelledby","legend","id","useAsyncAction","ref","onLoading","onError","setLoading","setError","doSetError","doSetLoading","controllerRef","useRef","resetRef","useEffect","current","abort","useImperativeHandle","reset","run","controller","AbortController","err","Error","isAbortReason","warn","aborted","reason","DOMException","name","errorRenderDefault","ErrorCard","FormCardAsync","invalid","submitLabel","onCancel","cancelLabel","errorRender","doSubmit","currentTarget","reportValidity","MIN_PASSWORD_LENGTH","EMOJI","UPPER","LOWER","DEC","SPECIAL","PasswordStrength","getPasswordStrength","pwd","matches","regexps","regexpsCountToMatch","TypeError","regexp","test","PasswordStrengthLabel","password","strength","extra","strong","moderate","PasswordStrengthMeter","colorBg","aria-valuemin","aria-valuemax","aria-valuenow","Array","from","_","i","updateRef","mergeRefs","refs","ButtonToggleVisibility","visible","toggleVisible","defaultPrevented","EyeIcon","aria-hidden","EyeSlashIcon","InputContainer","icon","bellow","onFocus","onBlur","hasFocus","setHasFocus","InputText","ariaLabel","ariaLabelledBy","placeholder","ctx","inputRef","focusedRef","tabIndex","stopPropagation","focus","onMouseDown","input","InputPassword","autoHide","onChange","autoComplete","LockIcon","defaultValue","dir","autoCapitalize","autoCorrect","spellCheck","setVisible","setPassword","doChange","prev","InputNewPassword","passwordInit","onPassword","minLength","validity","valid","OTP_CODE_EXAMPLE","InputToken","example","onToken","TokenIcon","token","setToken","maxLength","pattern","selectionEnd","selectionStart","fixedValue","fix","pos","fixedSlicedValue","isDefaultPrevented","normalized","toUpperCase","replaceAll","ResetPasswordConfirmForm","tokenAriaId","passwordRef","Admonition","enterKeyHint","required","autoFocus","InputEmailAddress","onEmail","AtSymbolIcon","setEmail","toLowerCase","ResetPasswordRequestForm","emailDefault","emailAriaId","ctrlRef","ResetPasswordView","onresetPasswordRequest","onResetPasswordConfirm","view","setView","hr","center","h2","InputCheckbox","htmlFor","labelRef","inputId","click","SignInForm","usernameDefault","usernameReadonly","rememberDefault","onForgotPassword","username","setUsername","remember","setRemember","otp","setOtp","secondFactor","setSecondFactor","formRef","clearSecondFactor","resetState","SecondAuthenticationFactorRequiredError","InvalidCredentialsError","readOnly","includes","checked","hint","AccountImage","errored","setErrored","AccountIcon","SignInPicker","accounts","onAccount","onOther","identifier","filter","Boolean","onKeyDown","key","picture","CaretRightIcon","arial-label","SignInView","loginHint","onSignIn","clearSession","showSignInForm","setShowSignInForm","isEnabled","isRequired","isCompleted","useStepper","steps","firstIdx","lastIdx","findLastIndex","requiredIdx","currentIdx","setCurrentIdx","to","join","prevIdx","nextIdx","toFirst","toLast","toPrev","toNext","toRequired","currentPosition","reduce","acc","count","completed","every","broken","atFirst","atLast","WizardCard","prevLabel","nextLabel","backLabel","onDone","doneLabel","onNext","next","stepTitle","titleRender","stepContent","contentRender","HelpCard","links","helpLink","l","SignUpAccountForm","inviteCodeRequired","credentials","creds","onCredentials","onPrev","inviteCode","setInviteCode","resetForm","SignUpDisclaimer","tosLink","ppLink","LinkAnchor","link","MAX_LENGTH","MIN_LENGTH","MAX_FULL_LENGTH","isValidDomain","domain","startsWith","endsWith","useSegmentValidator","minLen","maxLen","Math","min","validateSegment","segment","validLength","validCharset","SignUpHandleForm","domains","availableDomains","handle","handleInit","onHandle","domainIdx","setDomainIdx","d","setSegment","split","v","preview","ValidationMessage","hasValue","setSelectionRange","select","Number","option","CheckMarkIcon","XMarkIcon","window","matchMedia","useBrowserColorScheme","theme","setTheme","listener","addEventListener","removeEventListener","HCaptchaLazy","lazy","__vitePreload","SignUpHcaptchaForm","siteKey","tokenInit","captchaRef","onLoad","execute","onVerify","ekey","sitekey","SignUpView","customizationData","availableUserDomains","hcaptchaSiteKey","onValidateNewHandle","setCredentials","setHandle","hcaptcha","setHcaptcha","hcaptchaToken","doDone","WelcomeView","onSignUp","LayoutWelcome","AuthorizeView","authorizeData","initialSessions","forceSignIn","initialView","showDone","showSignIn","showResetPassword","showSignUp","showAccept","showWelcome","resetPasswordHint","setResetPasswordHint","canSignUp","resetNeeded","__authorizeData","__sessions","__customizationData","searchParams","has","set","requestUri","history","replaceState","container","document","getElementById","createRoot","render","StrictMode","LocaleProvider","userLocales","uiLocales","ErrorView"],"ignoreList":[0],"sources":["../../../../node_modules/.pnpm/react-error-boundary@5.0.0_react@19.0.0/node_modules/react-error-boundary/dist/react-error-boundary.esm.js","../src/components/layouts/layout-title-page.tsx","../src/lib/util.ts","../src/hooks/use-api.ts","../src/hooks/use-bound-dispatch.ts","../src/components/forms/button.tsx","../src/components/forms/form-card.tsx","../src/components/utils/account-identifier.tsx","../src/components/utils/url-viewer.tsx","../src/components/utils/client-name.tsx","../src/views/authorize/accept/accept-form.tsx","../src/views/authorize/accept/accept-view.tsx","../src/components/forms/fieldset.tsx","../src/hooks/use-async-action.ts","../src/components/forms/form-card-async.tsx","../src/lib/password.ts","../src/components/utils/password-strength-label.tsx","../src/components/utils/password-strength-meter.tsx","../src/lib/ref.ts","../src/components/forms/button-toggle-visibility.tsx","../src/components/forms/input-container.tsx","../src/components/forms/input-text.tsx","../src/components/forms/input-password.tsx","../src/components/forms/input-new-password.tsx","../src/components/forms/input-token.tsx","../src/views/authorize/reset-password/reset-password-confirm-form.tsx","../src/components/forms/input-email-address.tsx","../src/views/authorize/reset-password/reset-password-request-form.tsx","../src/views/authorize/reset-password/reset-password-view.tsx","../src/components/forms/input-checkbox.tsx","../src/views/authorize/sign-in/sign-in-form.tsx","../src/components/utils/account-image.tsx","../src/views/authorize/sign-in/sign-in-picker.tsx","../src/views/authorize/sign-in/sign-in-view.tsx","../src/hooks/use-stepper.ts","../src/components/forms/wizard-card.tsx","../src/components/utils/help-card.tsx","../src/views/authorize/sign-up/sign-up-account-form.tsx","../src/views/authorize/sign-up/sign-up-disclaimer.tsx","../src/views/authorize/sign-up/sign-up-handle-form.tsx","../src/hooks/use-browser-color-scheme.ts","../src/views/authorize/sign-up/sign-up-hcaptcha-form.tsx","../src/views/authorize/sign-up/sign-up-view.tsx","../src/views/authorize/welcome/welcome-view.tsx","../src/views/authorize/authorize-view.tsx","../src/authorization-page.tsx"],"sourcesContent":["'use client';\nimport { createContext, Component, createElement, useContext, useState, useMemo, forwardRef } from 'react';\n\nconst ErrorBoundaryContext = createContext(null);\n\nconst initialState = {\n didCatch: false,\n error: null\n};\nclass ErrorBoundary extends Component {\n constructor(props) {\n super(props);\n this.resetErrorBoundary = this.resetErrorBoundary.bind(this);\n this.state = initialState;\n }\n static getDerivedStateFromError(error) {\n return {\n didCatch: true,\n error\n };\n }\n resetErrorBoundary() {\n const {\n error\n } = this.state;\n if (error !== null) {\n var _this$props$onReset, _this$props;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n (_this$props$onReset = (_this$props = this.props).onReset) === null || _this$props$onReset === void 0 ? void 0 : _this$props$onReset.call(_this$props, {\n args,\n reason: \"imperative-api\"\n });\n this.setState(initialState);\n }\n }\n componentDidCatch(error, info) {\n var _this$props$onError, _this$props2;\n (_this$props$onError = (_this$props2 = this.props).onError) === null || _this$props$onError === void 0 ? void 0 : _this$props$onError.call(_this$props2, error, info);\n }\n componentDidUpdate(prevProps, prevState) {\n const {\n didCatch\n } = this.state;\n const {\n resetKeys\n } = this.props;\n\n // There's an edge case where if the thing that triggered the error happens to *also* be in the resetKeys array,\n // we'd end up resetting the error boundary immediately.\n // This would likely trigger a second error to be thrown.\n // So we make sure that we don't check the resetKeys on the first call of cDU after the error is set.\n\n if (didCatch && prevState.error !== null && hasArrayChanged(prevProps.resetKeys, resetKeys)) {\n var _this$props$onReset2, _this$props3;\n (_this$props$onReset2 = (_this$props3 = this.props).onReset) === null || _this$props$onReset2 === void 0 ? void 0 : _this$props$onReset2.call(_this$props3, {\n next: resetKeys,\n prev: prevProps.resetKeys,\n reason: \"keys\"\n });\n this.setState(initialState);\n }\n }\n render() {\n const {\n children,\n fallbackRender,\n FallbackComponent,\n fallback\n } = this.props;\n const {\n didCatch,\n error\n } = this.state;\n let childToRender = children;\n if (didCatch) {\n const props = {\n error,\n resetErrorBoundary: this.resetErrorBoundary\n };\n if (typeof fallbackRender === \"function\") {\n childToRender = fallbackRender(props);\n } else if (FallbackComponent) {\n childToRender = createElement(FallbackComponent, props);\n } else if (fallback !== undefined) {\n childToRender = fallback;\n } else {\n throw error;\n }\n }\n return createElement(ErrorBoundaryContext.Provider, {\n value: {\n didCatch,\n error,\n resetErrorBoundary: this.resetErrorBoundary\n }\n }, childToRender);\n }\n}\nfunction hasArrayChanged() {\n let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n return a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));\n}\n\nfunction assertErrorBoundaryContext(value) {\n if (value == null || typeof value.didCatch !== \"boolean\" || typeof value.resetErrorBoundary !== \"function\") {\n throw new Error(\"ErrorBoundaryContext not found\");\n }\n}\n\nfunction useErrorBoundary() {\n const context = useContext(ErrorBoundaryContext);\n assertErrorBoundaryContext(context);\n const [state, setState] = useState({\n error: null,\n hasError: false\n });\n const memoized = useMemo(() => ({\n resetBoundary: () => {\n context.resetErrorBoundary();\n setState({\n error: null,\n hasError: false\n });\n },\n showBoundary: error => setState({\n error,\n hasError: true\n })\n }), [context.resetErrorBoundary]);\n if (state.hasError) {\n throw state.error;\n }\n return memoized;\n}\n\nfunction withErrorBoundary(component, errorBoundaryProps) {\n const Wrapped = forwardRef((props, ref) => createElement(ErrorBoundary, errorBoundaryProps, createElement(component, {\n ...props,\n ref\n })));\n\n // Format for display in DevTools\n const name = component.displayName || component.name || \"Unknown\";\n Wrapped.displayName = \"withErrorBoundary(\".concat(name, \")\");\n return Wrapped;\n}\n\nexport { ErrorBoundary, ErrorBoundaryContext, useErrorBoundary, withErrorBoundary };\n","import { clsx } from 'clsx'\nimport { JSX, ReactNode } from 'react'\nimport { Override } from '../../lib/util.ts'\nimport { LocaleSelector } from '../../locales/locale-selector.tsx'\n\nexport type LayoutTitlePageProps = Override<\n JSX.IntrinsicElements['div'],\n {\n title?: string\n subtitle?: ReactNode\n children?: ReactNode\n }\n>\n\nexport function LayoutTitlePage({\n children,\n title,\n subtitle,\n\n // HTMLDivElement\n className,\n ...props\n}: LayoutTitlePageProps) {\n return (\n <div\n {...props}\n className={clsx(\n className,\n 'flex flex-col items-center',\n 'md:flex md:flex-row md:items-center md:justify-stretch',\n 'min-w-screen min-h-screen',\n 'bg-white text-slate-900',\n 'dark:bg-slate-900 dark:text-slate-100',\n )}\n >\n {title && <title>{title}</title>}\n\n <div\n className={clsx(\n 'px-6 pt-4',\n 'w-full',\n 'md:max-w-lg',\n 'flex flex-row items-start',\n 'md:flex-col md:items-end',\n 'md:self-stretch',\n 'md:max-w-fix md:w-1/2 md:p-4',\n 'md:text-right',\n 'md:dark:border-r md:dark:border-slate-700',\n 'md:bg-slate-100 md:dark:bg-slate-800',\n )}\n >\n <div className=\"grid grow content-center md:justify-items-end\">\n {title && (\n <h1\n key=\"title\"\n className=\"text-primary text-xl font-semibold md:my-4 md:text-2xl lg:text-5xl\"\n >\n {title}\n </h1>\n )}\n\n {subtitle && (\n <p\n key=\"subtitle\"\n className=\"hidden max-w-xs text-slate-600 md:block dark:text-slate-400\"\n >\n {subtitle}\n </p>\n )}\n </div>\n\n <LocaleSelector key=\"localeSelector\" className=\"m-1 md:m-2\" />\n </div>\n\n <main className=\"w-full p-6 md:max-w-3xl md:px-12\">{children}</main>\n </div>\n )\n}\n","export function upsert<T>(\n arr: undefined | readonly T[],\n item: T,\n predicate: (value: T, index: number, obj: readonly T[]) => boolean,\n): T[] {\n if (!arr) return [item]\n const idx = arr.findIndex(predicate)\n return idx === -1\n ? [...arr, item]\n : [...arr.slice(0, idx), item, ...arr.slice(idx + 1)]\n}\n\nexport type Simplify<T> = { [K in keyof T]: T[K] } & NonNullable<unknown>\nexport type Override<T, U> = Simplify<Omit<T, keyof U> & U>\n","import { useLingui } from '@lingui/react/macro'\nimport { useCallback, useState } from 'react'\nimport { useErrorBoundary } from 'react-error-boundary'\nimport type {\n Account,\n ConfirmResetPasswordInput,\n InitiatePasswordResetInput,\n Session,\n SignInInput,\n SignUpInput,\n VerifyHandleAvailabilityInput,\n} from '@atproto/oauth-provider-api'\nimport { Api, UnknownRequestUriError } from '../lib/api.ts'\nimport { upsert } from '../lib/util.ts'\n\n/**\n * Any function wrapped with this helper will automatically show the error\n * boundary when an `UnknownRequestUriError` is thrown. This typically happens\n * in development, or if the user left its browser session open for a (very)\n * long time.\n *\n * @note Requires an error boundary to be present in the component tree.\n */\nfunction useSafeCallback<F extends (...a: any) => any>(fn: F, deps: unknown[]) {\n const { showBoundary } = useErrorBoundary<UnknownRequestUriError>()\n\n return useCallback(\n async (...args: Parameters<F>): Promise<Awaited<ReturnType<F>>> => {\n try {\n return await fn(...args)\n } catch (error) {\n if (error instanceof UnknownRequestUriError) showBoundary(error)\n throw error\n }\n },\n deps.concat(showBoundary),\n )\n}\n\nexport type SessionWithToken = Session & {\n ephemeralToken?: string\n}\n\nexport function useApi({\n sessions: sessionsInit = [],\n onRedirected,\n}: {\n sessions?: readonly Session[]\n onRedirected?: () => void\n}) {\n const [api] = useState(() => new Api())\n const [sessions, setSessions] =\n useState<readonly SessionWithToken[]>(sessionsInit)\n\n const { i18n } = useLingui()\n const { locale } = i18n\n\n const selectSub = useCallback(\n (sub: string | null) => {\n setSessions((sessions) =>\n sub === (sessions.find((s) => s.selected)?.account.sub || null)\n ? sessions\n : sessions.map((s) => ({ ...s, selected: s.account.sub === sub })),\n )\n },\n [setSessions],\n )\n\n const upsertSession = useCallback(\n ({\n account,\n ephemeralToken,\n // The server will tell us if the user needs to consent to the\n // authorization. Defaults to true in case of sign-ups\n consentRequired = true,\n // When a new session is inserted, assume that the user intends to use\n // it, and therefore, it is selected by default.\n selected = true,\n // When a new session is inserted, it is assumed that the user just\n // created the session, and therefore, login is not required.\n loginRequired = false,\n }: { account: Account } & Partial<SessionWithToken>) => {\n const session: SessionWithToken = {\n account,\n ephemeralToken,\n selected,\n loginRequired,\n consentRequired,\n }\n\n setSessions((sessions) =>\n upsert(sessions, session, (s) => s.account.sub === account.sub).map(\n // Make sure to de-select any other selected session (if selected is\n // true)\n (s) =>\n !selected || s === session || !s.selected\n ? s\n : { ...s, selected: false },\n ),\n )\n },\n [setSessions],\n )\n\n const performRedirect = useCallback(\n (url: string | URL) => {\n // @TODO At this point, the request cannot be accepted/rejected anymore.\n // We should probably change the app's state to something that indicates\n // that in order to improve UX in case the user comes back to the app.\n // This is currently ensured by the backend (through back-forward cache\n // busting) but handling it here would provide a better UX.\n\n window.location.href = String(url)\n if (onRedirected) setTimeout(onRedirected)\n },\n [onRedirected],\n )\n\n const doSignIn = useSafeCallback(\n async (data: Omit<SignInInput, 'locale'>, signal?: AbortSignal) => {\n const response = await api.fetch(\n 'POST',\n '/sign-in',\n { ...data, locale },\n { signal },\n )\n upsertSession(response)\n },\n [api, locale, upsertSession],\n )\n\n const doInitiatePasswordReset = useSafeCallback(\n async (\n data: Omit<InitiatePasswordResetInput, 'locale'>,\n signal?: AbortSignal,\n ) => {\n await api.fetch(\n 'POST',\n '/reset-password-request',\n { ...data, locale },\n { signal },\n )\n },\n [api, locale],\n )\n\n const doConfirmResetPassword = useSafeCallback(\n async (data: ConfirmResetPasswordInput, signal?: AbortSignal) => {\n await api.fetch('POST', '/reset-password-confirm', data, { signal })\n },\n [api],\n )\n\n const doValidateNewHandle = useSafeCallback(\n async (data: VerifyHandleAvailabilityInput, signal?: AbortSignal) => {\n await api.fetch('POST', '/verify-handle-availability', data, { signal })\n },\n [api],\n )\n\n const doSignUp = useSafeCallback(\n async (data: Omit<SignUpInput, 'locale'>, signal?: AbortSignal) => {\n const response = await api.fetch(\n 'POST',\n '/sign-up',\n { ...data, locale },\n { signal },\n )\n upsertSession(response)\n },\n [api, locale, upsertSession],\n )\n\n const doAccept = useSafeCallback(\n async (sub: string) => {\n // If \"remember me\" was unchecked, we need to use the ephemeral token to\n // authenticate the request.\n const bearer = sessions.find((s) => s.account.sub === sub)?.ephemeralToken\n const { url } = await api.fetch('POST', '/accept', { sub }, { bearer })\n performRedirect(url)\n },\n [api, sessions, performRedirect],\n )\n\n const doReject = useSafeCallback(async () => {\n const { url } = await api.fetch('POST', '/reject', {})\n performRedirect(url)\n }, [api, performRedirect])\n\n return {\n sessions,\n selectSub,\n\n doSignIn,\n doInitiatePasswordReset,\n doConfirmResetPassword,\n doValidateNewHandle,\n doSignUp,\n doAccept,\n doReject,\n }\n}\n","import { Dispatch, useCallback } from 'react'\n\nexport function useBoundDispatch<A>(dispatch: Dispatch<A>, value: A) {\n return useCallback(() => dispatch(value), [dispatch, value])\n}\n","import { clsx } from 'clsx'\nimport { JSX } from 'react'\nimport { Override } from '../../lib/util.ts'\n\nexport type ButtonProps = Override<\n JSX.IntrinsicElements['button'],\n {\n color?: 'primary' | 'grey'\n loading?: boolean\n transparent?: boolean\n square?: boolean\n }\n>\n\nexport function Button({\n color = 'grey',\n transparent = false,\n loading = undefined,\n square = false,\n\n // button\n children,\n className,\n type = 'button',\n role = 'Button',\n disabled = false,\n ...props\n}: ButtonProps) {\n return (\n <button\n role={role}\n type={type}\n disabled={disabled || loading === true}\n {...props}\n className={clsx(\n 'cursor-pointer touch-manipulation overflow-hidden truncate rounded-md tracking-wide',\n square ? 'p-2' : 'px-6 py-2',\n color === 'primary'\n ? clsx(\n 'accent-slate-100',\n transparent\n ? 'text-primary bg-transparent'\n : 'bg-primary text-primary-contrast',\n )\n : color === 'grey'\n ? clsx(\n 'accent-primary',\n 'text-slate-600 dark:text-slate-300',\n 'hover:bg-gray-200 dark:hover:bg-gray-700',\n transparent ? 'bg-transparent' : 'bg-gray-100 dark:bg-gray-800',\n )\n : undefined,\n 'disabled:opacity-50',\n className,\n )}\n >\n {children}\n </button>\n )\n}\n","import { JSX, ReactNode } from 'react'\nimport { Override } from '../../lib/util.ts'\n\nexport type FormCardProps = Override<\n JSX.IntrinsicElements['form'],\n {\n disabled?: boolean\n append?: ReactNode\n prepend?: ReactNode\n cancel?: ReactNode\n actions?: ReactNode\n }\n>\n\nexport function FormCard({\n actions,\n cancel,\n append,\n children,\n prepend,\n disabled,\n\n // form\n inert = disabled,\n ...props\n}: FormCardProps) {\n return (\n <form {...props} inert={inert} className=\"flex flex-col space-y-4\">\n {prepend && <div key=\"prepend\">{prepend}</div>}\n\n <div key=\"children\" className=\"space-y-4\">\n {children}\n </div>\n\n {append && <div key=\"append\">{append}</div>}\n\n {(actions || cancel) && (\n <div\n key=\"buttons\"\n className=\"flex flex-row-reverse flex-wrap items-center justify-end space-x-2 space-x-reverse\"\n >\n {actions}\n <div className=\"flex-auto\" />\n {cancel}\n </div>\n )}\n </form>\n )\n}\n","import { JSX } from 'react'\nimport type { Account } from '@atproto/oauth-provider-api'\nimport { Override } from '../../lib/util.ts'\n\nexport type AccountIdentifierProps = Override<\n Omit<JSX.IntrinsicElements['b'], 'children'>,\n {\n account: Account\n }\n>\n\nexport function AccountIdentifier({\n account,\n\n // b\n ...props\n}: AccountIdentifierProps) {\n return (\n <b {...props}>\n {account.preferred_username || account.email || account.sub}\n </b>\n )\n}\n","import { JSX, useMemo } from 'react'\nimport { Override } from '../../lib/util.ts'\n\nexport type UrlPartRenderingOptions = {\n faded?: boolean\n bold?: boolean\n}\n\nexport type UrlRendererProps = {\n url: string | URL\n proto?: boolean | UrlPartRenderingOptions\n host?: boolean | UrlPartRenderingOptions\n path?: boolean | UrlPartRenderingOptions\n query?: boolean | UrlPartRenderingOptions\n hash?: boolean | UrlPartRenderingOptions\n as?: string\n}\n\nexport function UrlViewer<As extends keyof JSX.IntrinsicElements = 'span'>({\n url,\n proto = false,\n host = true,\n path = false,\n query = false,\n hash = false,\n as: As = 'span',\n\n // Element\n ...props\n}: Override<JSX.IntrinsicElements[As], UrlRendererProps>) {\n const urlObj = useMemo(() => (url instanceof URL ? url : new URL(url)), [url])\n\n return (\n <As {...props}>\n {proto && (\n <UrlPartViewer\n value={`${urlObj.protocol}//`}\n {...(proto === true ? null : proto)}\n />\n )}\n {host && (\n <UrlPartViewer\n value={urlObj.host}\n {...(host === true ? { faded: false, bold: true } : host)}\n />\n )}\n {path && (\n <UrlPartViewer\n value={urlObj.pathname}\n {...(path === true ? null : path)}\n />\n )}\n {query && (\n <UrlPartViewer\n value={urlObj.search}\n {...(query === true ? null : query)}\n />\n )}\n {hash && (\n <UrlPartViewer value={urlObj.hash} {...(hash === true ? null : hash)} />\n )}\n </As>\n )\n}\n\nfunction UrlPartViewer({\n value,\n faded = true,\n bold = false,\n}: { value: string } & UrlPartRenderingOptions) {\n const Comp = bold ? 'b' : 'span'\n return <Comp className={faded ? 'opacity-50' : ''}>{value}</Comp>\n}\n","import { Trans } from '@lingui/react/macro'\nimport { JSX, useMemo } from 'react'\nimport type { OAuthClientMetadata } from '@atproto/oauth-types'\nimport { Override } from '../../lib/util.ts'\nimport { UrlViewer } from './url-viewer.tsx'\n\nexport type ClientNameProps = Override<\n Omit<JSX.IntrinsicElements['span'], 'children'>,\n {\n clientId: string\n clientMetadata: OAuthClientMetadata\n clientTrusted: boolean\n }\n>\n\nexport function ClientName({\n clientId,\n clientMetadata,\n clientTrusted,\n\n // span\n ...attrs\n}: ClientNameProps) {\n const url = useMemo(() => {\n try {\n return new URL(clientId)\n } catch {\n return null\n }\n }, [clientId])\n\n if (clientTrusted && clientMetadata.client_name) {\n return <span {...attrs}>{clientMetadata.client_name}</span>\n }\n\n // @NOTE: not using isOAuthClientIdLoopback & isOAuthClientIdDiscoverable from\n // @atproto/oauth-types here because 1) we don't need to validate here and 2)\n // we prefer not to import un-necessary code to improve bundle size.\n\n if (url?.protocol === 'http:') {\n return (\n <span {...attrs}>\n <Trans>An application on your device</Trans>\n </span>\n )\n }\n\n if (url?.protocol === 'https:') {\n // Only display the url details if the client id does not follow our\n // convention.\n const simplifiedView =\n url.protocol === 'https:' &&\n url.pathname === '/oauth-client-metadata.json' &&\n !url.port &&\n !url.search\n\n return (\n <UrlViewer\n {...attrs}\n url={url}\n proto={!simplifiedView}\n host={true}\n path={!simplifiedView}\n query={!simplifiedView}\n hash={false}\n />\n )\n }\n\n return <span {...attrs}>{clientId}</span>\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport type { Account, ScopeDetail } from '@atproto/oauth-provider-api'\nimport type { OAuthClientMetadata } from '@atproto/oauth-types'\nimport { Button } from '../../../components/forms/button.tsx'\nimport {\n FormCard,\n FormCardProps,\n} from '../../../components/forms/form-card.tsx'\nimport { AccountIdentifier } from '../../../components/utils/account-identifier.tsx'\nimport { ClientName } from '../../../components/utils/client-name.tsx'\nimport { MultiLangString } from '../../../components/utils/multi-lang-string.tsx'\nimport { Override } from '../../../lib/util.ts'\n\nexport type AcceptFormProps = Override<\n Omit<FormCardProps, 'onSubmit' | 'cancel' | 'actions' | 'children'>,\n {\n clientId: string\n clientMetadata: OAuthClientMetadata\n clientTrusted: boolean\n\n account: Account\n scopeDetails?: ScopeDetail[]\n\n onAccept: () => void\n onReject: () => void\n onBack?: () => void\n }\n>\n\nexport function AcceptForm({\n clientId,\n clientMetadata,\n clientTrusted,\n\n account,\n scopeDetails,\n\n onAccept,\n onReject,\n onBack,\n\n // FormCardProps\n ...props\n}: AcceptFormProps) {\n const { t } = useLingui()\n return (\n <FormCard\n {...props}\n onSubmit={(event) => {\n event.preventDefault()\n onAccept()\n }}\n cancel={onBack && <Button onClick={onBack}>Back</Button>}\n actions={\n <>\n <Button type=\"submit\" color=\"primary\">\n <Trans>Authorize</Trans>\n </Button>\n\n <Button onClick={onReject}>\n <Trans>Deny access</Trans>\n </Button>\n </>\n }\n >\n {clientTrusted && clientMetadata.logo_uri && (\n <div key=\"logo\" className=\"flex items-center justify-center\">\n <img\n crossOrigin=\"anonymous\"\n src={clientMetadata.logo_uri}\n alt={clientMetadata.client_name}\n className=\"h-16 w-16 rounded-full\"\n />\n </div>\n )}\n <p>\n <Trans>\n <ClientName\n clientId={clientId}\n clientMetadata={clientMetadata}\n clientTrusted={clientTrusted}\n />{' '}\n is asking for permission to access your account (\n <AccountIdentifier account={account} />\n ).\n </Trans>\n </p>\n\n <p>\n <Trans>\n By clicking{' '}\n <b>\n <Trans>Authorize</Trans>\n </b>\n , you allow this application to perform the following actions in\n accordance with their{' '}\n <a\n role=\"link\"\n href={clientMetadata.tos_uri}\n rel=\"nofollow noopener\"\n target=\"_blank\"\n className=\"text-primary underline\"\n >\n <Trans>terms of service</Trans>\n </a>\n {' and '}\n <a\n role=\"link\"\n href={clientMetadata.policy_uri}\n rel=\"nofollow noopener\"\n target=\"_blank\"\n className=\"text-primary underline\"\n >\n <Trans>privacy policy</Trans>\n </a>\n :\n </Trans>\n </p>\n\n {scopeDetails?.length ? (\n <ul\n className=\"list-inside list-disc\"\n key=\"scopes\"\n aria-label={t`Requested permissions`}\n >\n {scopeDetails.map(({ scope, description }) => (\n <li key={scope}>\n {description ? (\n <MultiLangString value={description} />\n ) : (\n <ScopeDescription scope={scope} />\n )}\n </li>\n ))}\n </ul>\n ) : null}\n </FormCard>\n )\n}\n\ntype ScopeDescriptionProps = {\n scope: string\n}\nfunction ScopeDescription({ scope }: ScopeDescriptionProps) {\n switch (scope) {\n case 'atproto':\n return <Trans>Uniquely identify you</Trans>\n case 'transition:generic':\n return <Trans>Access your account data (except chat messages)</Trans>\n case 'transition:chat.bsky':\n return <Trans>Access your chat messages</Trans>\n default:\n return scope\n }\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport type { Account, ScopeDetail } from '@atproto/oauth-provider-api'\nimport type { OAuthClientMetadata } from '@atproto/oauth-types'\nimport {\n LayoutTitlePage,\n LayoutTitlePageProps,\n} from '../../../components/layouts/layout-title-page.tsx'\nimport { Override } from '../../../lib/util.ts'\nimport { AcceptForm } from './accept-form.tsx'\n\nexport type AcceptViewProps = Override<\n LayoutTitlePageProps,\n {\n clientId: string\n clientMetadata: OAuthClientMetadata\n clientTrusted: boolean\n\n account: Account\n scopeDetails?: ScopeDetail[]\n\n onAccept: () => void\n onReject: () => void\n onBack?: () => void\n }\n>\n\nexport function AcceptView({\n clientId,\n clientMetadata,\n clientTrusted,\n account,\n scopeDetails,\n onAccept,\n onReject,\n onBack,\n\n // LayoutTitlePage\n title,\n subtitle = (\n <Trans>\n Grant access to your{' '}\n <b className=\"text-slate-800 dark:text-slate-200\">\n {account.preferred_username || account.email || account.sub}\n </b>{' '}\n account\n </Trans>\n ),\n ...props\n}: AcceptViewProps) {\n const { t } = useLingui()\n\n return (\n <LayoutTitlePage\n {...props}\n title={title ?? t`Authorize`}\n subtitle={subtitle}\n >\n <AcceptForm\n clientId={clientId}\n clientMetadata={clientMetadata}\n clientTrusted={clientTrusted}\n account={account}\n scopeDetails={scopeDetails}\n onBack={onBack}\n onAccept={onAccept}\n onReject={onReject}\n />\n </LayoutTitlePage>\n )\n}\n","import { JSX, ReactNode, createContext, useMemo } from 'react'\nimport { useRandomString } from '../../hooks/use-random-string.ts'\nimport { Override } from '../../lib/util.ts'\n\nexport type FieldsetContextValue = {\n disabled: boolean\n labelId?: string\n}\n\nexport const FieldsetContext = createContext<FieldsetContextValue>({\n disabled: false,\n})\nFieldsetContext.displayName = 'FieldsetContext'\n\nexport type FieldsetCardProps = Override<\n Omit<JSX.IntrinsicElements['fieldset'], 'aria-labelledby'>,\n {\n label?: ReactNode\n }\n>\n\nexport function Fieldset({\n label,\n children,\n disabled,\n ...props\n}: FieldsetCardProps) {\n const labelId = useRandomString({ prefix: 'fieldset-' })\n\n const contextValue = useMemo(\n () => ({\n disabled: disabled ?? false,\n labelId: label ? labelId : undefined,\n }),\n [disabled, label, labelId],\n )\n\n return (\n <fieldset {...props} aria-labelledby={labelId} disabled={disabled}>\n {label && (\n <legend\n id={labelId}\n key=\"title\"\n className=\"mb-1 text-sm font-medium text-slate-600 dark:text-slate-400\"\n >\n {label}\n </legend>\n )}\n\n <div className=\"flex flex-col space-y-4\">\n <FieldsetContext value={contextValue}>{children}</FieldsetContext>\n </div>\n </fieldset>\n )\n}\n","import {\n ForwardedRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react'\n\nexport type AsyncActionController = {\n reset: () => void\n}\n\nexport type UseAsyncActionOptions = {\n ref?: ForwardedRef<AsyncActionController>\n onLoading?: (loading: boolean) => void\n onError?: (error: Error | undefined) => void\n}\n\nexport function useAsyncAction(\n fn: (signal: AbortSignal) => void | PromiseLike<void>,\n { ref, onLoading, onError }: UseAsyncActionOptions = {},\n) {\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<Error | undefined>()\n\n const doSetError = useCallback(\n (error: Error | undefined) => {\n setError(error)\n onError?.(error)\n },\n [onError],\n )\n\n const doSetLoading = useCallback(\n (loading: boolean) => {\n setLoading(loading)\n onLoading?.(loading)\n },\n [onLoading],\n )\n\n const controllerRef = useRef<AbortController>(null)\n\n const resetRef = useRef<() => void>(null)\n useEffect(() => {\n resetRef.current = () => {\n controllerRef.current?.abort()\n controllerRef.current = null\n doSetError(undefined)\n doSetLoading(false)\n }\n return () => {\n resetRef.current = null\n }\n }, [doSetError, doSetLoading])\n\n useImperativeHandle(\n ref,\n (): AsyncActionController => ({\n reset: () => resetRef.current?.(),\n }),\n [],\n )\n\n // Cancel pending action when unmounted\n useEffect(() => {\n return () => {\n controllerRef.current?.abort()\n controllerRef.current = null\n }\n }, [])\n\n const run = useCallback(async (): Promise<void> => {\n // Cancel previous run\n controllerRef.current?.abort()\n\n doSetLoading(true)\n doSetError(undefined)\n\n const controller = new AbortController()\n const { signal } = controller\n\n controllerRef.current = controller\n\n try {\n await fn(signal)\n } catch (err) {\n if (controller === controllerRef.current) {\n doSetError(err instanceof Error ? err : new Error(String(err)))\n } else {\n if (!isAbortReason(signal, err)) {\n console.warn('Async action error after abort', err)\n }\n }\n } finally {\n if (controller === controllerRef.current) {\n controllerRef.current = null\n doSetLoading(false)\n }\n\n controller.abort()\n }\n }, [fn, doSetLoading, doSetError])\n\n return {\n loading,\n error,\n run,\n }\n}\n\nfunction isAbortReason(signal: AbortSignal, err: unknown): boolean {\n return (\n signal.aborted &&\n (signal.reason === err ||\n signal.reason === err?.['cause'] ||\n (err instanceof DOMException && err.name === 'AbortError'))\n )\n}\n","import { Trans } from '@lingui/react/macro'\nimport { FormEvent, ReactNode, useCallback } from 'react'\nimport {\n UseAsyncActionOptions,\n useAsyncAction,\n} from '../../hooks/use-async-action.ts'\nimport { Override } from '../../lib/util.ts'\nimport { ErrorCard } from '../utils/error-card.tsx'\nimport { Button } from './button.tsx'\nimport { FormCard, FormCardProps } from './form-card.tsx'\n\nexport type { AsyncActionController } from '../../hooks/use-async-action.ts'\n\nexport type ErrorRender = (data: { error: Error }) => ReactNode\nexport const errorRenderDefault: ErrorRender = ({ error }) => (\n <ErrorCard error={error} />\n)\n\nexport type FormCardAsyncProps = Override<\n Override<\n Omit<FormCardProps, 'cancel' | 'actions' | 'prepend'>,\n Pick<UseAsyncActionOptions, 'ref' | 'onLoading' | 'onError'>\n >,\n {\n invalid?: boolean\n disabled?: boolean\n\n onSubmit: (signal: AbortSignal) => void | PromiseLike<void>\n submitLabel?: ReactNode\n\n onCancel?: () => void\n cancelLabel?: ReactNode\n\n errorRender?: ErrorRender\n }\n>\n\nexport function FormCardAsync({\n invalid,\n disabled,\n\n onSubmit,\n submitLabel,\n\n onCancel = undefined,\n cancelLabel,\n\n errorRender = errorRenderDefault,\n\n // UseAsyncActionOptions\n ref,\n onLoading,\n onError,\n\n // FormCardProps\n children,\n ...props\n}: FormCardAsyncProps) {\n const { run, loading, error } = useAsyncAction(onSubmit, {\n ref,\n onError,\n onLoading,\n })\n\n const doSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n if (!event.currentTarget.reportValidity()) return\n\n if (!disabled && !invalid) void run()\n },\n [disabled, invalid, run],\n )\n\n return (\n <FormCard\n {...props}\n onSubmit={doSubmit}\n disabled={disabled || loading}\n prepend={error != null ? errorRender({ error }) : undefined}\n cancel={\n onCancel && (\n <Button onClick={onCancel}>\n {cancelLabel || <Trans>Cancel</Trans>}\n </Button>\n )\n }\n actions={\n <Button\n color=\"primary\"\n type=\"submit\"\n loading={loading}\n disabled={disabled}\n >\n {submitLabel || <Trans>Submit</Trans>}\n </Button>\n }\n >\n {children}\n </FormCard>\n )\n}\n","export const MIN_PASSWORD_LENGTH = 8\n\nconst EMOJI =\n /(\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff])/\nconst UPPER = /[A-Z]/\nconst LOWER = /[a-z]/\nconst DEC = /[0-9]/\nconst SPECIAL = /[^a-zA-Z0-9]/\n\nexport enum PasswordStrength {\n weak = 1,\n moderate = 2,\n strong = 3,\n extra = 4,\n}\n\nexport function getPasswordStrength(pwd: string): PasswordStrength {\n if (pwd.length < MIN_PASSWORD_LENGTH) {\n return PasswordStrength.weak\n }\n\n // Very long passwords\n if (pwd.length >= MIN_PASSWORD_LENGTH + 12) {\n return PasswordStrength.extra\n }\n\n // Long passwords\n if (pwd.length >= MIN_PASSWORD_LENGTH + 8) {\n if (matches(pwd, [SPECIAL])) {\n return PasswordStrength.extra\n }\n if (matches(pwd, [UPPER, LOWER, DEC], 2)) {\n return PasswordStrength.extra\n }\n return PasswordStrength.strong\n }\n\n // Emojis make passwords strong\n if (pwd.length >= MIN_PASSWORD_LENGTH) {\n if (matches(pwd, [EMOJI])) {\n return PasswordStrength.strong\n }\n }\n\n // Pretty long passwords\n if (pwd.length >= MIN_PASSWORD_LENGTH + 6) {\n if (matches(pwd, [SPECIAL])) {\n return PasswordStrength.strong\n }\n if (matches(pwd, [UPPER, LOWER, DEC], 2)) {\n return PasswordStrength.strong\n }\n // Only 1 type of alpha-num characters\n return PasswordStrength.moderate\n }\n\n // Longish password\n if (pwd.length >= MIN_PASSWORD_LENGTH + 4) {\n if (matches(pwd, [SPECIAL])) {\n return PasswordStrength.moderate\n }\n if (matches(pwd, [UPPER, LOWER, DEC], 2)) {\n return PasswordStrength.moderate\n }\n\n // Only 1 type of alpha-num characters\n return PasswordStrength.weak\n }\n\n // Short password (8-11 characters)\n if (pwd.length >= MIN_PASSWORD_LENGTH) {\n if (matches(pwd, [SPECIAL])) {\n return PasswordStrength.moderate\n }\n if (matches(pwd, [UPPER, LOWER, DEC])) {\n return PasswordStrength.moderate\n }\n }\n\n return PasswordStrength.weak\n}\n\nfunction matches(\n pwd: string,\n regexps: RegExp[],\n regexpsCountToMatch: number = regexps.length,\n): boolean {\n if (regexpsCountToMatch < 1 || regexpsCountToMatch > regexps.length) {\n throw new TypeError('Invalid regexpsCountToMatch')\n }\n for (const regexp of regexps) {\n if (regexp.test(pwd)) {\n regexpsCountToMatch--\n if (regexpsCountToMatch === 0) return true\n }\n }\n return false\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { JSX } from 'react'\nimport { PasswordStrength, getPasswordStrength } from '../../lib/password.ts'\nimport { Override } from '../../lib/util.ts'\n\nexport type PasswordStrengthLabelProps = Override<\n Omit<JSX.IntrinsicElements['span'], 'children' | 'aria-label'>,\n {\n password: string\n }\n>\n\nexport function PasswordStrengthLabel({\n password,\n\n // span\n ...props\n}: PasswordStrengthLabelProps) {\n const { t } = useLingui()\n const strength = getPasswordStrength(password)\n\n return (\n <span {...props} aria-label={t`Password strength`}>\n {strength === PasswordStrength.extra ? (\n <Trans>Extra</Trans>\n ) : strength === PasswordStrength.strong ? (\n <Trans>Strong</Trans>\n ) : strength === PasswordStrength.moderate ? (\n <Trans>Moderate</Trans>\n ) : password ? (\n <Trans>Weak</Trans>\n ) : (\n <Trans>Missing</Trans>\n )}\n </span>\n )\n}\n","import { useLingui } from '@lingui/react/macro'\nimport { clsx } from 'clsx'\nimport { JSX } from 'react'\nimport { PasswordStrength, getPasswordStrength } from '../../lib/password.ts'\nimport { Override } from '../../lib/util.ts'\n\nexport type PasswordStrengthMeterProps = Override<\n Omit<\n JSX.IntrinsicElements['div'],\n | 'children'\n | 'role'\n | 'aria-label'\n | 'aria-valuemin'\n | 'aria-valuemax'\n | 'aria-valuenow'\n >,\n {\n password: string\n }\n>\n\nexport function PasswordStrengthMeter({\n password,\n\n // div\n className,\n ...props\n}: PasswordStrengthMeterProps) {\n const { t } = useLingui()\n const strength = password ? getPasswordStrength(password) : 0\n\n const colorBg = 'bg-gray-300 dark:bg-slate-500'\n const color =\n strength === PasswordStrength.extra || strength === PasswordStrength.strong\n ? 'bg-success'\n : strength === PasswordStrength.moderate\n ? 'bg-warning'\n : 'bg-error'\n\n return (\n <div\n {...props}\n className={clsx('flex h-1 w-full space-x-2', className)}\n role=\"meter\"\n aria-label={t`Password strength indicator`}\n aria-valuemin={0}\n aria-valuemax={PasswordStrength.extra}\n aria-valuenow={strength}\n >\n {Array.from({ length: 4 }, (_, i) => (\n <div\n key={i}\n className={`h-1 w-1/4 rounded-sm ${strength > i ? color : colorBg}`}\n />\n ))}\n </div>\n )\n}\n","import { ForwardedRef } from 'react'\n\nexport function updateRef<T>(ref: ForwardedRef<T>, value: T | null) {\n if (typeof ref === 'function') {\n ref(value)\n } else if (ref) {\n ref.current = value\n }\n}\n\nexport function mergeRefs<T>(refs: readonly (ForwardedRef<T> | undefined)[]) {\n return (value: T | null) => {\n for (const ref of refs) {\n if (ref) updateRef(ref, value)\n }\n }\n}\n","import { useLingui } from '@lingui/react/macro'\nimport { Override } from '../../lib/util.ts'\nimport { EyeIcon, EyeSlashIcon } from '../utils/icons.tsx'\nimport { Button, ButtonProps } from './button.tsx'\n\nexport type ButtonToggleVisibilityProps = Override<\n Omit<ButtonProps, 'aria-label' | 'square'>,\n {\n visible: boolean\n toggleVisible: () => void\n }\n>\n\n/**\n * Generic button to toggle visibility of an item (e.g. password).\n */\nexport function ButtonToggleVisibility({\n visible,\n toggleVisible,\n\n // button\n onClick,\n ...props\n}: ButtonToggleVisibilityProps) {\n const { t } = useLingui()\n return (\n <Button\n {...props}\n square\n onClick={(event) => {\n onClick?.(event)\n if (!event.defaultPrevented) toggleVisible()\n }}\n aria-label={visible ? t`Hide` : t`Make visible`}\n >\n {visible ? (\n <EyeIcon className=\"w-5\" aria-hidden />\n ) : (\n <EyeSlashIcon className=\"w-5\" aria-hidden />\n )}\n </Button>\n )\n}\n","import { clsx } from 'clsx'\nimport { JSX, ReactNode, useState } from 'react'\nimport { Override } from '../../lib/util.ts'\n\nexport type InputContainerProps = Override<\n JSX.IntrinsicElements['div'],\n {\n icon: ReactNode\n append?: ReactNode\n bellow?: ReactNode\n }\n>\n\nexport function InputContainer({\n icon,\n append,\n bellow,\n\n // div\n className,\n children,\n onFocus,\n onBlur,\n ...props\n}: InputContainerProps) {\n const [hasFocus, setHasFocus] = useState(false)\n\n return (\n <div\n {...props}\n onFocus={(event) => {\n onFocus?.(event)\n if (!event.defaultPrevented) setHasFocus(true)\n }}\n onBlur={(event) => {\n onBlur?.(event)\n if (!event.defaultPrevented) setHasFocus(false)\n }}\n className={clsx(\n // Layout\n 'min-h-12',\n 'max-w-full',\n 'overflow-hidden',\n // Border\n 'rounded-lg',\n className,\n )}\n >\n <div\n className={clsx(\n // Layout\n 'px-1',\n 'min-h-12 w-full',\n 'flex items-center justify-stretch',\n // Border\n 'rounded-lg',\n bellow ? 'rounded-bl-none rounded-br-none' : undefined,\n 'outline-hidden',\n 'border-2 border-solid border-transparent',\n 'focus:border-primary has-focus:border-primary',\n 'hover:border-gray-400 hover:focus:border-gray-400',\n 'dark:hover:border-gray-500 dark:hover:focus:border-gray-500',\n // Background\n 'has-focus:bg-slate-200 bg-gray-100 focus:bg-slate-200',\n 'dark:has-focus:bg-slate-700 dark:bg-slate-800 dark:focus:bg-slate-700',\n // Font\n 'text-slate-600 dark:text-slate-300',\n 'accent-primary',\n )}\n >\n {icon && (\n <div\n className={clsx(\n 'shrink-0 grow-0',\n 'mx-1',\n hasFocus ? 'text-primary' : 'text-slate-500',\n )}\n >\n {icon}\n </div>\n )}\n\n {children}\n\n <div className=\"ml-1 flex shrink-0 grow-0 items-center\">{append}</div>\n </div>\n {bellow && (\n <div\n className={clsx(\n // Layout\n 'space-x-2 px-3 py-2',\n 'flex flex-row items-center gap-1',\n // Border\n 'rounded-br-2 rounded-bl-2',\n // Background\n 'bg-gray-200 dark:bg-slate-700',\n // Font\n 'text-gray-700 dark:text-gray-300',\n 'text-sm italic',\n )}\n >\n {bellow}\n </div>\n )}\n </div>\n )\n}\n","import { clsx } from 'clsx'\nimport { JSX, ReactNode, useContext, useRef } from 'react'\nimport { mergeRefs } from '../../lib/ref.ts'\nimport { Override } from '../../lib/util.ts'\nimport { FieldsetContext } from './fieldset.tsx'\nimport { InputContainer } from './input-container.tsx'\n\nexport type InputTextProps = Override<\n Omit<JSX.IntrinsicElements['input'], 'children'>,\n {\n icon?: ReactNode\n append?: ReactNode\n bellow?: ReactNode\n className?: string\n }\n>\n\nexport function InputText({\n icon,\n append,\n bellow,\n className,\n\n // input\n onFocus,\n onBlur,\n ref,\n disabled,\n title,\n 'aria-label': ariaLabel = title,\n 'aria-labelledby': ariaLabelledBy,\n placeholder = ariaLabel,\n ...props\n}: InputTextProps) {\n const ctx = useContext(FieldsetContext)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const focusedRef = useRef(false) // ref instead of state to avoid re-renders\n\n return (\n <InputContainer\n icon={icon}\n append={append}\n bellow={bellow}\n className={clsx('cursor-text', className)}\n tabIndex={-1}\n onClick={(event) => {\n if (inputRef.current !== event.target) {\n event.preventDefault()\n event.stopPropagation()\n inputRef.current?.focus()\n }\n }}\n onMouseDown={(event) => {\n if (focusedRef.current && event.target !== inputRef.current) {\n // Prevent \"blur\" event from firing when clicking outside the input\n event.preventDefault()\n event.stopPropagation()\n }\n }}\n >\n <input\n {...props}\n disabled={disabled ?? ctx.disabled}\n title={title}\n placeholder={placeholder}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy ?? ctx.labelId}\n ref={mergeRefs([ref, inputRef])}\n className=\"outline-hidden w-full text-ellipsis bg-transparent bg-clip-padding text-base text-inherit dark:placeholder-gray-500\"\n onFocus={(event) => {\n onFocus?.(event)\n if (!event.defaultPrevented) focusedRef.current = true\n }}\n onBlur={(event) => {\n onBlur?.(event)\n if (!event.defaultPrevented) focusedRef.current = false\n }}\n />\n </InputContainer>\n )\n}\n","import { useLingui } from '@lingui/react/macro'\nimport { ChangeEvent, useCallback, useRef, useState } from 'react'\nimport { mergeRefs } from '../../lib/ref.ts'\nimport { Override } from '../../lib/util.ts'\nimport { LockIcon } from '../utils/icons.tsx'\nimport { ButtonToggleVisibility } from './button-toggle-visibility.tsx'\nimport { InputText, InputTextProps } from './input-text.tsx'\n\nexport type InputPasswordProps = Override<\n Omit<InputTextProps, 'type' | 'children'>,\n {\n autoHide?: boolean\n }\n>\n\nexport function InputPassword({\n autoHide = true,\n\n // InputTextProps\n onBlur,\n onChange,\n append,\n autoComplete = 'current-password',\n icon = <LockIcon className=\"w-5\" />,\n value,\n defaultValue = value,\n ref,\n title,\n dir = 'auto',\n autoCapitalize = 'none',\n autoCorrect = 'off',\n spellCheck = 'false',\n ...props\n}: InputPasswordProps) {\n const { t } = useLingui()\n const inputRef = useRef<HTMLInputElement>(null)\n const [visible, setVisible] = useState<boolean>(false)\n const [password, setPassword] = useState<string>(\n typeof defaultValue === 'string' ? defaultValue : '',\n )\n\n const doChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n onChange?.(event)\n setPassword(event.target.value)\n },\n [onChange],\n )\n\n return (\n <InputText\n {...props}\n title={title ?? t`Password`}\n ref={mergeRefs([ref, inputRef])}\n dir={dir}\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n spellCheck={spellCheck}\n icon={icon}\n onBlur={\n autoHide\n ? (event) => {\n onBlur?.(event)\n if (!event.defaultPrevented) setVisible(false)\n }\n : onBlur\n }\n value={password}\n onChange={doChange}\n type={visible ? 'text' : 'password'}\n autoComplete={autoComplete}\n append={\n <>\n <ButtonToggleVisibility\n className=\"m-1\"\n visible={visible}\n toggleVisible={() => {\n setVisible((prev) => !prev)\n inputRef.current?.focus()\n }}\n />\n {append}\n </>\n }\n />\n )\n}\n","import { useLingui } from '@lingui/react/macro'\nimport { ChangeEvent, useCallback, useState } from 'react'\nimport { MIN_PASSWORD_LENGTH } from '../../lib/password.ts'\nimport { Override } from '../../lib/util.ts'\nimport { PasswordStrengthLabel } from '../utils/password-strength-label.tsx'\nimport { PasswordStrengthMeter } from '../utils/password-strength-meter.tsx'\nimport { InputPassword, InputPasswordProps } from './input-password.tsx'\n\nexport type InputNewPasswordProps = Override<\n Omit<InputPasswordProps, 'value' | 'defaultValue'>,\n {\n password?: string\n onPassword?: (password: undefined | string) => void\n }\n>\n\nexport function InputNewPassword({\n password: passwordInit = '',\n onPassword,\n\n // InputPasswordProps\n onChange,\n autoComplete = 'new-password',\n minLength = MIN_PASSWORD_LENGTH,\n ...props\n}: InputNewPasswordProps) {\n const { t } = useLingui()\n const [password, setPassword] = useState<string>(passwordInit)\n\n const doChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n const { value } = event.target\n onChange?.(event)\n if (event.defaultPrevented) return\n setPassword(value)\n onPassword?.(event.target.validity.valid ? value : undefined)\n },\n [onChange, onPassword],\n )\n\n return (\n <InputPassword\n {...props}\n placeholder={t`Enter a password`}\n aria-label={t`Enter your new password`}\n title={t`Password with at least ${MIN_PASSWORD_LENGTH} characters`}\n minLength={minLength}\n onChange={doChange}\n value={password}\n autoComplete={autoComplete}\n bellow={\n <>\n <PasswordStrengthMeter password={password} />\n <PasswordStrengthLabel\n className=\"grow-1 min-w-max text-xs text-gray-500 dark:text-gray-400\"\n password={password}\n />\n </>\n }\n />\n )\n}\n","import { useLingui } from '@lingui/react/macro'\nimport { ChangeEvent, useState } from 'react'\nimport { Override } from '../../lib/util.ts'\nimport { TokenIcon } from '../utils/icons.tsx'\nimport { InputText, InputTextProps } from './input-text.tsx'\n\nexport type InputTokenProps = Override<\n Omit<\n InputTextProps,\n | 'type'\n | 'pattern'\n | 'autoCapitalize'\n | 'autoCorrect'\n | 'autoComplete'\n | 'spellCheck'\n | 'minLength'\n | 'maxLength'\n | 'placeholder'\n | 'dir'\n >,\n {\n example?: string\n onToken?: (code: string | null) => void\n }\n>\n\nexport const OTP_CODE_EXAMPLE = 'XXXXX-XXXXX'\n\nexport function InputToken({\n example = OTP_CODE_EXAMPLE,\n onToken,\n\n // InputTextProps\n icon = <TokenIcon className=\"w-5\" />,\n title = example,\n onChange,\n value,\n defaultValue = value,\n ...props\n}: InputTokenProps) {\n const { t } = useLingui()\n const [token, setToken] = useState<string>(\n typeof defaultValue === 'string' ? defaultValue : '',\n )\n\n return (\n <InputText\n {...props}\n type=\"text\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n autoComplete=\"off\"\n spellCheck=\"false\"\n minLength={11}\n maxLength={11}\n dir=\"auto\"\n icon={icon}\n pattern=\"^[A-Z2-7]{5}-[A-Z2-7]{5}$\"\n placeholder={t`Looks like ${example}`}\n title={title}\n value={token}\n onChange={(event: ChangeEvent<HTMLInputElement>) => {\n const { value, selectionEnd, selectionStart } = event.currentTarget\n\n const fixedValue = fix(value)\n\n event.currentTarget.value = fixedValue\n\n // Move the cursor back where it was relative to the original value\n const pos = selectionEnd ?? selectionStart\n if (pos != null) {\n const fixedSlicedValue = fix(value.slice(0, pos))\n event.currentTarget.selectionStart =\n event.currentTarget.selectionEnd = fixedSlicedValue.length\n }\n\n setToken(fixedValue)\n onChange?.(event)\n\n if (!event.isDefaultPrevented()) {\n onToken?.(fixedValue.length === 11 ? fixedValue : null)\n }\n }}\n />\n )\n}\n\nfunction fix(value: string) {\n const normalized = value.toUpperCase().replaceAll(/[^A-Z2-7]/g, '')\n\n if (normalized.length <= 5) return normalized\n\n return `${normalized.slice(0, 5)}-${normalized.slice(5, 10)}`\n}\n","import { Trans } from '@lingui/react/macro'\nimport { useRef, useState } from 'react'\nimport { Fieldset } from '../../../components/forms/fieldset.tsx'\nimport {\n FormCardAsync,\n FormCardAsyncProps,\n} from '../../../components/forms/form-card-async.tsx'\nimport { InputNewPassword } from '../../../components/forms/input-new-password.tsx'\nimport { InputToken } from '../../../components/forms/input-token.tsx'\nimport { Admonition } from '../../../components/utils/admonition.tsx'\nimport { useRandomString } from '../../../hooks/use-random-string.ts'\nimport { Override } from '../../../lib/util.ts'\n\nexport type ResetPasswordConfirmFormProps = Override<\n FormCardAsyncProps,\n {\n onSubmit: (\n data: {\n token: string\n password: string\n },\n signal: AbortSignal,\n ) => void | PromiseLike<void>\n\n tokenPattern?: string\n tokenFormat?: string\n tokenParseValue?: (value: string) => string | false\n }\n>\n\nexport function ResetPasswordConfirmForm({\n onSubmit,\n\n // FormCardAsyncProps\n invalid,\n ...props\n}: ResetPasswordConfirmFormProps) {\n const tokenAriaId = useRandomString({ prefix: 'reset-pwd-email-' })\n const passwordRef = useRef<HTMLInputElement>(null)\n\n const [token, setToken] = useState<string | null>(null)\n const [password, setPassword] = useState<string | undefined>(undefined)\n\n return (\n <FormCardAsync\n {...props}\n onSubmit={(signal) => {\n if (token && password) return onSubmit({ token, password }, signal)\n }}\n invalid={invalid || !token || !password}\n >\n <Admonition role=\"info\">\n <p id={tokenAriaId} className=\"text-md\">\n <Trans>\n You will receive an email with a \"reset code\". Enter that code here\n then enter your new password.\n </Trans>\n </p>\n </Admonition>\n\n <Fieldset label={<Trans>Reset code</Trans>}>\n <InputToken\n name=\"code\"\n aria-labelledby={tokenAriaId}\n enterKeyHint=\"next\"\n required\n autoFocus={true}\n onToken={(token) => {\n setToken(token)\n // Auto-focus next field when token is complete\n if (token) passwordRef.current?.focus()\n }}\n />\n </Fieldset>\n\n <Fieldset label={<Trans>New password</Trans>}>\n <InputNewPassword\n ref={passwordRef}\n name=\"password\"\n enterKeyHint=\"done\"\n required\n password={password}\n onPassword={setPassword}\n />\n </Fieldset>\n </FormCardAsync>\n )\n}\n","import { useLingui } from '@lingui/react/macro'\nimport { ChangeEvent, useCallback, useState } from 'react'\nimport { Override } from '../../lib/util.ts'\nimport { AtSymbolIcon } from '../utils/icons.tsx'\nimport { InputText, InputTextProps } from './input-text.tsx'\n\nexport type InputEmailAddressProps = Override<\n Omit<InputTextProps, 'type'>,\n {\n onEmail?: (email: string | undefined) => void\n }\n>\n\nexport function InputEmailAddress({\n onEmail,\n\n // InputTextProps\n autoCapitalize = 'none',\n autoComplete = 'email',\n autoCorrect = 'off',\n dir = 'auto',\n icon = <AtSymbolIcon className=\"w-5\" />,\n onBlur,\n onChange,\n pattern = '^[^@]+@[^@]+\\\\.[^@]+$',\n spellCheck = 'false',\n value,\n defaultValue = value,\n title,\n ...props\n}: InputEmailAddressProps) {\n const { t } = useLingui()\n const [email, setEmail] = useState<string>(\n typeof defaultValue === 'string' ? defaultValue : '',\n )\n\n const doChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n const email = event.target.value.toLowerCase()\n\n setEmail(email)\n onChange?.(event)\n onEmail?.(event.target.validity.valid ? email : undefined)\n },\n [onChange, onEmail],\n )\n\n return (\n <InputText\n {...props}\n title={title ?? t`Email address`}\n type=\"email\"\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n dir={dir}\n spellCheck={spellCheck}\n icon={icon}\n pattern={pattern}\n autoComplete={autoComplete}\n value={email}\n onChange={doChange}\n onBlur={onBlur}\n />\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { useCallback, useRef, useState } from 'react'\nimport { Fieldset } from '../../../components/forms/fieldset.tsx'\nimport {\n AsyncActionController,\n FormCardAsync,\n FormCardAsyncProps,\n} from '../../../components/forms/form-card-async.tsx'\nimport { InputEmailAddress } from '../../../components/forms/input-email-address.tsx'\nimport { Admonition } from '../../../components/utils/admonition.tsx'\nimport { useRandomString } from '../../../hooks/use-random-string.ts'\nimport { mergeRefs } from '../../../lib/ref.ts'\nimport { Override } from '../../../lib/util.ts'\n\nexport type ResetPasswordRequestFormProps = Override<\n Omit<FormCardAsyncProps, 'children'>,\n {\n emailDefault?: string\n onSubmit: (\n data: { email: string },\n signal: AbortSignal,\n ) => void | PromiseLike<void>\n }\n>\n\nexport function ResetPasswordRequestForm({\n emailDefault,\n onSubmit,\n\n // FormCardAsyncProps\n invalid,\n ref,\n ...props\n}: ResetPasswordRequestFormProps) {\n const { t } = useLingui()\n const emailAriaId = useRandomString({ prefix: 'reset-pwd-email-' })\n const [email, setEmail] = useState(emailDefault)\n\n const ctrlRef = useRef<AsyncActionController>(null)\n\n const doSubmit = useCallback(\n (signal: AbortSignal) => {\n if (email) return onSubmit({ email }, signal)\n },\n [email, onSubmit],\n )\n\n return (\n <FormCardAsync\n {...props}\n ref={mergeRefs([ref, ctrlRef])}\n invalid={invalid || !email}\n onSubmit={doSubmit}\n >\n <Fieldset label={<Trans>Email address</Trans>}>\n <InputEmailAddress\n name=\"email\"\n placeholder={t`Enter your email address`}\n aria-labelledby={emailAriaId}\n title={t`Email address`}\n required\n autoFocus={true}\n value={email}\n onEmail={(email) => {\n ctrlRef.current?.reset()\n setEmail(email)\n }}\n />\n <Admonition role=\"info\">\n <p id={emailAriaId} className=\"\">\n <Trans>\n Enter the email you used to create your account. We'll send you a\n \"reset code\" so you can set a new password.\n </Trans>\n </p>\n </Admonition>\n </Fieldset>\n </FormCardAsync>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { useState } from 'react'\nimport { Button } from '../../../components/forms/button.tsx'\nimport {\n LayoutTitlePage,\n LayoutTitlePageProps,\n} from '../../../components/layouts/layout-title-page.tsx'\nimport { Override } from '../../../lib/util.ts'\nimport { ResetPasswordConfirmForm } from './reset-password-confirm-form.tsx'\nimport { ResetPasswordRequestForm } from './reset-password-request-form.tsx'\n\nexport type ResetPasswordViewProps = Override<\n LayoutTitlePageProps,\n {\n emailDefault?: string\n onresetPasswordRequest: (\n data: { email: string },\n signal: AbortSignal,\n ) => void | PromiseLike<void>\n onResetPasswordConfirm: (\n data: {\n token: string\n password: string\n },\n signal: AbortSignal,\n ) => void | PromiseLike<void>\n onBack: () => void\n }\n>\n\nenum View {\n RequestReset,\n ConfirmReset,\n PasswordUpdated,\n}\n\nexport function ResetPasswordView({\n emailDefault,\n onresetPasswordRequest,\n onResetPasswordConfirm,\n onBack,\n\n // LayoutTitlePage\n ...props\n}: ResetPasswordViewProps) {\n const { t } = useLingui()\n const [view, setView] = useState<View>(View.RequestReset)\n\n if (view === View.RequestReset) {\n return (\n <LayoutTitlePage\n {...props}\n title={props.title || t`Forgot Password`}\n subtitle={\n props.subtitle || <Trans>Let's get your password reset!</Trans>\n }\n >\n <ResetPasswordRequestForm\n emailDefault={emailDefault}\n submitLabel={<Trans>Next</Trans>}\n onSubmit={async (data, signal) => {\n await onresetPasswordRequest(data, signal)\n if (!signal.aborted) setView(View.ConfirmReset)\n }}\n cancelLabel={<Trans>Back</Trans>}\n onCancel={onBack}\n />\n <hr className=\"my-5 border-gray-300 dark:border-gray-700\" />\n <center>\n <Button transparent onClick={() => setView(View.ConfirmReset)}>\n <Trans>Already have a code?</Trans>\n </Button>\n </center>\n </LayoutTitlePage>\n )\n }\n\n if (view === View.ConfirmReset) {\n return (\n <LayoutTitlePage\n {...props}\n title={props.title || t`Reset Password`}\n subtitle={\n props.subtitle || (\n <Trans>Enter the code you received to reset your password.</Trans>\n )\n }\n >\n <ResetPasswordConfirmForm\n submitLabel={<Trans>Next</Trans>}\n onSubmit={async (data, signal) => {\n await onResetPasswordConfirm(data, signal)\n if (!signal.aborted) setView(View.PasswordUpdated)\n }}\n cancelLabel={<Trans>Back</Trans>}\n onCancel={onBack}\n />\n </LayoutTitlePage>\n )\n }\n\n if (view === View.PasswordUpdated) {\n return (\n <LayoutTitlePage\n {...props}\n title={props.title || t`Password Updated`}\n subtitle={\n props.subtitle || <Trans>Your password has been updated!</Trans>\n }\n >\n <center>\n <h2 className=\"pb-2 text-xl font-bold\">\n <Trans>Password updated!</Trans>\n </h2>\n <p className=\"pb-4\">\n <Trans>You can now sign in with your new password.</Trans>\n </p>\n <Button color=\"primary\" onClick={onBack}>\n <Trans>Okay</Trans>\n </Button>\n </center>\n </LayoutTitlePage>\n )\n }\n\n throw new Error(`Invalid view: ${view}`)\n}\n","import { clsx } from 'clsx'\nimport { JSX, ReactNode, useContext, useRef } from 'react'\nimport { useRandomString } from '../../hooks/use-random-string.ts'\nimport { mergeRefs } from '../../lib/ref.ts'\nimport { Override } from '../../lib/util.ts'\nimport { FieldsetContext } from './fieldset.tsx'\nimport { InputContainer } from './input-container.tsx'\n\nexport type InputCheckboxProps = Override<\n Omit<JSX.IntrinsicElements['input'], 'className' | 'type' | 'children'>,\n {\n className?: string\n children?: ReactNode\n }\n>\n\nexport function InputCheckbox({\n className,\n children,\n\n // input\n id,\n ref,\n disabled,\n title,\n 'aria-label': ariaLabel = title,\n 'aria-labelledby': ariaLabelledBy,\n ...props\n}: InputCheckboxProps) {\n const htmlFor = useRandomString('input-checkbox-')\n const labelRef = useRef<HTMLLabelElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const ctx = useContext(FieldsetContext)\n\n const inputId = id ?? htmlFor\n\n return (\n <InputContainer\n className={clsx('cursor-pointer', className)}\n icon={\n <input\n {...props}\n disabled={disabled ?? ctx.disabled}\n title={title}\n aria-label={ariaLabel}\n aria-labelledby={\n children\n ? // Prefer the local \"<label>\" element (through \"htmlFor\") over the wrapping \"<fieldset>\" to describe the checkbox.\n undefined\n : ariaLabelledBy ?? ctx.labelId\n }\n ref={mergeRefs([ref, inputRef])}\n id={inputId}\n className=\"accent-primary outline-hidden\"\n type=\"checkbox\"\n />\n }\n tabIndex={-1}\n onClick={({ target }) => {\n // Native behavior of clicking the label should toggle the checkbox.\n if (target === labelRef.current) return\n if (target === inputRef.current) return\n\n inputRef.current?.click()\n }}\n >\n {children && (\n <label\n ref={labelRef}\n htmlFor={inputId}\n className=\"block w-full cursor-pointer select-none leading-[1.6]\"\n >\n {children}\n </label>\n )}\n </InputContainer>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { useCallback, useRef, useState } from 'react'\nimport { Button } from '../../../components/forms/button.tsx'\nimport { Fieldset } from '../../../components/forms/fieldset.tsx'\nimport {\n FormCardAsync,\n FormCardAsyncProps,\n} from '../../../components/forms/form-card-async.tsx'\nimport { InputCheckbox } from '../../../components/forms/input-checkbox.tsx'\nimport { InputPassword } from '../../../components/forms/input-password.tsx'\nimport { InputText } from '../../../components/forms/input-text.tsx'\nimport { InputToken } from '../../../components/forms/input-token.tsx'\nimport { Admonition } from '../../../components/utils/admonition.tsx'\nimport { AtSymbolIcon } from '../../../components/utils/icons.tsx'\nimport { AsyncActionController } from '../../../hooks/use-async-action.ts'\nimport {\n InvalidCredentialsError,\n SecondAuthenticationFactorRequiredError,\n} from '../../../lib/api.ts'\nimport { mergeRefs } from '../../../lib/ref.ts'\nimport { Override } from '../../../lib/util.ts'\n\nexport type SignInFormOutput = {\n username: string\n password: string\n remember?: boolean\n}\n\nexport type SignInFormProps = Override<\n Omit<FormCardAsyncProps, 'append' | 'onCancel'>,\n {\n usernameDefault?: string\n usernameReadonly?: boolean\n rememberDefault?: boolean\n\n onBack?: () => void\n onForgotPassword?: (emailHint?: string) => void\n onSubmit: (\n credentials: SignInFormOutput,\n signal: AbortSignal,\n ) => void | PromiseLike<void>\n }\n>\n\nexport function SignInForm({\n usernameDefault = '',\n usernameReadonly = false,\n rememberDefault = false,\n\n onSubmit,\n onBack,\n onForgotPassword,\n\n // FormCardAsync\n ref,\n invalid,\n children,\n ...props\n}: SignInFormProps) {\n const { t } = useLingui()\n\n const [username, setUsername] = useState<string>(usernameDefault)\n const [password, setPassword] = useState<string>('')\n const [remember, setRemember] = useState<boolean>(rememberDefault)\n const [otp, setOtp] = useState<string | null>(null)\n\n const [secondFactor, setSecondFactor] =\n useState<null | SecondAuthenticationFactorRequiredError>(null)\n\n const [loading, setLoading] = useState(false)\n\n const formRef = useRef<AsyncActionController>(null)\n\n const clearSecondFactor = useCallback(() => {\n setOtp(null)\n setSecondFactor(null)\n }, [setOtp, setSecondFactor])\n\n const resetState = useCallback(() => {\n clearSecondFactor()\n formRef.current?.reset()\n }, [clearSecondFactor, formRef])\n\n const doSubmit = useCallback(\n async (signal: AbortSignal) => {\n try {\n await onSubmit(\n {\n username,\n password,\n remember,\n ...(secondFactor ? { [secondFactor.type]: otp } : {}),\n },\n signal,\n )\n } catch (err) {\n if (signal.aborted) {\n // If the action was aborted, ignore the error\n return\n }\n\n if (err instanceof SecondAuthenticationFactorRequiredError) {\n setSecondFactor(err)\n\n // Do not re-throw 2FA required error to prevent the form from from\n // displaying it. Instead, we handle the error by showing the second\n // factor form.\n return\n }\n\n if (err instanceof InvalidCredentialsError) {\n // If the username/password are not valid, clear the second factor\n // as valid credentials are a pre-requisite for 2FA.\n clearSecondFactor()\n }\n\n // Any thrown err will be displayed through the form's errorRender\n throw err\n }\n },\n [username, password, remember, secondFactor, otp, onSubmit],\n )\n\n return (\n <FormCardAsync\n {...props}\n ref={mergeRefs([ref, formRef])}\n onLoading={setLoading}\n onCancel={onBack}\n cancelLabel={t`Back`}\n append={children}\n invalid={\n invalid || !username || !password || (secondFactor != null && !otp)\n }\n submitLabel={secondFactor ? t`Confirm` : t`Sign in`}\n onSubmit={doSubmit}\n >\n <Fieldset disabled={loading} label={<Trans>Identifier</Trans>}>\n <InputText\n icon={<AtSymbolIcon className=\"w-5\" />}\n name=\"username\"\n type=\"text\"\n title={t`Username or email address`}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n autoComplete=\"username\"\n spellCheck=\"false\"\n dir=\"auto\"\n enterKeyHint=\"next\"\n required\n readOnly={usernameReadonly}\n disabled={usernameReadonly}\n autoFocus\n value={username}\n onChange={(event) => {\n resetState()\n setUsername(event.target.value)\n }}\n />\n </Fieldset>\n\n <Fieldset disabled={loading} label={<Trans>Password</Trans>}>\n <InputPassword\n name=\"password\"\n onChange={(event) => {\n resetState()\n setPassword(event.target.value)\n }}\n append={\n onForgotPassword && (\n <Button\n className=\"text-sm\"\n type=\"button\"\n onClick={() => {\n onForgotPassword(\n username?.includes('@') ? username : undefined,\n )\n }}\n aria-label={t`Reset your password`}\n >\n <Trans>Forgot?</Trans>\n </Button>\n )\n }\n enterKeyHint={secondFactor ? 'next' : 'done'}\n disabled={loading}\n required\n />\n </Fieldset>\n\n <Admonition role=\"status\">\n <p className=\"text-md text-primary pb-1 font-bold\">\n <Trans>Warning</Trans>\n </p>\n <p className=\"text-sm\">\n <Trans>\n Please verify the domain name of the website before entering your\n password. Never enter your password on a domain you do not trust.\n </Trans>\n </p>\n </Admonition>\n\n <InputCheckbox\n name=\"remember\"\n title={t`Remember this account on this device`}\n enterKeyHint={secondFactor ? 'next' : 'done'}\n checked={remember}\n onChange={(event) => setRemember(event.target.checked)}\n >\n <Trans>Remember this account on this device</Trans>\n </InputCheckbox>\n\n {secondFactor && (\n <Fieldset\n key=\"2fa\"\n disabled={loading}\n label={<Trans>2FA Confirmation</Trans>}\n >\n <div>\n <InputToken\n title={t`Confirmation code`}\n enterKeyHint=\"done\"\n required\n autoFocus={true}\n value={otp ?? ''}\n onToken={setOtp}\n />\n\n <p className=\"text-sm text-slate-600 dark:text-slate-400\">\n <Trans>\n Check your {secondFactor.hint} email for a login code and enter\n it here.\n </Trans>\n </p>\n </div>\n </Fieldset>\n )}\n </FormCardAsync>\n )\n}\n","import { useEffect, useState } from 'react'\nimport { AccountIcon } from './icons.tsx'\n\nexport type AccountIconProps = {\n src?: string\n alt: string\n}\n\nexport function AccountImage({ src, alt }: AccountIconProps) {\n const [errored, setErrored] = useState(false)\n\n useEffect(() => {\n setErrored(false)\n }, [src])\n\n return src && !errored ? (\n <img\n aria-hidden\n crossOrigin=\"anonymous\"\n src={src}\n alt={alt}\n className=\"-ml-1 h-6 w-6 rounded-full\"\n onError={() => setErrored(true)}\n />\n ) : (\n <div\n aria-hidden\n className=\"bg-primary border-primary h-6 w-6 overflow-hidden rounded-full border-2 border-solid text-white\"\n >\n <AccountIcon className=\"-mx-1 -mb-1\" />\n </div>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport type { Account } from '@atproto/oauth-provider-api'\nimport { Button } from '../../../components/forms/button.tsx'\nimport {\n FormCard,\n FormCardProps,\n} from '../../../components/forms/form-card.tsx'\nimport { InputContainer } from '../../../components/forms/input-container.tsx'\nimport { AccountImage } from '../../../components/utils/account-image.tsx'\nimport {\n AtSymbolIcon,\n CaretRightIcon,\n} from '../../../components/utils/icons.tsx'\nimport { Override } from '../../../lib/util.ts'\n\nexport type SignInPickerProps = Override<\n Omit<FormCardProps, 'cancel' | 'actions' | 'append'>,\n {\n accounts: readonly Account[]\n\n onAccount: (account: Account) => void\n onOther?: () => void\n onBack?: () => void\n }\n>\n\nexport function SignInPicker({\n accounts,\n\n onAccount,\n onOther = undefined,\n onBack,\n\n // FormCard\n children,\n ...props\n}: SignInPickerProps) {\n const { t } = useLingui()\n return (\n <FormCard\n {...props}\n append={children}\n actions={null}\n cancel={\n onBack && (\n <Button onClick={onBack}>\n <Trans>Back</Trans>\n </Button>\n )\n }\n >\n <p className=\"text-sm font-medium text-slate-600 dark:text-slate-400\">\n <Trans>Sign in as...</Trans>\n </p>\n\n {accounts.map((account) => {\n const [name, identifier] = [\n account.name,\n account.preferred_username,\n account.email,\n account.sub,\n ].filter(Boolean) as [string, string?]\n\n return (\n <InputContainer\n tabIndex={0}\n key={account.sub}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n onAccount(account)\n }\n }}\n onClick={() => onAccount(account)}\n role=\"button\"\n aria-label={t`Sign in as ${account.name}`}\n icon={<AccountImage src={account.picture} alt={name} />}\n append={<CaretRightIcon aria-hidden className=\"h-4\" />}\n >\n <span className=\"flex flex-wrap items-center\">\n <span className=\"mr-2 truncate font-medium\" arial-label={t`Name`}>\n {name}\n </span>\n {identifier && (\n <span\n className=\"truncate text-sm text-neutral-500 dark:text-neutral-400\"\n arial-label={t`Identifier`}\n >\n {identifier}\n </span>\n )}\n </span>\n </InputContainer>\n )\n })}\n\n {onOther && (\n <InputContainer\n key=\"other\"\n tabIndex={0}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') onOther()\n }}\n onClick={onOther}\n aria-label={t`Login to account that is not listed`}\n role=\"button\"\n append={<CaretRightIcon aria-hidden className=\"h-4\" />}\n icon={<AtSymbolIcon aria-hidden className=\"h-4\" />}\n >\n <span className=\"truncate text-slate-700 dark:text-slate-400\">\n <Trans>Another account</Trans>\n </span>\n </InputContainer>\n )}\n </FormCard>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { Session } from '@atproto/oauth-provider-api'\nimport {\n LayoutTitlePage,\n LayoutTitlePageProps,\n} from '../../../components/layouts/layout-title-page.tsx'\nimport { Override } from '../../../lib/util.ts'\nimport { SignInForm, SignInFormOutput } from './sign-in-form.tsx'\nimport { SignInPicker } from './sign-in-picker.tsx'\n\nexport type SignInViewProps = Override<\n LayoutTitlePageProps,\n {\n sessions: readonly Session[]\n selectSub: (sub: string | null) => void\n loginHint?: string\n\n onSignIn: (\n credentials: SignInFormOutput,\n signal: AbortSignal,\n ) => void | PromiseLike<void>\n onForgotPassword?: (emailHint?: string) => void\n onBack?: () => void\n }\n>\n\nexport function SignInView({\n loginHint,\n sessions,\n selectSub,\n\n onSignIn,\n onForgotPassword,\n onBack,\n\n // LayoutTitlePage\n title,\n subtitle,\n ...props\n}: SignInViewProps) {\n const { t } = useLingui()\n const session = useMemo(() => sessions.find((s) => s.selected), [sessions])\n const clearSession = useCallback(() => selectSub(null), [selectSub])\n const accounts = useMemo(() => sessions.map((s) => s.account), [sessions])\n const [showSignInForm, setShowSignInForm] = useState(sessions.length === 0)\n\n title ??= t`Sign in`\n\n useEffect(() => {\n // Make sure the \"back\" action shows the account picker instead of the\n // sign-in form (since the account was added to the list of current\n // sessions).\n if (session) setShowSignInForm(false)\n }, [session])\n\n if (session) {\n // All set (parent view will handle the redirect)\n if (!session.loginRequired) return null\n\n return (\n <LayoutTitlePage\n {...props}\n title={title}\n subtitle={subtitle ?? <Trans>Confirm your password to continue</Trans>}\n >\n <SignInForm\n onSubmit={onSignIn}\n onForgotPassword={onForgotPassword}\n onBack={clearSession}\n usernameDefault={\n session.account.preferred_username || session.account.sub\n }\n usernameReadonly={true}\n rememberDefault={true}\n />\n </LayoutTitlePage>\n )\n }\n\n if (loginHint) {\n return (\n <LayoutTitlePage\n {...props}\n title={title}\n subtitle={subtitle ?? <Trans>Enter your password</Trans>}\n >\n <SignInForm\n onSubmit={onSignIn}\n onForgotPassword={onForgotPassword}\n onBack={onBack}\n usernameDefault={loginHint}\n usernameReadonly={true}\n />\n </LayoutTitlePage>\n )\n }\n\n if (sessions.length === 0) {\n return (\n <LayoutTitlePage\n {...props}\n title={title}\n subtitle={subtitle ?? <Trans>Enter your username and password</Trans>}\n >\n <SignInForm\n onSubmit={onSignIn}\n onForgotPassword={onForgotPassword}\n onBack={onBack}\n />\n </LayoutTitlePage>\n )\n }\n\n if (showSignInForm) {\n return (\n <LayoutTitlePage\n {...props}\n title={title}\n subtitle={subtitle ?? <Trans>Enter your username and password</Trans>}\n >\n <SignInForm\n onSubmit={onSignIn}\n onForgotPassword={onForgotPassword}\n onBack={() => setShowSignInForm(false)}\n />\n </LayoutTitlePage>\n )\n }\n\n return (\n <LayoutTitlePage\n {...props}\n title={title}\n subtitle={subtitle ?? <Trans>Select from an existing account</Trans>}\n >\n <SignInPicker\n accounts={accounts}\n onAccount={(a) => selectSub(a.sub)}\n onOther={() => setShowSignInForm(true)}\n onBack={onBack}\n />\n </LayoutTitlePage>\n )\n}\n","import { useCallback, useEffect, useState } from 'react'\n\nexport type DisabledStep = false | null | undefined\nexport type Step = {\n invalid: boolean\n}\n\nconst isEnabled = <S extends Step | DisabledStep>(\n s: S,\n): s is S extends DisabledStep ? never : S => s != null && s !== false\nconst isRequired = <S extends Step | DisabledStep>(\n s: S,\n): s is S extends DisabledStep ? never : S & { invalid: true } =>\n isEnabled(s) && s.invalid === true\nconst isCompleted = <S extends Step | DisabledStep>(\n s: S,\n): s is S extends DisabledStep ? S : S & { invalid: false } =>\n !isEnabled(s) || s.invalid === false\n\nexport function useStepper<const S extends Step>(\n steps: readonly (S | DisabledStep)[],\n) {\n const firstIdx = steps.findIndex(isEnabled)\n const lastIdx = steps.findLastIndex(isEnabled)\n const requiredIdx = steps.findIndex(isRequired)\n\n const [currentIdx, setCurrentIdx] = useState<number>(firstIdx)\n\n const to = useCallback(\n (idx: number) => {\n if (idx !== -1 && steps[idx]) {\n setCurrentIdx(idx)\n return true\n } else {\n return false\n }\n },\n [steps.map(isEnabled).join()],\n )\n\n const prevIdx = steps.findLastIndex((s, i) => isEnabled(s) && i < currentIdx)\n const nextIdx = steps.findIndex((s, i) => isEnabled(s) && i > currentIdx)\n\n const toFirst = useCallback(() => to(firstIdx), [to, firstIdx])\n const toLast = useCallback(() => to(lastIdx), [to, lastIdx])\n const toPrev = useCallback(() => to(prevIdx), [to, prevIdx])\n const toNext = useCallback(() => to(nextIdx), [to, nextIdx])\n const toRequired = useCallback(() => to(requiredIdx), [to, requiredIdx])\n\n // Step number in user friendly terms (accounting for disabled steps)\n const currentPosition =\n currentIdx +\n // use \"1 indexed position\" (for user friendliness):\n 1 +\n // Adjust the position by counting the number of disabled steps before the\n // current step (if any):\n steps.reduce(\n (acc, s, i) => (i >= currentIdx || isEnabled(s) ? acc : acc - 1),\n 0,\n )\n\n const count = steps.filter(isEnabled).length\n const completed = steps.every(isCompleted)\n\n const current =\n currentIdx === -1 || !steps[currentIdx] ? undefined : steps[currentIdx]\n\n // Fool-proof (reset current step in case the current step becomes disabled)\n const broken = currentIdx === -1\n useEffect(() => {\n if (broken) toFirst()\n }, [broken])\n\n return {\n current,\n currentPosition,\n count,\n completed,\n atFirst: currentPosition === 1,\n atLast: currentPosition === count,\n toFirst,\n toLast,\n toPrev,\n toNext,\n toRequired,\n }\n}\n","import { Trans } from '@lingui/react/macro'\nimport { clsx } from 'clsx'\nimport { JSX, ReactNode, useCallback } from 'react'\nimport { DisabledStep, Step, useStepper } from '../../hooks/use-stepper.ts'\nimport { Override } from '../../lib/util.ts'\n\nexport type DoneFn = (...a: any) => unknown\n\nexport type WizardRenderProps<TDone extends DoneFn> = {\n /**\n * Indicates wether the render function being invoked corresponds to the step\n * currently active. The steps titles could, for example, be rendered in a\n * list of links, where the current step is highlighted (based on `current`).\n *\n * Another use for this is to render the next/previous steps in order to\n * provide animated transitions between steps. In this case, `current` would\n * be used to disable any form interaction with the form transitioning in/out.\n */\n current: boolean\n invalid: boolean\n\n prev?: () => void\n prevLabel: ReactNode\n\n // On the last step, the \"next()\" function will actually be the done function\n next: (() => void) | TDone\n nextLabel: ReactNode\n}\n\nexport type WizardRenderFn<TDone extends DoneFn> = (\n data: WizardRenderProps<TDone>,\n) => ReactNode\n\nexport type WizardStep<TDone extends DoneFn> = Step & {\n titleRender?: WizardRenderFn<TDone>\n contentRender: WizardRenderFn<TDone>\n}\n\nexport type WizardCardProps<TDone extends DoneFn> = Override<\n Omit<JSX.IntrinsicElements['div'], 'children'>,\n {\n prevLabel?: ReactNode\n nextLabel?: ReactNode\n\n onBack?: () => void\n backLabel?: ReactNode\n\n onDone: TDone\n doneLabel?: ReactNode\n\n steps: readonly (WizardStep<TDone> | DisabledStep)[]\n }\n>\n\nexport function WizardCard<TDone extends DoneFn>({\n prevLabel,\n nextLabel,\n\n onBack,\n backLabel,\n\n onDone,\n doneLabel,\n\n steps,\n className,\n\n ...props\n}: WizardCardProps<TDone>) {\n const {\n atFirst,\n atLast,\n count,\n current,\n currentPosition,\n completed,\n toNext,\n toPrev,\n toRequired,\n } = useStepper(steps)\n\n // Memoized to avoid re-renders in child (rendered) components\n const onNext = useCallback(() => {\n // If already at last step, go to the first incomplete (required) step\n if (!toNext()) toRequired()\n }, [toNext, toRequired])\n\n const data: WizardRenderProps<TDone> = {\n // The current UI only displays the current title & content.\n current: true,\n invalid: current ? current.invalid : false,\n\n prevLabel: (atFirst && backLabel) || prevLabel || <Trans>Back</Trans>,\n prev: atFirst ? onBack : toPrev,\n\n nextLabel: (atLast && doneLabel) || nextLabel || <Trans>Next</Trans>,\n next: atLast && completed ? onDone : onNext,\n }\n\n const stepTitle = current?.titleRender?.(data)\n const stepContent = current?.contentRender?.(data)\n\n return (\n <div className={clsx(className, 'flex flex-col')} {...props}>\n <p className=\"text-slate-500 dark:text-slate-400\">\n <Trans>\n Step {currentPosition} of {count}\n </Trans>\n </p>\n\n {stepTitle && <h2 className=\"mb-4 text-xl font-medium\">{stepTitle}</h2>}\n\n {stepContent}\n </div>\n )\n}\n","import { Trans } from '@lingui/react/macro'\nimport { clsx } from 'clsx'\nimport { JSX } from 'react'\nimport type { LinkDefinition } from '@atproto/oauth-provider-api'\nimport { Override } from '../../lib/util.ts'\n\nexport type HelpCardProps = Override<\n Omit<JSX.IntrinsicElements['p'], 'children'>,\n {\n links?: readonly LinkDefinition[]\n }\n>\n\nexport function HelpCard({\n links,\n\n className,\n ...props\n}: HelpCardProps) {\n const helpLink = links?.find((l) => l.rel === 'help')\n\n if (!helpLink) return null\n\n return (\n <p\n {...props}\n className={clsx(\n 'rounded-md bg-slate-100 p-3 text-sm text-slate-800 dark:bg-slate-800 dark:text-slate-400',\n className,\n )}\n >\n <Trans>\n Having trouble?{' '}\n <a\n role=\"link\"\n href={helpLink.href}\n rel={helpLink.rel}\n target=\"_blank\"\n className=\"text-primary\"\n >\n <Trans>Contact support</Trans>\n </a>\n </Trans>\n </p>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { ReactNode, useEffect, useMemo, useRef, useState } from 'react'\nimport { Fieldset } from '../../../components/forms/fieldset.tsx'\nimport {\n AsyncActionController,\n FormCardAsync,\n FormCardAsyncProps,\n} from '../../../components/forms/form-card-async.tsx'\nimport { InputEmailAddress } from '../../../components/forms/input-email-address.tsx'\nimport { InputNewPassword } from '../../../components/forms/input-new-password.tsx'\nimport { InputText } from '../../../components/forms/input-text.tsx'\nimport { TokenIcon } from '../../../components/utils/icons.tsx'\nimport { mergeRefs } from '../../../lib/ref.ts'\nimport { Override } from '../../../lib/util.ts'\n\nexport type SignUpAccountFormOutput = {\n email: string\n password: string\n inviteCode?: string\n}\n\nexport type SignUpAccountFormProps = Override<\n Omit<\n FormCardAsyncProps,\n 'append' | 'onCancel' | 'onSubmit' | 'submitLabel' | 'cancelLabel'\n >,\n {\n inviteCodeRequired?: boolean\n\n credentials?: SignUpAccountFormOutput\n onCredentials?: (credentials?: SignUpAccountFormOutput) => void\n\n onNext: (signal: AbortSignal) => void | PromiseLike<void>\n nextLabel?: ReactNode\n\n onPrev?: () => void\n prevLabel?: ReactNode\n }\n>\n\nexport function SignUpAccountForm({\n inviteCodeRequired = true,\n\n credentials: creds,\n onCredentials,\n\n onNext,\n nextLabel,\n\n onPrev,\n prevLabel,\n\n // FormCardAsyncProps\n children,\n ref,\n invalid,\n ...props\n}: SignUpAccountFormProps) {\n const { t } = useLingui()\n\n const [email, setEmail] = useState(creds?.email)\n const [password, setPassword] = useState(creds?.password)\n const [inviteCode, setInviteCode] = useState(creds?.inviteCode)\n\n const formRef = useRef<AsyncActionController>(null)\n const resetForm = () => formRef.current?.reset()\n\n const credentials = useMemo(\n () =>\n email && password && (!inviteCodeRequired || inviteCode)\n ? {\n email,\n password,\n inviteCode: inviteCodeRequired ? inviteCode : undefined,\n }\n : undefined,\n [email, password, inviteCode, inviteCodeRequired],\n )\n\n useEffect(() => {\n onCredentials?.(credentials)\n }, [credentials, onCredentials])\n\n return (\n <FormCardAsync\n {...props}\n ref={mergeRefs([ref, formRef])}\n invalid={invalid || !credentials}\n onCancel={onPrev}\n cancelLabel={prevLabel}\n onSubmit={onNext}\n submitLabel={nextLabel}\n append={children}\n >\n {inviteCodeRequired && (\n <Fieldset label={<Trans>Invite code</Trans>}>\n <InputText\n icon={<TokenIcon className=\"w-5\" />}\n autoFocus\n name=\"inviteCode\"\n title={t`Invite code`}\n placeholder={t`example-com-xxxxx-xxxxx`}\n required\n value={inviteCode || ''}\n onChange={(event) => {\n setInviteCode(event.target.value || undefined)\n resetForm()\n }}\n enterKeyHint=\"next\"\n />\n </Fieldset>\n )}\n\n <Fieldset label={<Trans>Email</Trans>}>\n <InputEmailAddress\n autoFocus={!inviteCodeRequired}\n name=\"email\"\n enterKeyHint=\"next\"\n required\n defaultValue={email}\n onEmail={(email) => {\n setEmail(email)\n resetForm()\n }}\n />\n </Fieldset>\n\n <Fieldset label={<Trans>Password</Trans>}>\n <InputNewPassword\n name=\"password\"\n enterKeyHint=\"next\"\n required\n password={password}\n onPassword={(value) => {\n setPassword(value)\n resetForm()\n }}\n />\n </Fieldset>\n </FormCardAsync>\n )\n}\n","import { Trans } from '@lingui/react/macro'\nimport { clsx } from 'clsx'\nimport { JSX } from 'react'\nimport type { LinkDefinition } from '@atproto/oauth-provider-api'\nimport { LinkAnchor } from '../../../components/utils/link-anchor.tsx'\nimport { Override } from '../../../lib/util.ts'\n\nexport type SignUpDisclaimerProps = Override<\n Omit<JSX.IntrinsicElements['p'], 'children'>,\n {\n links?: readonly LinkDefinition[]\n }\n>\n\nexport function SignUpDisclaimer({\n links,\n\n // p\n className,\n ...attrs\n}: SignUpDisclaimerProps) {\n const tosLink = links?.find((l) => l.rel === 'terms-of-service')\n const ppLink = links?.find((l) => l.rel === 'privacy-policy')\n\n return (\n <p\n className={clsx('text-sm text-slate-500 dark:text-slate-400', className)}\n {...attrs}\n >\n <Trans>\n By creating an account you agree to the{' '}\n {tosLink ? (\n <LinkAnchor className=\"text-primary underline\" link={tosLink}>\n <Trans>Terms of Service</Trans>\n </LinkAnchor>\n ) : (\n <Trans>Terms of Service</Trans>\n )}\n {' and the '}\n {ppLink ? (\n <LinkAnchor className=\"text-primary underline\" link={ppLink}>\n <Trans>Privacy Policy</Trans>\n </LinkAnchor>\n ) : (\n <Trans>Privacy Policy</Trans>\n )}{' '}\n of this service.\n </Trans>\n </p>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { clsx } from 'clsx'\nimport { JSX, ReactNode, useCallback, useEffect, useRef, useState } from 'react'\nimport {\n AsyncActionController,\n FormCardAsync,\n FormCardAsyncProps,\n} from '../../../components/forms/form-card-async.tsx'\nimport { InputText } from '../../../components/forms/input-text.tsx'\nimport { Admonition } from '../../../components/utils/admonition.tsx'\nimport {\n AtSymbolIcon,\n CheckMarkIcon,\n XMarkIcon,\n} from '../../../components/utils/icons.tsx'\nimport { mergeRefs } from '../../../lib/ref.ts'\nimport { Override } from '../../../lib/util.ts'\n\n/**\n * Spec limit is 63, but in practice, we've limited it to 18 in our implementations.\n *\n * @see {@link https://atproto.com/specs/handle | ATProto Handle Spec}\n */\nconst MAX_LENGTH = 18\n\n/**\n * Spec limit is 1, but in practice, we've targeted at least 3 characters in handles.\n *\n * @see {@link https://atproto.com/specs/handle | ATProto Handle Spec}\n */\nconst MIN_LENGTH = 3\n\n/**\n * Spec limit is 253, but in practice, we've targeted 30 characters in handles.\n *\n * @see {@link https://atproto.com/specs/handle | ATProto Handle Spec}\n */\nconst MAX_FULL_LENGTH = 30\n\ntype ValidDomain = `.${string}`\nconst isValidDomain = (domain: string): domain is ValidDomain =>\n // Ignore domains that are so long that they would make the handle smaller\n // than MIN_LENGTH characters\n MIN_LENGTH + domain.length <= MAX_FULL_LENGTH &&\n // Basic validation here\n domain.startsWith('.') &&\n !domain.endsWith('.')\n\nfunction useSegmentValidator(domain: ValidDomain) {\n const minLen = MIN_LENGTH\n const maxLen = Math.min(MAX_LENGTH, MAX_FULL_LENGTH - domain.length)\n\n const validateSegment = useCallback(\n (segment: string) => {\n const validLength = segment.length >= minLen && segment.length <= maxLen\n const validCharset = /^[a-z0-9][a-z0-9-]+[a-z0-9]$/g.test(segment)\n\n return { validLength, validCharset, valid: validLength && validCharset }\n },\n [maxLen, minLen],\n )\n\n return {\n minLength: minLen,\n maxLength: maxLen,\n validateSegment,\n }\n}\n\nexport type SignUpHandleFormProps = Override<\n Omit<\n FormCardAsyncProps,\n 'append' | 'onCancel' | 'cancelLabel' | 'onSubmit' | 'submitLabel'\n >,\n {\n domains: string[]\n\n onNext: (signal: AbortSignal) => void | PromiseLike<void>\n nextLabel?: ReactNode\n\n onPrev?: () => void\n prevLabel?: ReactNode\n\n handle?: string\n onHandle?: (handle: string | undefined) => void\n }\n>\n\nexport function SignUpHandleForm({\n domains: availableDomains,\n\n onNext,\n nextLabel,\n\n onPrev,\n prevLabel,\n\n handle: handleInit,\n onHandle,\n\n // FormCardProps\n invalid,\n children,\n ref,\n ...props\n}: SignUpHandleFormProps) {\n const { t } = useLingui()\n const domains = availableDomains.filter(isValidDomain)\n\n const formRef = useRef<AsyncActionController>(null)\n\n const [domainIdx, setDomainIdx] = useState(() => {\n const idx = domains.findIndex((d) => handleInit?.endsWith(d))\n return idx === -1 ? 0 : idx\n })\n const [segment, setSegment] = useState(() => handleInit?.split('.')[0] || '')\n\n // Automatically update the domain index when the list length changes\n useEffect(() => {\n setDomainIdx((v) => Math.min(v, domains.length - 1))\n }, [domains.length])\n\n const domain: ValidDomain | null = domains[domainIdx] || domains[0] || null\n\n const { minLength, maxLength, validateSegment } = useSegmentValidator(domain)\n\n const validity = validateSegment(segment)\n const handle = domain && validity.valid ? `${segment}${domain}` : undefined\n useEffect(() => {\n // Whenever the user changes the handle, abort any pending form action\n formRef.current?.reset()\n onHandle?.(handle)\n }, [onHandle, handle])\n\n const inputRef = useRef<HTMLInputElement>(null)\n\n const preview = `@${segment}${domain}`\n\n return (\n <FormCardAsync\n {...props}\n ref={mergeRefs([ref, formRef])}\n onCancel={onPrev}\n cancelLabel={prevLabel}\n onSubmit={onNext}\n submitLabel={nextLabel}\n invalid={invalid || !handle}\n append={children}\n >\n <div>\n <ValidationMessage hasValue={!!segment} valid={validity.validLength}>\n <Trans>\n Between {minLength} and {maxLength} characters\n </Trans>\n </ValidationMessage>\n <ValidationMessage hasValue={!!segment} valid={validity.validCharset}>\n <Trans>Only letters, numbers, and hyphens</Trans>\n </ValidationMessage>\n </div>\n\n <InputText\n ref={inputRef}\n icon={<AtSymbolIcon className=\"w-5\" />}\n name=\"handle\"\n type=\"text\"\n title={t`Type your desired username`}\n pattern=\"[a-z0-9][a-z0-9\\-]+[a-z0-9]\"\n minLength={minLength}\n maxLength={maxLength}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n autoComplete=\"off\"\n dir=\"auto\"\n enterKeyHint=\"done\"\n autoFocus\n required\n value={segment}\n onChange={(event) => {\n const segment = event.target.value.toLowerCase()\n\n // Ensure the input is always lowercase\n const selectionStart = event.target.selectionStart\n const selectionEnd = event.target.selectionEnd\n event.target.value = segment\n event.target.setSelectionRange(selectionStart, selectionEnd)\n\n setSegment(segment)\n }}\n append={\n // @TODO refactor this to a separate component\n domains.length > 1 && (\n <select\n onClick={(event) => event.stopPropagation()}\n onMouseDown={(event) => event.stopPropagation()}\n value={domainIdx}\n aria-label={t`Select domain`}\n onChange={(event) => {\n setDomainIdx(Number(event.target.value))\n inputRef.current?.focus()\n }}\n className={clsx(\n 'block w-full',\n 'text-sm',\n 'rounded-lg p-2',\n 'bg-white dark:bg-slate-600',\n )}\n >\n {domains.map((domain, idx) => (\n <option key={domain} value={idx}>\n {domain}\n </option>\n ))}\n </select>\n )\n }\n bellow={\n <Trans>\n Your full username will be:{' '}\n {segment.length ? (\n <strong className=\"text-gray-800 dark:text-gray-200\">\n {preview}\n </strong>\n ) : (\n <span\n aria-hidden\n className=\"w-24 rounded-md bg-gray-300 p-2 dark:bg-slate-600\"\n />\n )}\n </Trans>\n }\n />\n\n <Admonition role=\"status\">\n <p className=\"text-md\">\n <Trans>\n You can change this username to any domain name you control after\n your account is set up.\n </Trans>\n </p>\n </Admonition>\n </FormCardAsync>\n )\n}\n\ntype ValidationMessageProps = JSX.IntrinsicElements['div'] & {\n valid: boolean\n hasValue: boolean\n}\n\nfunction ValidationMessage({\n valid,\n hasValue,\n\n // div\n children,\n className,\n ...props\n}: ValidationMessageProps) {\n const { t } = useLingui()\n return (\n <div\n {...props}\n className={clsx('flex flex-row items-center gap-2', className)}\n >\n {hasValue ? (\n <>\n {valid ? (\n <CheckMarkIcon\n className=\"text-success inline-block h-4 w-4\"\n title={t`Valid`}\n />\n ) : (\n <XMarkIcon\n className=\"text-error inline-block h-4 w-4\"\n title={t`Invalid`}\n />\n )}\n </>\n ) : (\n <div aria-hidden className=\"flex h-4 w-4 items-center justify-center\">\n <div className=\"h-2 w-2 rounded-full bg-gray-300 dark:bg-slate-600\" />\n </div>\n )}\n <div className=\"text-sm\">{children}</div>\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\n\nconst query =\n typeof window === 'undefined'\n ? null\n : window.matchMedia('(prefers-color-scheme: dark)')\n\nexport function useBrowserColorScheme() {\n const [theme, setTheme] = useState<'light' | 'dark'>(\n query?.matches ? 'dark' : 'light',\n )\n\n useEffect(() => {\n if (!query) return\n\n const listener = () => {\n setTheme(query.matches ? 'dark' : 'light')\n }\n\n query.addEventListener('change', listener)\n\n return () => {\n query.removeEventListener('change', listener)\n }\n\n // @NOTE \"query\" is a global constant and does not need to be part of the\n // array bellow:\n }, [])\n\n return theme\n}\n","import type HCaptcha from '@hcaptcha/react-hcaptcha'\nimport {\n ForwardedRef,\n ReactNode,\n lazy,\n useCallback,\n useRef,\n useState,\n} from 'react'\nimport {\n FormCardAsync,\n FormCardAsyncProps,\n} from '../../../components/forms/form-card-async.tsx'\nimport { useBrowserColorScheme } from '../../../hooks/use-browser-color-scheme.ts'\nimport { mergeRefs } from '../../../lib/ref.ts'\nimport { Override } from '../../../lib/util.ts'\n\nexport type SignUpHcaptchaFormProps = Override<\n Omit<\n FormCardAsyncProps,\n 'append' | 'onSubmit' | 'submitLabel' | 'onCancel' | 'cancelLabel'\n >,\n {\n siteKey: string\n\n token?: string\n onToken: (token: string, ekey: string) => void\n\n prevLabel?: ReactNode\n onPrev?: () => void\n\n nextLabel?: ReactNode\n onNext: (signal: AbortSignal) => void | PromiseLike<void>\n\n ref?: ForwardedRef<HCaptcha>\n }\n>\n\nconst HCaptchaLazy = lazy(() => import('@hcaptcha/react-hcaptcha'))\n\nexport function SignUpHcaptchaForm({\n siteKey,\n\n token: tokenInit,\n onToken,\n\n prevLabel,\n onPrev,\n\n nextLabel,\n onNext,\n\n ref,\n\n // FormCardProps\n invalid,\n children,\n ...props\n}: SignUpHcaptchaFormProps) {\n const captchaRef = useRef<HCaptcha>(null)\n const theme = useBrowserColorScheme()\n const [token, setToken] = useState<string | undefined>(tokenInit)\n\n const onLoad = useCallback(() => {\n // this reaches out to the hCaptcha JS API and runs the\n // execute function on it. you can use other functions as\n // documented here:\n // https://docs.hcaptcha.com/configuration#jsapi\n captchaRef.current?.execute()\n }, [])\n\n const onVerify = useCallback(\n (token: string, ekey: string) => {\n setToken(token)\n onToken(token, ekey)\n },\n [onToken],\n )\n\n const doSubmit = useCallback(\n (signal: AbortSignal) => {\n if (token) return onNext(signal)\n else if (captchaRef.current) captchaRef.current.execute()\n else throw new Error('Unable to load hCaptcha')\n },\n [token, onNext],\n )\n\n return (\n <FormCardAsync\n {...props}\n cancelLabel={prevLabel}\n onCancel={onPrev}\n submitLabel={nextLabel}\n onSubmit={doSubmit}\n append={children}\n invalid={invalid || !token}\n >\n <HCaptchaLazy\n theme={theme}\n sitekey={siteKey}\n onLoad={onLoad}\n onVerify={onVerify}\n ref={mergeRefs([ref, captchaRef])}\n />\n </FormCardAsync>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { useCallback, useState } from 'react'\nimport type { CustomizationData } from '@atproto/oauth-provider-api'\nimport { WizardCard } from '../../../components/forms/wizard-card.tsx'\nimport {\n LayoutTitlePage,\n LayoutTitlePageProps,\n} from '../../../components/layouts/layout-title-page.tsx'\nimport { HelpCard } from '../../../components/utils/help-card.tsx'\nimport { Override } from '../../../lib/util.ts'\nimport {\n SignUpAccountForm,\n SignUpAccountFormOutput,\n} from './sign-up-account-form.tsx'\nimport { SignUpDisclaimer } from './sign-up-disclaimer.tsx'\nimport { SignUpHandleForm } from './sign-up-handle-form.tsx'\nimport { SignUpHcaptchaForm } from './sign-up-hcaptcha-form.tsx'\n\nexport type SignUpViewProps = Override<\n LayoutTitlePageProps,\n {\n customizationData?: CustomizationData\n\n onBack?: () => void\n onValidateNewHandle: (\n data: { handle: string },\n signal?: AbortSignal,\n ) => void | PromiseLike<void>\n onDone: (\n data: SignUpAccountFormOutput & {\n handle: string\n hcaptchaToken?: string\n },\n signal?: AbortSignal,\n ) => void | PromiseLike<void>\n }\n>\n\nexport function SignUpView({\n customizationData: {\n availableUserDomains = [],\n hcaptchaSiteKey = undefined,\n inviteCodeRequired = true,\n links,\n } = {},\n\n onValidateNewHandle,\n onDone,\n onBack,\n\n // LayoutTitlePage\n ...props\n}: SignUpViewProps) {\n const { t } = useLingui()\n const [credentials, setCredentials] = useState<\n undefined | SignUpAccountFormOutput\n >(undefined)\n const [handle, setHandle] = useState<undefined | string>(undefined)\n const [hcaptcha, setHcaptcha] = useState<undefined | string>(undefined)\n\n /**\n * \"false\" indicates that the hcaptcha token is invalid (required but not provided)\n */\n const hcaptchaToken = hcaptchaSiteKey == null ? undefined : hcaptcha || false\n\n const doDone = useCallback(\n (signal: AbortSignal) => {\n if (credentials && handle && hcaptchaToken !== false) {\n return onDone({ ...credentials, handle, hcaptchaToken }, signal)\n }\n },\n [credentials, handle, hcaptchaToken, onDone],\n )\n\n return (\n <LayoutTitlePage\n {...props}\n title={props.title ?? t`Create Account`}\n subtitle={\n props.subtitle ?? <Trans>We're so excited to have you join us!</Trans>\n }\n >\n <WizardCard\n doneLabel={<Trans>Sign up</Trans>}\n onBack={onBack}\n onDone={doDone}\n steps={[\n // We use the handle input first since the \"onValidateNewHandle\" check\n // will make it less likely that the actual signup call will fail, and\n // will result in a better user experience, especially if there is an\n // issue with the email address (e.g. already in use).\n {\n invalid: !handle,\n titleRender: () => <Trans>Choose a username</Trans>,\n contentRender: ({ prev, prevLabel, next, nextLabel, invalid }) => (\n <SignUpHandleForm\n className=\"grow\"\n invalid={invalid}\n domains={availableUserDomains}\n handle={handle}\n onHandle={setHandle}\n prevLabel={prevLabel}\n onPrev={prev}\n nextLabel={nextLabel}\n onNext={async (signal) => {\n if (handle) await onValidateNewHandle({ handle }, signal)\n if (!signal.aborted) return next(signal)\n }}\n >\n <SignUpDisclaimer links={links} />\n </SignUpHandleForm>\n ),\n },\n {\n invalid: !credentials,\n titleRender: () => <Trans>Your account</Trans>,\n contentRender: ({ prev, prevLabel, next, nextLabel, invalid }) => (\n <SignUpAccountForm\n className=\"grow\"\n invalid={invalid}\n prevLabel={prevLabel}\n onPrev={prev}\n nextLabel={nextLabel}\n onNext={next}\n inviteCodeRequired={inviteCodeRequired}\n credentials={credentials}\n onCredentials={setCredentials}\n >\n <SignUpDisclaimer links={links} />\n </SignUpAccountForm>\n ),\n },\n hcaptchaSiteKey != null && {\n invalid: hcaptchaToken === false,\n titleRender: () => <Trans>Verify you are human</Trans>,\n contentRender: ({ prev, prevLabel, next, nextLabel, invalid }) => (\n <SignUpHcaptchaForm\n className=\"grow\"\n invalid={invalid}\n siteKey={hcaptchaSiteKey}\n token={hcaptcha}\n onToken={setHcaptcha}\n prevLabel={prevLabel}\n onPrev={prev}\n nextLabel={nextLabel}\n onNext={next}\n >\n <SignUpDisclaimer links={links} />\n </SignUpHcaptchaForm>\n ),\n },\n ]}\n />\n\n <HelpCard className=\"mt-4\" links={links} />\n </LayoutTitlePage>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { Button } from '../../../components/forms/button.tsx'\nimport {\n LayoutWelcome,\n LayoutWelcomeProps,\n} from '../../../components/layouts/layout-welcome.tsx'\nimport { Override } from '../../../lib/util.ts'\n\nexport type WelcomeViewParams = Override<\n LayoutWelcomeProps,\n {\n onSignIn?: () => void\n onSignUp?: () => void\n onCancel?: () => void\n }\n>\n\nexport function WelcomeView({\n onSignUp,\n onSignIn,\n onCancel,\n\n // LayoutWelcome\n ...props\n}: WelcomeViewParams) {\n const { t } = useLingui()\n return (\n <LayoutWelcome {...props} title={props.title ?? t`Authenticate`}>\n {onSignUp && (\n <Button\n className={'m-1 w-60 min-w-min max-w-full'}\n color={onSignIn ? 'primary' : undefined}\n onClick={onSignUp}\n >\n <Trans>Create a new account</Trans>\n </Button>\n )}\n\n {onSignIn && (\n <Button\n className={'m-1 w-60 min-w-min max-w-full'}\n color={onSignUp ? undefined : 'primary'}\n onClick={onSignIn}\n >\n <Trans>Sign in</Trans>\n </Button>\n )}\n\n {onCancel && (\n <Button className=\"m-1 w-60 min-w-min max-w-full\" onClick={onCancel}>\n <Trans>Cancel</Trans>\n </Button>\n )}\n </LayoutWelcome>\n )\n}\n","import { Trans, useLingui } from '@lingui/react/macro'\nimport { useEffect, useState } from 'react'\nimport type { CustomizationData, Session } from '@atproto/oauth-provider-api'\nimport {\n LayoutTitlePage,\n LayoutTitlePageProps,\n} from '../../components/layouts/layout-title-page.tsx'\nimport { useApi } from '../../hooks/use-api.ts'\nimport { useBoundDispatch } from '../../hooks/use-bound-dispatch.ts'\nimport type { AuthorizeData } from '../../hydration-data'\nimport { Override } from '../../lib/util.ts'\nimport { AcceptView } from './accept/accept-view.tsx'\nimport { ResetPasswordView } from './reset-password/reset-password-view.tsx'\nimport { SignInView } from './sign-in/sign-in-view.tsx'\nimport { SignUpView } from './sign-up/sign-up-view.tsx'\nimport { WelcomeView } from './welcome/welcome-view.tsx'\n\nexport type AuthorizeViewProps = Override<\n LayoutTitlePageProps,\n {\n customizationData?: CustomizationData\n authorizeData: AuthorizeData\n sessions: readonly Session[]\n }\n>\n\nenum View {\n Welcome,\n SignUp,\n SignIn,\n ResetPassword,\n Accept,\n Done,\n}\n\nexport function AuthorizeView({\n authorizeData,\n sessions: initialSessions,\n customizationData,\n\n // LayoutTitlePage\n ...props\n}: AuthorizeViewProps) {\n const { t } = useLingui()\n\n const forceSignIn = authorizeData?.loginHint != null\n\n const initialView = forceSignIn ? View.SignIn : View.Welcome\n const [view, setView] = useState<View>(initialView)\n\n const showDone = useBoundDispatch(setView, View.Done)\n const showSignIn = useBoundDispatch(setView, View.SignIn)\n const showResetPassword = useBoundDispatch(setView, View.ResetPassword)\n const showSignUp = useBoundDispatch(setView, View.SignUp)\n const showAccept = useBoundDispatch(setView, View.Accept)\n const showWelcome = useBoundDispatch(setView, View.Welcome)\n\n const [resetPasswordHint, setResetPasswordHint] = useState<\n string | undefined\n >(undefined)\n\n const {\n sessions,\n selectSub,\n doValidateNewHandle,\n doSignUp,\n doSignIn,\n doInitiatePasswordReset,\n doConfirmResetPassword,\n doAccept,\n doReject,\n } = useApi({\n sessions: initialSessions,\n onRedirected: showDone,\n })\n\n // Navigate when the user signs-in (selects a new session)\n const session = sessions.find((s) => s.selected && !s.loginRequired)\n useEffect(() => {\n if (session) {\n if (session.consentRequired) showAccept()\n else doAccept(session.account.sub)\n }\n }, [session, doAccept, showAccept])\n\n const canSignUp =\n Boolean(customizationData?.availableUserDomains?.length) &&\n !authorizeData.loginHint\n\n // Fool-proofing\n const resetNeeded =\n (view === View.SignUp && !canSignUp) || (view === View.Accept && !session)\n useEffect(() => {\n if (resetNeeded) showWelcome()\n }, [resetNeeded, showWelcome])\n\n if (view === View.Welcome) {\n return (\n <WelcomeView\n {...props}\n customizationData={customizationData}\n onSignIn={showSignIn}\n onSignUp={canSignUp ? showSignUp : undefined}\n onCancel={() => doReject()}\n />\n )\n }\n\n if (view === View.SignUp) {\n return (\n <SignUpView\n {...props}\n customizationData={customizationData}\n onValidateNewHandle={doValidateNewHandle}\n onBack={showWelcome}\n onDone={doSignUp}\n />\n )\n }\n\n if (view === View.ResetPassword) {\n return (\n <ResetPasswordView\n {...props}\n emailDefault={resetPasswordHint}\n onresetPasswordRequest={doInitiatePasswordReset}\n onResetPasswordConfirm={doConfirmResetPassword}\n onBack={forceSignIn ? showSignIn : showWelcome}\n />\n )\n }\n\n if (view === View.SignIn) {\n return (\n <SignInView\n {...props}\n loginHint={authorizeData.loginHint}\n sessions={sessions}\n selectSub={selectSub}\n onSignIn={doSignIn}\n onBack={forceSignIn ? () => doReject() : showWelcome}\n onForgotPassword={(email) => {\n showResetPassword()\n setResetPasswordHint(email)\n }}\n />\n )\n }\n\n if (view === View.Accept) {\n // TypeSafety: should never be null here\n if (!session) return null\n\n return (\n <AcceptView\n {...props}\n clientId={authorizeData.clientId}\n clientMetadata={authorizeData.clientMetadata}\n clientTrusted={authorizeData.clientTrusted}\n account={session.account}\n scopeDetails={authorizeData.scopeDetails}\n onAccept={() => doAccept(session.account.sub)}\n onReject={() => doReject()}\n onBack={\n forceSignIn\n ? undefined\n : () => {\n selectSub(null)\n setView(sessions.length ? View.SignIn : View.Welcome)\n }\n }\n />\n )\n }\n\n if (view === View.Done) {\n return (\n <LayoutTitlePage {...props} title={props.title ?? t`Login complete`}>\n <Trans>You are being redirected...</Trans>\n </LayoutTitlePage>\n )\n }\n\n // Fool-proofing\n throw new Error('Unexpected application state')\n}\n","import './style.css'\n\nimport { StrictMode } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport { ErrorBoundary } from 'react-error-boundary'\nimport type { HydrationData } from './hydration-data.d.ts'\nimport { LocaleProvider } from './locales/locale-provider.tsx'\nimport { AuthorizeView } from './views/authorize/authorize-view.tsx'\nimport { ErrorView } from './views/error/error-view.tsx'\n\nconst {\n __authorizeData: authorizeData,\n __sessions: sessions,\n __customizationData: customizationData,\n} = window as typeof window & HydrationData['authorization-page']\n\n// When the user is logging in, make sure the page URL contains the\n// \"request_uri\" in case the user refreshes the page.\n// @TODO Actually do this on the backend through a redirect.\nconst url = new URL(window.location.href)\nif (\n url.pathname === '/oauth/authorize' &&\n !url.searchParams.has('request_uri')\n) {\n url.search = ''\n url.searchParams.set('client_id', authorizeData.clientId)\n url.searchParams.set('request_uri', authorizeData.requestUri)\n window.history.replaceState(history.state, '', url.pathname + url.search)\n}\n\nconst container = document.getElementById('root')!\n\ncreateRoot(container).render(\n <StrictMode>\n <LocaleProvider userLocales={authorizeData.uiLocales?.split(' ')}>\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <ErrorView error={error} customizationData={customizationData} />\n )}\n >\n <AuthorizeView\n customizationData={customizationData}\n authorizeData={authorizeData}\n sessions={sessions}\n />\n </ErrorBoundary>\n </LocaleProvider>\n </StrictMode>,\n)\n"],"file":"authorization-page-Cms-rcBA.js"}
@@ -1,2 +0,0 @@
1
- import{n as o,j as r,r as t,o as e,p as a}from"./error-view-MVy7C9l0.js";const{__errorData:s,__customizationData:n}=window,i=document.getElementById("root");o.createRoot(i).render(r.jsx(t.StrictMode,{children:r.jsx(e,{children:r.jsx(a,{error:s,customizationData:n})})}));
2
- //# sourceMappingURL=error-page-DC6Vc-cv.js.map