@passflow/core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +1087 -0
  2. package/dist/index.js +2 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.mjs +2149 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/dist/lib/api/app.d.ts +8 -0
  7. package/dist/lib/api/app.d.ts.map +1 -0
  8. package/dist/lib/api/auth.d.ts +23 -0
  9. package/dist/lib/api/auth.d.ts.map +1 -0
  10. package/dist/lib/api/axios-client.d.ts +36 -0
  11. package/dist/lib/api/axios-client.d.ts.map +1 -0
  12. package/dist/lib/api/index.d.ts +8 -0
  13. package/dist/lib/api/index.d.ts.map +1 -0
  14. package/dist/lib/api/invitation.d.ts +77 -0
  15. package/dist/lib/api/invitation.d.ts.map +1 -0
  16. package/dist/lib/api/model.d.ts +459 -0
  17. package/dist/lib/api/model.d.ts.map +1 -0
  18. package/dist/lib/api/setting.d.ts +10 -0
  19. package/dist/lib/api/setting.d.ts.map +1 -0
  20. package/dist/lib/api/tenant.d.ts +213 -0
  21. package/dist/lib/api/tenant.d.ts.map +1 -0
  22. package/dist/lib/api/user.d.ts +19 -0
  23. package/dist/lib/api/user.d.ts.map +1 -0
  24. package/dist/lib/constants/index.d.ts +8 -0
  25. package/dist/lib/constants/index.d.ts.map +1 -0
  26. package/dist/lib/device-service/index.d.ts +7 -0
  27. package/dist/lib/device-service/index.d.ts.map +1 -0
  28. package/dist/lib/index.d.ts +8 -0
  29. package/dist/lib/index.d.ts.map +1 -0
  30. package/dist/lib/passflow.d.ts +115 -0
  31. package/dist/lib/passflow.d.ts.map +1 -0
  32. package/dist/lib/services/auth-service.d.ts +67 -0
  33. package/dist/lib/services/auth-service.d.ts.map +1 -0
  34. package/dist/lib/services/index.d.ts +7 -0
  35. package/dist/lib/services/index.d.ts.map +1 -0
  36. package/dist/lib/services/invitation-service.d.ts +44 -0
  37. package/dist/lib/services/invitation-service.d.ts.map +1 -0
  38. package/dist/lib/services/logger.d.ts +24 -0
  39. package/dist/lib/services/logger.d.ts.map +1 -0
  40. package/dist/lib/services/tenant-service.d.ts +200 -0
  41. package/dist/lib/services/tenant-service.d.ts.map +1 -0
  42. package/dist/lib/services/tenant-user-membership.d.ts +76 -0
  43. package/dist/lib/services/tenant-user-membership.d.ts.map +1 -0
  44. package/dist/lib/services/token-cache-service.d.ts +26 -0
  45. package/dist/lib/services/token-cache-service.d.ts.map +1 -0
  46. package/dist/lib/services/user-service.d.ts +39 -0
  47. package/dist/lib/services/user-service.d.ts.map +1 -0
  48. package/dist/lib/storage-manager/index.d.ts +37 -0
  49. package/dist/lib/storage-manager/index.d.ts.map +1 -0
  50. package/dist/lib/store.d.ts +89 -0
  51. package/dist/lib/store.d.ts.map +1 -0
  52. package/dist/lib/token-service/index.d.ts +4 -0
  53. package/dist/lib/token-service/index.d.ts.map +1 -0
  54. package/dist/lib/token-service/membership.d.ts +37 -0
  55. package/dist/lib/token-service/membership.d.ts.map +1 -0
  56. package/dist/lib/token-service/service.d.ts +35 -0
  57. package/dist/lib/token-service/service.d.ts.map +1 -0
  58. package/dist/lib/token-service/token.d.ts +34 -0
  59. package/dist/lib/token-service/token.d.ts.map +1 -0
  60. package/dist/lib/types/index.d.ts +22 -0
  61. package/dist/lib/types/index.d.ts.map +1 -0
  62. package/dist/tests/storage-manager/fake-storage.d.ts +7 -0
  63. package/dist/tests/storage-manager/fake-storage.d.ts.map +1 -0
  64. package/dist/tests/storage-manager/storage-manager.test.d.ts +2 -0
  65. package/dist/tests/storage-manager/storage-manager.test.d.ts.map +1 -0
  66. package/dist/tsconfig.tsbuildinfo +1 -0
  67. package/package.json +81 -0
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("axios"),V=require("uuid"),E=require("@simplewebauthn/browser"),C="X-Passflow-Clientid",m="Authorization",$="X-Passflow-DeviceId",R="X-Passflow-DeviceType",U=["id","offline","tenant","email","oidc","openid","access:tenant:all"],_="https://auth.passflow.cloud",Y="default",z=i=>{const e=[];let t;for(t in i){const s=i[t];if(s===void 0)continue;const r={tenant:{id:s.tenant_id,name:s.tenant_name}};r.groups=s.groups?Object.keys(s.groups).map(o=>{const n=s.groups[o]||[];return{group:{id:o,name:s.group_names?.[o]??"unknown"},roles:n}}):[],r.tenantRoles=r.groups?.find(o=>o.group.id===s.root_group_id),e.push(r)}return{raw:i,tenants:e}};class J{constructor(){this.storageManager=new P}isTokenTypeExpired(e){const t=this.storageManager.getToken(e);if(!t)return!0;const s=d(t);return s?f(s):!0}parseTokenType(e){const t=this.storageManager.getToken(e);if(t)return d(t)}}function f(i){return Math.floor(Date.now()/1e3)>i.exp}function d(i){const e=i.split(".")[1];if(!e)throw new Error("Invalid token string");const t=e.replace(/-/g,"+").replace(/_/g,"/"),s=decodeURIComponent(window.atob(t).split("").map(o=>"%"+("00"+o.charCodeAt(0).toString(16)).slice(-2)).join("")),r=JSON.parse(s);return r.membership=r.passflow_tm&&r.type!=="invite"?z(r.passflow_tm):void 0,r}var g=(i=>(i.id_token="id_token",i.access_token="access",i.refresh_token="refresh",i.invite_token="invite",i.reset_token="reset",i.web_cookie="web-cookie",i.management="management",i.signin="signin",i.actor="actor",i))(g||{});class P{constructor({storage:e,prefix:t}={}){this.keyStoragePrefix="",this.scopes=`${this.keyStoragePrefix}tokens_scopes`,this.deviceId=`${this.keyStoragePrefix}passflowDeviceId`,this.invitationToken=`${this.keyStoragePrefix}passflowInvitationToken`,this.previousRedirectUrl=`${this.keyStoragePrefix}passflowPreviousRedirectUrl`,this.storage=e??localStorage,this.keyStoragePrefix=t?`${t}_`:""}saveTokens(e){const{id_token:t,access_token:s,refresh_token:r,scopes:o}=e;t&&this.storage.setItem(this.getKeyForTokenType(g.id_token),t),s&&this.storage.setItem(this.getKeyForTokenType(g.access_token),s),r&&this.storage.setItem(this.getKeyForTokenType(g.refresh_token),r),o&&this.storage.setItem(this.scopes,o.join(","))}getToken(e){const t=this.getKeyForTokenType(e);return this.storage.getItem(t)??void 0}getTokens(){const e=this.storage.getItem(this.getKeyForTokenType(g.access_token));if(e)return{access_token:e,id_token:this.storage.getItem(this.getKeyForTokenType(g.id_token))??void 0,refresh_token:this.storage.getItem(this.getKeyForTokenType(g.refresh_token))??void 0,scopes:this.storage.getItem(this.scopes)?.split(",")??void 0}}getScopes(){return this.storage.getItem(this.scopes)?.split(",")??void 0}deleteToken(e){const t=this.getKeyForTokenType(e);this.storage.removeItem(t)}deleteTokens(){this.storage.removeItem(this.getKeyForTokenType(g.id_token)),this.storage.removeItem(this.getKeyForTokenType(g.access_token)),this.storage.removeItem(this.getKeyForTokenType(g.refresh_token)),this.storage.removeItem(this.scopes)}getDeviceId(){return this.storage.getItem(this.deviceId)??void 0}setDeviceId(e){this.storage.setItem(this.deviceId,e)}deleteDeviceId(){this.storage.removeItem(this.deviceId)}setInvitationToken(e){this.storage.setItem(this.invitationToken,e)}getInvitationToken(){return this.storage.getItem(this.invitationToken)??void 0}deleteInvitationToken(){this.storage.removeItem(this.invitationToken)}setPreviousRedirectUrl(e){this.storage.setItem(this.previousRedirectUrl,e)}getPreviousRedirectUrl(){return this.storage.getItem(this.previousRedirectUrl)??void 0}deletePreviousRedirectUrl(){this.storage.removeItem(this.previousRedirectUrl)}getKeyForTokenType(e){return`${this.keyStoragePrefix}${e}`}}class D{constructor(){this.storageManager=new P}getDeviceId(){const e=this.storageManager.getDeviceId();if(!e){const t=this.generateUniqueDeviceId();return this.storageManager.setDeviceId(t),t}return e}generateUniqueDeviceId(){return V.v4()}}var S=(i=>(i.GET="get",i.POST="post",i.PUT="put",i.PATCH="patch",i.DELETE="delete",i))(S||{}),c=(i=>(i.signin="/auth/login",i.signup="/auth/register",i.signInWithProvider="/auth/federated/start/",i.passwordless="/auth/passwordless/start",i.passwordlessComplete="/auth/passwordless/complete",i.logout="/user/logout",i.refresh="/auth/refresh",i.sendPasswordResetEmail="/auth/password/reset",i.resetPassword="/auth/password/change",i.appSettings="/app/settings",i.passkeyRegisterStart="/auth/passkey/register/start",i.passkeyRegisterComplete="/auth/passkey/register/complete",i.passkeyAuthenticateStart="/auth/passkey/authenticate/start",i.passkeyAuthenticateComplete="/auth/passkey/authenticate/complete",i.passkeyValidate="/auth/validate",i.settingsAll="/settings",i.settingsPasswordPolicy="/settings/password",i.settingsPasskey="/settings/passkey",i.userPasskey="/user/passkey",i.addUserPasskey="/user/passkey/add/start",i.completeAddUserPasskey="/user/passkey/add/complete",i.joinInvitation="/user/tenant/join",i.tenantPath="/user/tenant",i.invitationsPath="/user/tenant/:tenantID/invitations",i.requestInvitation="/user/invite",i.invitationDelete="/user/invite/:invitationID",i.invitationResend="/user/invite/:invitationID/resend",i.invitationGetLink="/user/invite/:invitationID/link",i))(c||{}),v=(i=>(i.passkeyRegisterStart="/admin/auth/passkey/register/start",i.passkeyRegisterComplete="/admin/auth/passkey/register/complete",i.passkeyAuthenticateStart="/admin/auth/passkey/authenticate/start",i.passkeyAuthenticateComplete="/admin/auth/passkey/authenticate/complete",i.passkeyValidate="/admin/auth/validate",i.logout="/admin/auth/logout",i))(v||{});class u extends Error{constructor(e){super(),this.id=e?.id??"unknown",this.message=e?.message??e??"Something went wrong",this.status=e?.status??500,this.location=e?.location??"unknown",this.time=e?.time??new Date().toISOString()}}var x=(i=>(i.google="google",i.facebook="facebook",i))(x||{}),w=(i=>(i.web="web",i))(w||{});function b(i,e){let t=i;return Object.entries(e).forEach(([s,r])=>{t=t.replace(`:${s}`,r)}),t}class I{constructor(e){this.refreshPromise=null,this.origin=window.location.origin,this.defaultHeaders={Accept:"application/json","Content-Type":"application/json"},this.nonAccessTokenEndpoints=["/auth/","/settings","/settings/"],this.protectedEndpoints=["logout","refresh"];const{url:t,appId:s,keyStoragePrefix:r}=e;this.url=t||_,this.storageManager=new P({prefix:r??""}),this.deviceService=new D,this.tokenService=new J,s&&(this.appId=s,this.defaultHeaders={...this.defaultHeaders,[C]:s});const o=this.deviceService.getDeviceId();this.defaultHeaders={...this.defaultHeaders,[$]:o,[R]:"web"},this.instance=T.create({baseURL:this.url,headers:{...this.defaultHeaders}}),this.instance.interceptors.request.use(async n=>{if(this.isNonAuthEndpoint(n.url))return n;if(n.url?.includes("refresh")){if(this.refreshPromise){const p=new AbortController;return p.abort(),n.signal=p.signal,n}return n}const h=this.storageManager.getTokens(),l=this.storageManager.getScopes();if(h?.access_token){const p=d(h.access_token);if(f(p)&&h.refresh_token)try{if(this.refreshPromise){const A=await this.refreshPromise;return A.data&&(n.headers[m]=`Bearer ${A.data.access_token}`),n}const y={refresh_token:h.refresh_token,scopes:l};this.refreshPromise=this.instance.post(c.refresh,y,{headers:{[m]:`Bearer ${h.refresh_token}`}});const k=await this.refreshPromise;return k.data&&(this.storageManager.saveTokens(k.data),n.headers[m]=`Bearer ${k.data.access_token}`),n}catch(y){return this.refreshPromise=null,Promise.reject(y)}finally{this.refreshPromise=null}return n.headers[m]=`Bearer ${h.access_token}`,n}return n}),this.instance.interceptors.response.use(n=>n,n=>this.handleAxiosError(n))}isProtectedEndpoint(e){return this.protectedEndpoints.some(t=>e?.includes(t))}isNonAuthEndpoint(e){return this.nonAccessTokenEndpoints.some(t=>e?.includes(t))&&!this.isProtectedEndpoint(e)}async handleAxiosError(e){if(!e.response)return Promise.reject(e);const t=e.response.status,s=e.response.data;if("error"in s&&typeof s.error=="object"&&s.error!==null){const{error:r}=s;return Promise.reject(new u(r))}return Promise.reject(new u({id:`error.http.${t}`,message:e.message||"An error occurred",status:t,location:e.config?.url||"unknown",time:new Date().toISOString()}))}async send(e,t,s){return(await this.instance.request({method:e,url:t,...s})).data}get(e,t){return this.send(S.GET,e,t)}post(e,t,s){return this.send(S.POST,e,{data:t,...s})}put(e,t,s){return this.send(S.PUT,e,{data:t,...s})}patch(e,t,s){return this.send(S.PATCH,e,{data:t,...s})}delete(e,t){return this.send(S.DELETE,e,t)}}class F{constructor(e){this.storageManager=new P,this.axiosClient=new I(e)}refreshToken(e,t,s){const r={access:s,scopes:t};return this.axiosClient.post(c.refresh,r,{headers:{[m]:`Bearer ${e}`}})}signIn(e,t,s){const r={...e,device:t,os:s};return this.axiosClient.post(c.signin,r)}signUp(e){const{create_tenant:t,anonymous:s}=e,r={...e,create_tenant:t??!1,anonymous:s??!1};return this.axiosClient.post(c.signup,r)}passwordlessSignIn(e,t,s){const{create_tenant:r}=e,o={...e,create_tenant:r??!1,device:t,os:s};return this.axiosClient.post(c.passwordless,o)}passwordlessSignInComplete(e){return this.axiosClient.post(c.passwordlessComplete,e)}logOut(e,t,s=!1){const r=s?void 0:{refresh_token:t,device:e},o=s?v.logout:c.logout;return this.axiosClient.post(o,r)}sendPasswordResetEmail(e){return this.axiosClient.post(c.sendPasswordResetEmail,e)}resetPassword(e,t,s){const r={password:e,scopes:t};return this.axiosClient.post(c.resetPassword,r,{headers:{[m]:`Bearer ${s}`,[C]:void 0}})}passkeyRegisterStart(e,t,s,r=!1){const{create_tenant:o}=e,n={...e,create_tenant:o??!1,device:t,os:s},h=r?v.passkeyRegisterStart:c.passkeyRegisterStart;return this.axiosClient.post(h,n)}passkeyRegisterComplete(e,t,s,r=!1){const o={challenge_id:s,device:t,passkey_data:e},n=r?v.passkeyRegisterComplete:c.passkeyRegisterComplete;return this.axiosClient.post(n,o)}passkeyAuthenticateStart(e,t,s,r=!1){const o={...e,user_id:e.user_id??"",device:t,os:s},n=r?v.passkeyAuthenticateStart:c.passkeyAuthenticateStart;return this.axiosClient.post(n,o)}passkeyAuthenticateComplete(e,t,s,r=!1){const o={challenge_id:s,device:t,passkey_data:e},n=r?v.passkeyAuthenticateComplete:c.passkeyAuthenticateComplete;return this.axiosClient.post(n,o)}passkeyValidate(e,t,s,r=!1,o){const n={otp:e,device:t,challenge_id:s};let h=c.passkeyValidate;!o&&r&&(h=v.passkeyValidate);const l=o?{[C]:o}:{};return this.axiosClient.post(h,n,{headers:l})}}class M{constructor(e){this.axiosClient=new I(e)}getAppSettings(){return this.axiosClient.get(c.appSettings)}}class L{constructor(e){this.axiosClient=new I(e)}getSettingsAll(){return this.axiosClient.get(c.settingsAll)}getPasswordPolicySettings(){return this.axiosClient.get(c.settingsPasswordPolicy)}getPasskeySettings(){return this.axiosClient.get(c.settingsPasskey)}}class G{constructor(e){this.axiosClient=new I(e)}getUserPasskeys(){return this.axiosClient.get(c.userPasskey)}renameUserPasskey(e,t){return this.axiosClient.patch(`${c.userPasskey}/${t}`,{name:e})}deleteUserPasskey(e){return this.axiosClient.delete(`${c.userPasskey}/${e}`)}addUserPasskeyStart({relyingPartyId:e,deviceId:t,os:s,passkeyDisplayName:r,passkeyUsername:o}){const n={passkey_display_name:r,passkey_username:o,relying_party_id:e,deviceId:t,os:s};return this.axiosClient.post(c.addUserPasskey,n)}addUserPasskeyComplete(e,t,s){return this.axiosClient.post(c.completeAddUserPasskey,{challenge_id:s,device:t,passkey_data:e})}}class O{constructor(e){this.axiosClient=new I(e)}joinInvitation(e,t){const s={invite_token:e,scopes:t};return this.axiosClient.post(c.joinInvitation,s)}createTenant(e){const t={name:e};return this.axiosClient.post(c.tenantPath,t)}getTenantDetails(e){const t=`${c.tenantPath}/${e}`;return this.axiosClient.get(t)}updateTenant(e,t){const s=`${c.tenantPath}/${e}`,r={name:t};return this.axiosClient.put(s,r)}deleteTenant(e){const t=`${c.tenantPath}/${e}`;return this.axiosClient.delete(t)}getUserTenantMembership(){return this.axiosClient.get(c.tenantPath)}createGroup(e,t){const s=`${c.tenantPath}/${e}/group`,r={name:t};return this.axiosClient.post(s,r)}getGroupInfo(e,t){const s=`${c.tenantPath}/${e}/group/${t}`;return this.axiosClient.get(s)}updateGroup(e,t,s){const r=`${c.tenantPath}/${e}/group/${t}`,o={name:s};return this.axiosClient.put(r,o)}deleteGroup(e,t){const s=`${c.tenantPath}/${e}/group/${t}`;return this.axiosClient.delete(s)}addUserToGroup(e,t,s,r){const o=`${c.tenantPath}/${e}/group/${t}/add`,n={user_id:s,role:r};return this.axiosClient.post(o,n)}removeUserRolesFromGroup(e,t,s,r){const o=`${c.tenantPath}/${e}/group/${t}/remove_roles`,n={user_id:s,roles:r};return this.axiosClient.post(o,n)}changeUserRoles(e,t,s,r){const o=`${c.tenantPath}/${e}/group/${t}/change`,n={user_id:s,roles:r};return this.axiosClient.post(o,n)}deleteUserFromGroup(e,t,s){const r=`${c.tenantPath}/${e}/group/${t}/${s}`;return this.axiosClient.delete(r)}getRolesForTenant(e){const t=`${c.tenantPath}/${e}/role`;return this.axiosClient.get(t)}createRoleForTenant(e,t){const s=`${c.tenantPath}/${e}/role`,r={name:t};return this.axiosClient.post(s,r)}updateRole(e,t,s){const r=`${c.tenantPath}/${e}/role/${t}`,o={name:s};return this.axiosClient.put(r,o)}deleteRole(e,t){const s=`${c.tenantPath}/${e}/role/${t}`;return this.axiosClient.delete(s)}deleteUserFromTenant(e,t){const s=`${c.tenantPath}/${e}/user/${t}`;return this.axiosClient.delete(s)}getGroupInvitations(e,t,s,r){const o=`${c.tenantPath}/${e}/group/${t}/invitations`;return this.axiosClient.get(o,{params:{limit:s,skip:r}})}getTenantInvitations(e,t,s){const r=`${c.tenantPath}/${e}/invitations`;return this.axiosClient.get(r,{params:{limit:t,skip:s}})}invalidateInviteById(e,t,s){const r=`${c.tenantPath}/${e}/group/${t}/invite/${s}`;return this.axiosClient.delete(r)}invalidateInviteByEmail(e,t,s){const r=`${c.tenantPath}/${e}/group/${t}/invite/email/${s}`;return this.axiosClient.delete(r)}}class j{constructor(e){this.axiosClient=new I(e)}requestInviteLink(e){return this.axiosClient.post(c.requestInvitation,e)}getInvitations(e){const t={};e.groupID&&(t.group_id=e.groupID.toString()),e.skip!==void 0&&(t.skip=e.skip.toString()),e.limit!==void 0&&(t.limit=e.limit.toString());const s=b(c.invitationsPath,{tenantID:e.tenantID});return this.axiosClient.get(s,{params:t}).then(r=>({invites:r.invites,nextPageSkip:r.next_page_skip}))}deleteInvitation(e){const t=b(c.invitationDelete,{invitationID:e});return this.axiosClient.delete(t)}resendInvitation(e){const t=b(c.invitationResend,{invitationID:e});return this.axiosClient.post(t,{})}getInvitationLink(e){const t=b(c.invitationGetLink,{invitationID:e});return this.axiosClient.get(t)}}var a=(i=>(i.SignIn="signin",i.SignInStart="signin:start",i.Register="register",i.RegisterStart="register:start",i.SignOut="signout",i.Error="error",i.Refresh="refresh",i.RefreshStart="refresh:start",i.TokenCacheExpired="token-cache-expired",i))(a||{});class X{constructor(){this.subscribers=new Map}subscribe(e,t){if(t?.length){const s=new Set(t);this.subscribers.set(e,s)}else this.subscribers.set(e,null)}unsubscribe(e,t){if(!t?.length){this.subscribers.delete(e);return}const s=this.subscribers.get(e);s&&(t.forEach(r=>s.delete(r)),s.size===0&&this.subscribers.delete(e))}notify(e,t){this.subscribers.forEach((s,r)=>{(!s||s.has(e))&&r.onAuthChange?.(e,t)})}}class K{constructor(e,t,s,r,o,n,h,l,p,y,k){this.authApi=e,this.deviceService=t,this.storageManager=s,this.subscribeStore=r,this.tokenCacheService=o,this.scopes=n,this.createTenantForNewUser=h,this.origin=l,this.url=p,this.sessionCallbacks=y,this.appId=k}async signIn(e){this.subscribeStore.notify(a.SignInStart,{email:e.email});const t=this.deviceService.getDeviceId(),s=w.web;e.scopes=e.scopes??this.scopes;try{const r=await this.authApi.signIn(e,t,s);return r.scopes=e.scopes,this.storageManager.saveTokens(r),this.tokenCacheService.setTokensCache(r),this.subscribeStore.notify(a.SignIn,{tokens:r,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),await this.submitSessionCheck(),r}catch(r){const o={message:r instanceof Error?r.message:"Sign in failed",originalError:r,code:r instanceof u?r.id:void 0};throw this.subscribeStore.notify(a.Error,o),r}}async signUp(e){this.subscribeStore.notify(a.RegisterStart,{email:e.user.email}),e.scopes=e.scopes??this.scopes,e.create_tenant=this.createTenantForNewUser;try{const t=await this.authApi.signUp(e);return t.scopes=e.scopes,this.storageManager.saveTokens(t),this.tokenCacheService.setTokensCache(t),this.subscribeStore.notify(a.Register,{tokens:t,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),await this.submitSessionCheck(),t}catch(t){const s={message:t instanceof Error?t.message:"Sign up failed",originalError:t,code:t instanceof u?t.id:void 0};throw this.subscribeStore.notify(a.Error,s),t}}async passwordlessSignIn(e){this.subscribeStore.notify(a.SignInStart,{email:e.email}),e.scopes=e.scopes??this.scopes;const t=this.deviceService.getDeviceId(),s=w.web;try{return await this.authApi.passwordlessSignIn(e,t,s)}catch(r){const o={message:r instanceof Error?r.message:"Failed to send passwordless sign-in link",originalError:r,code:r instanceof u?r.id:void 0};throw this.subscribeStore.notify(a.Error,o),r}}async passwordlessSignInComplete(e){this.subscribeStore.notify(a.SignInStart,{}),e.scopes=e.scopes??this.scopes,e.device=this.deviceService.getDeviceId();try{const t=await this.authApi.passwordlessSignInComplete(e);return t.scopes=e.scopes,this.storageManager.saveTokens(t),this.tokenCacheService.setTokensCache(t),this.subscribeStore.notify(a.SignIn,{tokens:t,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),await this.submitSessionCheck(),t}catch(t){const s={message:t instanceof Error?t.message:"Passwordless sign in failed",originalError:t,code:t instanceof u?t.id:void 0};throw this.subscribeStore.notify(a.Error,s),t}}async logOut(){const e=this.storageManager.getToken(g.refresh_token),t=this.storageManager.getDeviceId();try{if((await this.authApi.logOut(t,e,!this.appId)).status!=="ok")throw new Error("Logout failed");this.storageManager.deleteTokens(),this.subscribeStore.notify(a.SignOut,{})}catch(s){throw console.error(s),s}}async refreshToken(){this.subscribeStore.notify(a.RefreshStart,{});const e=this.storageManager.getTokens();if(e){if(!e?.refresh_token){const s=new Error("No refresh token found"),r={message:"No refresh token found",originalError:s};throw this.subscribeStore.notify(a.Error,r),s}}else{const s=new Error("No tokens found"),r={message:"No tokens found",originalError:s};throw this.subscribeStore.notify(a.Error,r),s}const t=e?.scopes??this.scopes;try{const s=await this.authApi.refreshToken(e?.refresh_token??"",t,e?.access_token);return s.scopes=t,this.storageManager.saveTokens(s),this.tokenCacheService.setTokensCache(s),this.subscribeStore.notify(a.Refresh,{tokens:s,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),this.subscribeStore.notify(a.TokenCacheExpired,{isExpired:!1}),this.tokenCacheService.isRefreshing=!1,this.tokenCacheService.isExpired=!1,this.tokenCacheService.startTokenCheck(),s}catch(s){const r={message:s instanceof Error?s.message:"Token refresh failed",originalError:s,code:s instanceof u?s.id:void 0,details:T.isAxiosError(s)&&s.response?{status:s.response.status,data:s.response.data}:void 0};throw this.subscribeStore.notify(a.Error,r),s instanceof u?s:T.isAxiosError(s)&&s.response&&s.response?.status>=400&&s.response?.status<500?new Error(`Getting unknown error message from server with code:${s.response.status}`):s}}async sendPasswordResetEmail(e){try{return await this.authApi.sendPasswordResetEmail(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to send password reset email",originalError:t,code:t instanceof u?t.id:void 0};throw this.subscribeStore.notify(a.Error,s),t}}async resetPassword(e,t){this.subscribeStore.notify(a.SignInStart,{});const r=new URLSearchParams(window.location.search).get("token")??void 0,o=t??this.scopes;try{const n=await this.authApi.resetPassword(e,o,r);return n.scopes=o,this.storageManager.saveTokens(n),this.tokenCacheService.setTokensCache(n),this.subscribeStore.notify(a.SignIn,{tokens:n,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),await this.submitSessionCheck(),n}catch(n){const h={message:n instanceof Error?n.message:"Password reset failed",originalError:n,code:n instanceof u?n.id:void 0};throw this.subscribeStore.notify(a.Error,h),n}}async passkeyRegister(e){this.subscribeStore.notify(a.RegisterStart,{});const t=this.deviceService.getDeviceId(),s=w.web;e.scopes=e.scopes??this.scopes,e.create_tenant=this.createTenantForNewUser;try{const{challenge_id:r,publicKey:o}=await this.authApi.passkeyRegisterStart(e,t,s,!this.appId);o.user.id=btoa(o.user.id);const n=await E.startRegistration({optionsJSON:o}),h=await this.authApi.passkeyRegisterComplete(n,t,r,!this.appId);return h.scopes=e.scopes,this.storageManager.saveTokens(h),this.tokenCacheService.setTokensCache(h),this.subscribeStore.notify(a.Register,{tokens:h,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),await this.submitSessionCheck(),h}catch(r){const o={message:r instanceof Error?r.message:"Passkey registration failed",originalError:r,code:r instanceof u?r.id:void 0};throw this.subscribeStore.notify(a.Error,o),r}}async passkeyAuthenticate(e){this.subscribeStore.notify(a.SignInStart,{});const t=this.deviceService.getDeviceId(),s=w.web;e.scopes=e.scopes??this.scopes;try{const{challenge_id:r,publicKey:o}=await this.authApi.passkeyAuthenticateStart(e,t,s,!this.appId),n=await E.startAuthentication({optionsJSON:o}),h=await this.authApi.passkeyAuthenticateComplete(n,t,r,!this.appId);return"access_token"in h&&(h.scopes=e.scopes,this.storageManager.saveTokens(h),this.tokenCacheService.setTokensCache(h),this.subscribeStore.notify(a.SignIn,{tokens:h,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),await this.submitSessionCheck()),h}catch(r){const o={message:r instanceof Error?r.message:"Passkey authentication failed",originalError:r,code:r instanceof u?r.id:void 0};throw this.subscribeStore.notify(a.Error,o),r}}createFederatedAuthUrl(e){const t=`/auth/federated/start/${e.provider}`;if(!this.appId)throw new Error("AppId is required for federated auth");const r={scopes:(e.scopes??this.scopes).join(" "),redirect_url:e.redirect_url??this.origin,appId:this.appId,...e.invite_token?{invite_token:e.invite_token}:{},...e.create_tenant?{create_tenant:e.create_tenant.toString()}:{},...e.device?{device:e.device}:{}},o=new URL(t,this.url),n=new URLSearchParams(r);return o.search=n.toString(),o.toString()}federatedAuthWithPopup(e){this.subscribeStore.notify(a.SignInStart,{provider:e.provider});const t=e.scopes??this.scopes,s=this.deviceService.getDeviceId(),r=this.createFederatedAuthUrl({...e,scopes:t,device:s}),o=window.open(r,"_blank","width=500,height=500");if(!o)this.federatedAuthWithRedirect(e);else{const n=setInterval(()=>{if(o.location.href.startsWith(this.origin)){const h=new URLSearchParams(o.location.search),l=h.get("access_token")||"",p=h.get("refresh_token")||"",y=h.get("id_token")||"",k={access_token:l,refresh_token:p,id_token:y,scopes:t};this.storageManager.saveTokens(k),this.tokenCacheService.setTokensCache(k),this.subscribeStore.notify(a.SignIn,{tokens:k,parsedTokens:this.tokenCacheService.getParsedTokenCache()}),window.location.href=`${this.origin}`,clearInterval(n),o.close()}},100)}}federatedAuthWithRedirect(e){this.subscribeStore.notify(a.SignInStart,{provider:e.provider});const t=e.scopes??this.scopes,s=this.deviceService.getDeviceId(),r=this.createFederatedAuthUrl({...e,scopes:t,device:s});window.location.href=r}authRedirectUrl(e={}){try{const{url:t,redirectUrl:s,scopes:r,appId:o}=e??{},n=new URL(t??this.url);n.pathname=(n.pathname.endsWith("/")?n.pathname:n.pathname+"/")+"web";const h=r??this.scopes,l={appId:o??this.appId??"",redirectto:s??window.location.href,scopes:h.join(",")},p=new URLSearchParams(l);return n.search=p.toString(),n.toString()}catch(t){const s={message:t instanceof Error?t.message:"Failed to create auth redirect URL",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}authRedirect(e={}){try{window.location.href=this.authRedirectUrl(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to redirect to auth page",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}isAuthenticated(e){try{return e?!f(e.access_token)||!!e.refresh_token&&!f(e.refresh_token):!1}catch(t){const s={message:t instanceof Error?t.message:"Failed to check authentication status",originalError:t};return this.subscribeStore.notify(a.Error,s),!1}}async submitSessionCheck(e=!1){let t,s;try{t=await this.getTokens(e),s=this.tokenCacheService.getParsedTokenCache()}catch(r){const o={message:r instanceof Error||r instanceof u?r.message:"Session check failed",originalError:r};this.subscribeStore.notify(a.Error,o),t=void 0}return t&&this.sessionCallbacks.createSession&&await this.sessionCallbacks.createSession({tokens:t,parsedTokens:s}),!t&&this.sessionCallbacks.expiredSession&&await this.sessionCallbacks.expiredSession(),t}async getTokens(e){try{const t=this.storageManager.getTokens();if(!t||!t.access_token)return;const s=d(t.access_token);return f(s)?e?await this.refreshToken():void 0:t}catch(t){const s={message:t instanceof Error?t.message:"Failed to get tokens",originalError:t};this.subscribeStore.notify(a.Error,s);return}}}class N{constructor(e){this.invitationAPI=e}requestInviteLink(e){return this.invitationAPI.requestInviteLink(e)}getInvitations(e){return this.invitationAPI.getInvitations(e)}deleteInvitation(e){return this.invitationAPI.deleteInvitation(e)}resendInvitation(e){return this.invitationAPI.resendInvitation(e)}getInvitationLink(e){return this.invitationAPI.getInvitationLink(e)}}class Z{error(e,...t){console.error(e,...t)}warn(e,...t){console.warn(e,...t)}info(e,...t){console.info(e,...t)}debug(e,...t){console.debug(e,...t)}}function Q(){return new Z}class H{constructor(e){this.data=this.normalize(e)}normalize(e){const t=new Map,s=new Map,r=new Map,o=[];return e.groups?.forEach(n=>{s.set(n.id,{id:n.id,name:n.name,default:n.default??!1,updated_at:n.updated_at,created_at:n.created_at})}),e.roles?.forEach(n=>{r.set(n.id,{id:n.id,tenant_id:n.tenant_id,name:n.name})}),e.users_in_groups?.forEach(n=>{const h=n.user;h&&!t.has(h.id)&&t.set(h.id,{id:h.id,name:h.name??null,email:h.email??null,phone:h.phone??null}),h&&n.group_id&&s.has(n.group_id)&&o.push({userId:h.id,groupId:n.group_id,roleIds:n.roles?.map(l=>l.id)??[]})}),{tenant_id:e.tenant_id,tenant_name:e.tenant_name,users:Array.from(t.values()),groups:Array.from(s.values()),roles:Array.from(r.values()),memberships:o,usersById:t,groupsById:s,rolesById:r}}getUsersInGroup(e){return this.data.memberships.filter(t=>t.groupId===e).map(t=>this.data.usersById.get(t.userId)).filter(t=>t!==void 0)}getGroupsForUser(e){return this.data.memberships.filter(t=>t.userId===e).map(t=>this.data.groupsById.get(t.groupId)).filter(t=>t!==void 0)}getUserRolesInGroup(e,t){const s=this.data.memberships.find(r=>r.userId===e&&r.groupId===t);return s?s.roleIds.map(r=>this.data.rolesById.get(r)).filter(r=>r!==void 0):[]}getData(){return this.data}}class W{constructor(e,t,s){this.tenantAPI=e,this.scopes=t,this.logger=s||Q()}handlePassflowError(e,t){if(T.isAxiosError(e)&&e.response?.data){const s=e.response.data;if(typeof s=="object"&&s!==null&&"error"in s&&typeof s.error=="object"&&s.error!==null){const r=s.error;throw this.logger.error(`${t}: ${r.id} - ${r.message} (Status: ${r.status})`),new Error(`Passflow API Error: ${r.id} - ${r.message} (Status: ${r.status})`)}}throw this.logger.error(`${t}:`,e),e instanceof Error?e:new Error(String(e))}async joinInvitation(e,t){try{const s=t??this.scopes;return await this.tenantAPI.joinInvitation(e,s)}catch(s){this.handlePassflowError(s,"Join invitation failed")}}async createTenant(e){try{return await this.tenantAPI.createTenant(e)}catch(t){this.handlePassflowError(t,"Tenant creation failed")}}async getTenantDetails(e){try{return await this.tenantAPI.getTenantDetails(e)}catch(t){this.handlePassflowError(t,`Get tenant details failed for tenant ID ${e}`)}}async getTenantUserMembership(e){try{const t=await this.tenantAPI.getTenantDetails(e);return new H(t)}catch(t){this.handlePassflowError(t,`Get tenant user membership failed for tenant ID ${e}`)}}async updateTenant(e,t){try{return await this.tenantAPI.updateTenant(e,t)}catch(s){this.handlePassflowError(s,`Update tenant failed for tenant ID ${e}`)}}async deleteTenant(e){try{return await this.tenantAPI.deleteTenant(e)}catch(t){this.handlePassflowError(t,`Delete tenant failed for tenant ID ${e}`)}}async getUserTenantMembership(){try{return await this.tenantAPI.getUserTenantMembership()}catch(e){this.handlePassflowError(e,"Get user tenant memberships failed")}}async createGroup(e,t){try{return await this.tenantAPI.createGroup(e,t)}catch(s){this.handlePassflowError(s,`Group creation failed for tenant ID ${e}`)}}async getGroupInfo(e,t){try{return await this.tenantAPI.getGroupInfo(e,t)}catch(s){this.handlePassflowError(s,`Get group info failed for tenant ID ${e}, group ID ${t}`)}}async updateGroup(e,t,s){try{return await this.tenantAPI.updateGroup(e,t,s)}catch(r){this.handlePassflowError(r,`Update group failed for tenant ID ${e}, group ID ${t}`)}}async deleteGroup(e,t){try{return await this.tenantAPI.deleteGroup(e,t)}catch(s){this.handlePassflowError(s,`Delete group failed for tenant ID ${e}, group ID ${t}`)}}async addUserToGroup(e,t,s,r){try{return await this.tenantAPI.addUserToGroup(e,t,s,r)}catch(o){this.handlePassflowError(o,`Add user to group failed for tenant ID ${e}, group ID ${t}, user ID ${s}`)}}async removeUserRolesFromGroup(e,t,s,r){try{return await this.tenantAPI.removeUserRolesFromGroup(e,t,s,r)}catch(o){this.handlePassflowError(o,`Remove user roles from group failed for tenant ID ${e}, group ID ${t}, user ID ${s}`)}}async changeUserRoles(e,t,s,r){try{return await this.tenantAPI.changeUserRoles(e,t,s,r)}catch(o){this.handlePassflowError(o,`Change user roles failed for tenant ID ${e}, group ID ${t}, user ID ${s}`)}}async deleteUserFromGroup(e,t,s){try{return await this.tenantAPI.deleteUserFromGroup(e,t,s)}catch(r){this.handlePassflowError(r,`Delete user from group failed for tenant ID ${e}, group ID ${t}, user ID ${s}`)}}async getRolesForTenant(e){try{return await this.tenantAPI.getRolesForTenant(e)}catch(t){this.handlePassflowError(t,`Get roles for tenant failed for tenant ID ${e}`)}}async createRoleForTenant(e,t){try{return await this.tenantAPI.createRoleForTenant(e,t)}catch(s){this.handlePassflowError(s,`Create role for tenant failed for tenant ID ${e}`)}}async updateRole(e,t,s){try{return await this.tenantAPI.updateRole(e,t,s)}catch(r){this.handlePassflowError(r,`Update role failed for tenant ID ${e}, role ID ${t}`)}}async deleteRole(e,t){try{return await this.tenantAPI.deleteRole(e,t)}catch(s){this.handlePassflowError(s,`Delete role failed for tenant ID ${e}, role ID ${t}`)}}async deleteUserFromTenant(e,t){try{return await this.tenantAPI.deleteUserFromTenant(e,t)}catch(s){this.handlePassflowError(s,`Delete user from tenant failed for tenant ID ${e}, user ID ${t}`)}}async getGroupInvitations(e,t,s,r){try{return await this.tenantAPI.getGroupInvitations(e,t,s,r)}catch(o){this.handlePassflowError(o,`Get group invitations failed for tenant ID ${e}, group ID ${t}`)}}async getTenantInvitations(e,t,s){try{return await this.tenantAPI.getTenantInvitations(e,t,s)}catch(r){this.handlePassflowError(r,`Get tenant invitations failed for tenant ID ${e}`)}}async invalidateInviteById(e,t,s){try{return await this.tenantAPI.invalidateInviteById(e,t,s)}catch(r){this.handlePassflowError(r,`Invalidate invite by ID failed for tenant ID ${e}, group ID ${t}, invite ID ${s}`)}}async invalidateInviteByEmail(e,t,s){try{return await this.tenantAPI.invalidateInviteByEmail(e,t,s)}catch(r){this.handlePassflowError(r,`Invalidate invite by email failed for tenant ID ${e}, group ID ${t}, email ${s}`)}}}class B{constructor(e,t){this.userAPI=e,this.deviceService=t}getUserPasskeys(){return this.userAPI.getUserPasskeys()}renameUserPasskey(e,t){return this.userAPI.renameUserPasskey(e,t)}deleteUserPasskey(e){return this.userAPI.deleteUserPasskey(e)}async addUserPasskey({relyingPartyId:e,passkeyUsername:t,passkeyDisplayName:s}={}){const r=this.deviceService.getDeviceId(),o=w.web,{challenge_id:n,publicKey:h}=await this.userAPI.addUserPasskeyStart({relyingPartyId:e||window?.location?.hostname,deviceId:r,os:o,passkeyDisplayName:s,passkeyUsername:t});h.user.id=btoa(h.user.id);const l=await E.startRegistration({optionsJSON:h});return await this.userAPI.addUserPasskeyComplete(l,r,n)}}class q{constructor(e,t,s){this.storageManager=e,this.authApi=t,this.subscribeStore=s,this.checkInterval=null,this.CHECK_INTERVAL=10,this.isRefreshing=!1,this.isExpired=!1,this.storageManager=e,this.authApi=t}initialize(){try{const e=this.storageManager.getTokens();if(!e||!e.access_token){this.startTokenCheck();return}const t=d(e.access_token);f(t)?(this.isExpired=!0,this.stopTokenCheck(),this.subscribeStore.notify(a.TokenCacheExpired,{isExpired:!0})):(this.setTokensCache(e),this.startTokenCheck())}catch(e){const t={message:e instanceof Error?e.message:"Failed to get tokens",originalError:e};this.subscribeStore.notify(a.Error,t),this.setTokensCache(void 0)}}async refreshTokensCache(e){if(!this.isRefreshing)try{this.isRefreshing=!0,this.subscribeStore.notify(a.RefreshStart,{});const t=await this.authApi.refreshToken(e?.refresh_token??"",e.scopes??[],e.access_token);this.setTokensCache(t),this.subscribeStore.notify(a.Refresh,{tokens:t,parsedTokens:this.getParsedTokenCache()}),this.subscribeStore.notify(a.TokenCacheExpired,{isExpired:!1}),this.isExpired=!1,this.startTokenCheck()}catch(t){const s={message:t instanceof Error?t.message:"Failed to get tokens",originalError:t};this.subscribeStore.notify(a.Error,s),this.setTokensCache(void 0)}finally{this.isRefreshing=!1}}startTokenCheck(){this.checkInterval&&clearInterval(this.checkInterval),!this.isExpired&&(this.checkInterval=setInterval(()=>{this.isRefreshing||this.isExpired||this.tokensCacheIsExpired()&&!this.isExpired&&(this.isExpired=!0,this.subscribeStore.notify(a.TokenCacheExpired,{isExpired:!0}),this.stopTokenCheck())},this.CHECK_INTERVAL))}stopTokenCheck(){this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=null)}setTokensCache(e){this.tokensCache=e,e?this.parsedTokensCache={access_token:d(e.access_token),id_token:e.id_token?d(e.id_token):void 0,refresh_token:e.refresh_token?d(e.refresh_token):void 0,scopes:e.scopes}:this.parsedTokensCache=void 0}getTokensCache(){return this.tokensCache}async getTokensCacheWithRefresh(){try{if(!this.tokensCache)return this.tokensCache;const e=d(this.tokensCache.access_token);return f(e)&&!this.isExpired?(await this.refreshTokensCache(this.tokensCache),this.tokensCache):this.tokensCache}catch(e){const t={message:e instanceof Error?e.message:"Failed to get tokens",originalError:e};this.subscribeStore.notify(a.Error,t);return}}getParsedTokenCache(){return this.parsedTokensCache}tokensCacheIsExpired(){if(!this.tokensCache)return!0;const e=d(this.tokensCache.access_token);return f(e)}}class ee{constructor(e){this.doRefreshTokens=!1,this.origin=window.location.origin,this.session=async({createSession:o,expiredSession:n,doRefresh:h=!1})=>{this.createSessionCallback=o,this.expiredSessionCallback=n,this.doRefreshTokens=h,await this.submitSessionCheck()};const{url:t,appId:s,scopes:r}=e;this.url=t||_,this.appId=s,this.authApi=new F(e),this.appApi=new M(e),this.userApi=new G(e),this.settingApi=new L(e),this.tenantAPI=new O(e),this.invitationAPI=new j(e),this.storageManager=new P({prefix:e.keyStoragePrefix??""}),this.deviceService=new D,this.subscribeStore=new X,this.tokenCacheService=new q(this.storageManager,this.authApi,this.subscribeStore),this.scopes=r??U,this.createTenantForNewUser=e.createTenantForNewUser??!1,this.authService=new K(this.authApi,this.deviceService,this.storageManager,this.subscribeStore,this.tokenCacheService,this.scopes,this.createTenantForNewUser,this.origin,this.url,{createSession:this.createSessionCallback,expiredSession:this.expiredSessionCallback},this.appId??""),this.userService=new B(this.userApi,this.deviceService),this.tenantService=new W(this.tenantAPI,this.scopes),this.tenant=this.tenantService,this.invitationService=new N(this.invitationAPI),e.parseQueryParams&&this.checkAndSetTokens(),this.setTokensToCacheFromLocalStorage()}async submitSessionCheck(){let e,t;try{e=await this.authService.getTokens(this.doRefreshTokens),t=this.tokenCacheService.getParsedTokenCache()}catch(s){const r={message:s instanceof Error||s instanceof u?s.message:"Session check failed",originalError:s};this.subscribeStore.notify(a.Error,r),e=void 0}e&&this.createSessionCallback&&await this.createSessionCallback({tokens:e,parsedTokens:t}),!e&&this.expiredSessionCallback&&await this.expiredSessionCallback()}subscribe(e,t){this.subscribeStore.subscribe(e,t),this.tokenCacheService.initialize()}unsubscribe(e,t){this.subscribeStore.unsubscribe(e,t)}handleTokensRedirect(){return this.checkAndSetTokens()}checkAndSetTokens(){const e=new URLSearchParams(window.location.search),t=e.get("access_token"),s=e.get("refresh_token"),r=e.get("id_token"),o=e.get("scopes")?.split(",")??this.scopes;let n;if(t)return n={access_token:t,refresh_token:s??void 0,id_token:r??void 0,scopes:o},this.storageManager.saveTokens(n),this.tokenCacheService.setTokensCache(n),this.subscribeStore.notify(a.SignIn,{tokens:n,parsedTokens:this.getParsedTokenCache()}),this.submitSessionCheck(),e.delete("access_token"),e.delete("refresh_token"),e.delete("id_token"),e.delete("client_challenge"),e.size>0?window.history.replaceState({},document.title,`${window.location.pathname}?${e.toString()}`):window.history.replaceState({},document.title,window.location.pathname),this.error=void 0,n;this.error=this.checkErrorsFromURL()}checkErrorsFromURL(){const t=new URLSearchParams(window.location.search).get("error");if(t)return new Error(t)}setTokensToCacheFromLocalStorage(){const e=this.storageManager.getTokens();e&&this.tokenCacheService.setTokensCache(e)}getTokensCache(){return this.tokenCacheService.getTokensCache()}getTokensCacheWithRefresh(){return this.tokenCacheService.getTokensCacheWithRefresh()}getParsedTokenCache(){return this.tokenCacheService.getParsedTokenCache()}tokensCacheIsExpired(){return this.tokenCacheService.tokensCacheIsExpired()}isAuthenticated(){const e=this.storageManager.getTokens();if(!e||!e.access_token)return!1;const t={access_token:d(e.access_token),refresh_token:e.refresh_token?d(e.refresh_token):void 0};return this.authService.isAuthenticated(t)}async signIn(e){return await this.authService.signIn(e)}async signUp(e){return await this.authService.signUp(e)}passwordlessSignIn(e){return this.authService.passwordlessSignIn(e)}async passwordlessSignInComplete(e){return await this.authService.passwordlessSignInComplete(e)}async logOut(){try{await this.authService.logOut(),this.storageManager.deleteTokens(),await this.submitSessionCheck()}catch(e){const t={message:e instanceof Error?e.message:"Failed to log out",originalError:e};this.subscribeStore.notify(a.Error,t)}this.tokenCacheService.setTokensCache(void 0),this.subscribeStore.notify(a.SignOut,{})}federatedAuthWithPopup(e){this.authService.federatedAuthWithPopup(e)}federatedAuthWithRedirect(e){this.authService.federatedAuthWithRedirect(e)}reset(e){if(this.storageManager.deleteTokens(),this.tokenCacheService.setTokensCache(void 0),this.subscribeStore.notify(a.SignOut,{}),e){this.error=new Error(e);const t={message:e,code:"RESET_ERROR"};throw this.subscribeStore.notify(a.Error,t),this.error}}async refreshToken(){if(!this.tokenCacheService.parsedTokensCache?.refresh_token)throw new Error("No refresh token found");try{return await this.authService.refreshToken()}catch(e){throw e instanceof u||this.subscribeStore.notify(a.Error,{message:"Failed to refresh token",originalError:e}),e}}sendPasswordResetEmail(e){return this.authService.sendPasswordResetEmail(e)}async resetPassword(e,t){return await this.authService.resetPassword(e,t)}async getAppSettings(){try{return await this.appApi.getAppSettings()}catch(e){const t={message:e instanceof Error?e.message:"Failed to get app settings",originalError:e};throw this.subscribeStore.notify(a.Error,t),e}}async getSettingsAll(){try{return await this.settingApi.getSettingsAll()}catch(e){const t={message:e instanceof Error?e.message:"Failed to get all settings",originalError:e};throw this.subscribeStore.notify(a.Error,t),e}}async getPasswordPolicySettings(){try{return await this.settingApi.getPasswordPolicySettings()}catch(e){const t={message:e instanceof Error?e.message:"Failed to get password policy settings",originalError:e};throw this.subscribeStore.notify(a.Error,t),e}}async getPasskeySettings(){try{return await this.settingApi.getPasskeySettings()}catch(e){const t={message:e instanceof Error?e.message:"Failed to get passkey settings",originalError:e};throw this.subscribeStore.notify(a.Error,t),e}}async passkeyRegister(e){return await this.authService.passkeyRegister(e)}async passkeyAuthenticate(e){return await this.authService.passkeyAuthenticate(e)}setTokens(e){this.storageManager.saveTokens(e),this.tokenCacheService.setTokensCache(e),this.subscribeStore.notify(a.SignIn,{tokens:e,parsedTokens:this.tokenCacheService.getParsedTokenCache()})}async getTokens(e=!1){return await this.authService.getTokens(e)}getToken(e){return this.storageManager.getToken(e)}async getUserPasskeys(){try{return await this.userService.getUserPasskeys()}catch(e){const t={message:e instanceof Error?e.message:"Failed to get user passkeys",originalError:e};throw this.subscribeStore.notify(a.Error,t),e}}async renameUserPasskey(e,t){try{return await this.userService.renameUserPasskey(e,t)}catch(s){const r={message:s instanceof Error?s.message:"Failed to rename user passkey",originalError:s};throw this.subscribeStore.notify(a.Error,r),s}}async deleteUserPasskey(e){try{return await this.userService.deleteUserPasskey(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to delete user passkey",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}async addUserPasskey(e){try{return await this.userService.addUserPasskey(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to add user passkey",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}async joinInvitation(e,t){try{const s=await this.tenant.joinInvitation(e,t);return s.scopes=t??this.scopes,this.storageManager.saveTokens(s),this.tokenCacheService.setTokensCache(s),s}catch(s){const r={message:s instanceof Error?s.message:"Failed to join invitation",originalError:s};throw this.subscribeStore.notify(a.Error,r),s}}async createTenant(e,t){try{const s=await this.tenant.createTenant(e);return t&&await this.refreshToken(),s}catch(s){const r={message:s instanceof Error?s.message:"Failed to create tenant",originalError:s};throw this.subscribeStore.notify(a.Error,r),s}}async requestInviteLink(e){try{return e.send_to_email===void 0&&(e.send_to_email=!0),await this.invitationService.requestInviteLink(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to request invite link",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}async getInvitations(e){try{return await this.invitationService.getInvitations(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to get invitations",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}async deleteInvitation(e){try{return await this.invitationService.deleteInvitation(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to delete invitation",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}async resendInvitation(e){try{return await this.invitationService.resendInvitation(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to resend invitation",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}async getInvitationLink(e){try{return await this.invitationService.getInvitationLink(e)}catch(t){const s={message:t instanceof Error?t.message:"Failed to get invitation link",originalError:t};throw this.subscribeStore.notify(a.Error,s),t}}authRedirectUrl(e={}){return this.authService.authRedirectUrl(e)}authRedirect(e={}){this.authService.authRedirect(e)}}exports.APP_ID_HEADER_KEY=C;exports.AUTHORIZATION_HEADER_KEY=m;exports.AppAPI=M;exports.AuthAPI=F;exports.AuthService=K;exports.DEFAULT_GROUP_NAME=Y;exports.DEFAULT_SCOPES=U;exports.DEVICE_ID_HEADER_KEY=$;exports.DEVICE_TYPE_HEADER_KEY=R;exports.InvitationAPI=j;exports.InvitationService=N;exports.OS=w;exports.PASSFLOW_CLOUD_URL=_;exports.Passflow=ee;exports.PassflowAdminEndpointPaths=v;exports.PassflowEndpointPaths=c;exports.PassflowError=u;exports.PassflowEvent=a;exports.Providers=x;exports.RequestMethod=S;exports.SettingAPI=L;exports.TenantAPI=O;exports.TenantService=W;exports.TenantUserMembership=H;exports.TokenCacheService=q;exports.TokenType=g;exports.UserAPI=G;exports.UserService=B;exports.isTokenExpired=f;exports.parseToken=d;exports.pathWithParams=b;
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../lib/constants/index.ts","../lib/token-service/membership.ts","../lib/token-service/service.ts","../lib/token-service/token.ts","../lib/storage-manager/index.ts","../lib/device-service/index.ts","../lib/api/model.ts","../lib/api/axios-client.ts","../lib/api/auth.ts","../lib/api/app.ts","../lib/api/setting.ts","../lib/api/user.ts","../lib/api/tenant.ts","../lib/api/invitation.ts","../lib/store.ts","../lib/services/auth-service.ts","../lib/services/invitation-service.ts","../lib/services/logger.ts","../lib/services/tenant-user-membership.ts","../lib/services/tenant-service.ts","../lib/services/user-service.ts","../lib/services/token-cache-service.ts","../lib/passflow.ts"],"sourcesContent":["export const APP_ID_HEADER_KEY = 'X-Passflow-Clientid';\nexport const AUTHORIZATION_HEADER_KEY = 'Authorization';\nexport const DEVICE_ID_HEADER_KEY = 'X-Passflow-DeviceId';\nexport const DEVICE_TYPE_HEADER_KEY = 'X-Passflow-DeviceType';\nexport const DEFAULT_SCOPES = ['id', 'offline', 'tenant', 'email', 'oidc', 'openid', 'access:tenant:all'];\nexport const PASSFLOW_CLOUD_URL = 'https://auth.passflow.cloud';\nexport const DEFAULT_GROUP_NAME = 'default';\n","export type Tenant = {\n id: string;\n name: string;\n};\n\nexport type TenantMembership = {\n tenant: Tenant;\n tenantRoles?: GroupMembership;\n groups?: GroupMembership[];\n};\n\nexport type Group = {\n id: string;\n name: string;\n};\n\nexport type GroupMembership = {\n group: Group;\n roles: string[];\n};\n\nexport type RawUserMembership = {\n [key: string]: {\n tenant_id: string;\n tenant_name: string;\n tenant_roles?: string[];\n root_group_id: string;\n groups: {\n [key: string]: string[];\n };\n group_names: { [key: string]: string };\n };\n};\n\nexport type UserMembership = {\n raw: RawUserMembership;\n tenants: TenantMembership[];\n};\n\nexport const parseMembership = (raw: RawUserMembership): UserMembership => {\n const tenants: TenantMembership[] = [];\n let k: string;\n for (k in raw) {\n const v = raw[k];\n if (v === undefined) {\n continue;\n }\n const tnt: TenantMembership = { tenant: { id: v.tenant_id, name: v.tenant_name } };\n tnt.groups = v.groups\n ? Object.keys(v.groups).map((gk) => {\n const roles = v.groups[gk] || [];\n return { group: { id: gk, name: v.group_names?.[gk] ?? 'unknown' }, roles };\n })\n : [];\n tnt.tenantRoles = tnt.groups?.find((g) => g.group.id === v.root_group_id);\n tenants.push(tnt);\n }\n return { raw, tenants };\n};\n","import { StorageManager } from '../storage-manager';\n\nimport { parseMembership } from './membership';\nimport { Token, TokenType } from './token';\n\nexport class TokenService {\n protected storageManager = new StorageManager();\n\n /**\n * Checks if a token is not exists or expired.\n *\n * @param {TokenType} ttype - The token type to check.\n * @returns {boolean} Returns true if the token is expired or not exists, false otherwise.\n */\n isTokenTypeExpired(ttype: TokenType): boolean {\n const tokenString = this.storageManager.getToken(ttype);\n if (!tokenString) return true;\n\n const token = parseToken(tokenString);\n return token ? isTokenExpired(token) : true;\n }\n\n /**\n * Parse token from storage by type.\n * Please be aware that this method does not check if the token signature and if the token is valid.\n *\n * @param {TokenType} tokenType - The token type to check.\n * @returns {Token | undefined} Returns token with parsed user membership or undefined.\n */\n parseTokenType(tokenType: TokenType): Token | undefined {\n const token = this.storageManager.getToken(tokenType);\n if (!token) return undefined;\n return parseToken(token);\n }\n}\n\n/**\n * Checks if a token is expired.\n *\n * @param {Token} token - The token to check.\n * @returns {boolean} Returns true if the token is expired, false otherwise.\n */\nexport function isTokenExpired(token: Token): boolean {\n const currentUnixTime = Math.floor(Date.now() / 1000);\n return currentUnixTime > token.exp;\n}\n\n/**\n * Parse token from string. Please be aware that this method does not check if the token signature and if the token is valid.\n *\n * @param {string} tokenString - The token string representation.\n * @returns {Token } Returns token with parsed user membership or undefined.\n */\nexport function parseToken(tokenString: string): Token {\n const base64Url = tokenString.split('.')[1];\n\n if (!base64Url) throw new Error('Invalid token string');\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n window\n .atob(base64)\n .split('')\n .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join(''),\n );\n\n const parsedToken = JSON.parse(jsonPayload) as Token;\n parsedToken.membership =\n parsedToken.passflow_tm && parsedToken.type !== 'invite' ? parseMembership(parsedToken.passflow_tm) : undefined;\n return parsedToken;\n}\n","import { RawUserMembership, UserMembership } from '../token-service/membership';\n\nexport type Token = {\n aud: string[];\n exp: number;\n iat: number;\n iss: string;\n jti: string;\n sub: string;\n type: string;\n email?: string;\n phonenumber?: string;\n passflow_tm?: RawUserMembership;\n payload?: unknown;\n membership?: UserMembership;\n};\n\nexport type InvitationToken = Token & {\n email: string;\n inviter_id: string;\n inviter_name: string;\n redirect_url: string;\n tenant_name: string;\n};\n\nexport enum TokenType {\n id_token = 'id_token',\n access_token = 'access',\n refresh_token = 'refresh',\n invite_token = 'invite',\n reset_token = 'reset',\n web_cookie = 'web-cookie',\n management = 'management',\n signin = 'signin',\n actor = 'actor',\n}\n","import { TokenType } from '../token-service';\nimport { Tokens } from '../types';\n\nexport type Storage = {\n setItem: (key: string, value: string) => void;\n getItem: (key: string) => string | null;\n removeItem: (key: string) => void;\n};\n\nexport interface StorageManagerParams {\n storage?: Storage;\n prefix?: string;\n}\n\nexport class StorageManager {\n private keyStoragePrefix = '';\n readonly scopes = `${this.keyStoragePrefix}tokens_scopes`;\n readonly deviceId = `${this.keyStoragePrefix}passflowDeviceId`;\n readonly invitationToken = `${this.keyStoragePrefix}passflowInvitationToken`;\n readonly previousRedirectUrl = `${this.keyStoragePrefix}passflowPreviousRedirectUrl`;\n\n private storage: Storage;\n\n constructor({ storage, prefix }: StorageManagerParams = {}) {\n this.storage = storage ?? localStorage;\n this.keyStoragePrefix = prefix ? `${prefix}_` : '';\n }\n\n saveTokens(tokens: Tokens): void {\n const { id_token, access_token, refresh_token, scopes } = tokens;\n if (id_token) this.storage.setItem(this.getKeyForTokenType(TokenType.id_token), id_token);\n if (access_token) this.storage.setItem(this.getKeyForTokenType(TokenType.access_token), access_token);\n if (refresh_token) this.storage.setItem(this.getKeyForTokenType(TokenType.refresh_token), refresh_token);\n if (scopes) this.storage.setItem(this.scopes, scopes.join(','));\n }\n\n getToken(tokenType: TokenType): string | undefined {\n const key = this.getKeyForTokenType(tokenType);\n return this.storage.getItem(key) ?? undefined;\n }\n\n getTokens(): Tokens | undefined {\n const access = this.storage.getItem(this.getKeyForTokenType(TokenType.access_token));\n if (!access) return undefined;\n return {\n access_token: access,\n id_token: this.storage.getItem(this.getKeyForTokenType(TokenType.id_token)) ?? undefined,\n refresh_token: this.storage.getItem(this.getKeyForTokenType(TokenType.refresh_token)) ?? undefined,\n scopes: this.storage.getItem(this.scopes)?.split(',') ?? undefined,\n };\n }\n\n getScopes(): string[] | undefined {\n return this.storage.getItem(this.scopes)?.split(',') ?? undefined;\n }\n\n deleteToken(tokenType: TokenType): void {\n const key = this.getKeyForTokenType(tokenType);\n this.storage.removeItem(key);\n }\n\n deleteTokens(): void {\n this.storage.removeItem(this.getKeyForTokenType(TokenType.id_token));\n this.storage.removeItem(this.getKeyForTokenType(TokenType.access_token));\n this.storage.removeItem(this.getKeyForTokenType(TokenType.refresh_token));\n this.storage.removeItem(this.scopes);\n }\n\n getDeviceId(): string | undefined {\n return this.storage.getItem(this.deviceId) ?? undefined;\n }\n\n setDeviceId(deviceId: string): void {\n this.storage.setItem(this.deviceId, deviceId);\n }\n\n deleteDeviceId(): void {\n this.storage.removeItem(this.deviceId);\n }\n\n setInvitationToken(token: string): void {\n this.storage.setItem(this.invitationToken, token);\n }\n\n getInvitationToken(): string | undefined {\n return this.storage.getItem(this.invitationToken) ?? undefined;\n }\n\n deleteInvitationToken(): void {\n this.storage.removeItem(this.invitationToken);\n }\n\n setPreviousRedirectUrl(url: string): void {\n this.storage.setItem(this.previousRedirectUrl, url);\n }\n\n getPreviousRedirectUrl(): string | undefined {\n return this.storage.getItem(this.previousRedirectUrl) ?? undefined;\n }\n\n deletePreviousRedirectUrl(): void {\n this.storage.removeItem(this.previousRedirectUrl);\n }\n\n private getKeyForTokenType(tokenType: TokenType): string {\n return `${this.keyStoragePrefix}${tokenType}`;\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\n\nimport { StorageManager } from '../storage-manager';\n\nexport class DeviceService {\n private storageManager: StorageManager;\n\n constructor() {\n this.storageManager = new StorageManager();\n }\n\n getDeviceId(): string {\n const deviceId = this.storageManager.getDeviceId();\n if (!deviceId) {\n const newDeviceId = this.generateUniqueDeviceId();\n this.storageManager.setDeviceId(newDeviceId);\n return newDeviceId;\n }\n return deviceId;\n }\n\n generateUniqueDeviceId(): string {\n return uuidv4();\n }\n}\n","import type {\n AuthenticationResponseJSON,\n PublicKeyCredentialCreationOptionsJSON,\n RegistrationResponseJSON,\n} from '@simplewebauthn/types';\nimport type { AxiosRequestConfig } from 'axios';\n\nimport type { Tokens } from '../types';\n\nexport type RequestOptions<D> = {\n data?: D;\n config?: AxiosRequestConfig;\n};\n\nexport enum RequestMethod {\n GET = 'get',\n POST = 'post',\n PUT = 'put',\n PATCH = 'patch',\n DELETE = 'delete',\n}\n\nexport enum PassflowEndpointPaths {\n signin = '/auth/login',\n signup = '/auth/register',\n signInWithProvider = '/auth/federated/start/',\n passwordless = '/auth/passwordless/start',\n passwordlessComplete = '/auth/passwordless/complete',\n logout = '/user/logout',\n refresh = '/auth/refresh',\n sendPasswordResetEmail = '/auth/password/reset',\n resetPassword = '/auth/password/change',\n appSettings = '/app/settings',\n passkeyRegisterStart = '/auth/passkey/register/start',\n passkeyRegisterComplete = '/auth/passkey/register/complete',\n passkeyAuthenticateStart = '/auth/passkey/authenticate/start',\n passkeyAuthenticateComplete = '/auth/passkey/authenticate/complete',\n passkeyValidate = '/auth/validate',\n settingsAll = '/settings',\n settingsPasswordPolicy = '/settings/password',\n settingsPasskey = '/settings/passkey',\n userPasskey = '/user/passkey',\n addUserPasskey = `${PassflowEndpointPaths.userPasskey}/add/start`,\n completeAddUserPasskey = `${PassflowEndpointPaths.userPasskey}/add/complete`,\n joinInvitation = '/user/tenant/join',\n tenantPath = '/user/tenant',\n invitationsPath = '/user/tenant/:tenantID/invitations',\n requestInvitation = '/user/invite',\n invitationDelete = '/user/invite/:invitationID',\n invitationResend = '/user/invite/:invitationID/resend',\n invitationGetLink = '/user/invite/:invitationID/link',\n}\n\nexport enum PassflowAdminEndpointPaths {\n passkeyRegisterStart = '/admin/auth/passkey/register/start',\n passkeyRegisterComplete = '/admin/auth/passkey/register/complete',\n passkeyAuthenticateStart = '/admin/auth/passkey/authenticate/start',\n passkeyAuthenticateComplete = '/admin/auth/passkey/authenticate/complete',\n passkeyValidate = '/admin/auth/validate',\n logout = '/admin/auth/logout',\n}\n\nexport type PassflowConfig = {\n url?: string;\n appId?: string;\n scopes?: string[];\n createTenantForNewUser?: boolean;\n parseQueryParams?: boolean;\n keyStoragePrefix?: string;\n};\n\nexport type PassflowAuthorizationResponse = Tokens;\n\nexport type PassflowValidationResponse = Tokens & {\n redirect_url: string;\n};\n\nexport type PassflowSuccessResponse = {\n result: 'ok';\n};\n\nexport type PassflowLogoutResponse = {\n status: 'ok';\n};\n\nexport type PassflowResponseError = {\n error: {\n id: string;\n message: string;\n status: number;\n location: string;\n time: string;\n };\n};\n\nexport class PassflowError extends Error {\n id: string;\n message: string;\n status: number;\n location: string;\n time: string;\n\n constructor(error: PassflowResponseError['error']) {\n super();\n this.id = error?.id ?? 'unknown';\n this.message = error?.message ?? error ?? 'Something went wrong';\n this.status = error?.status ?? 500;\n this.location = error?.location ?? 'unknown';\n this.time = error?.time ?? new Date().toISOString();\n }\n}\n\nexport type PassflowSignInPayload = {\n password: string;\n scopes?: string[];\n email?: string;\n phone?: string;\n username?: string;\n invite_token?: string;\n} & ({ email: string } | { phone: string } | { username: string });\n\nexport type PassflowSignInExtendedPayload = PassflowSignInPayload & {\n device: string;\n os: OS;\n};\n\nexport type PassflowAddressPayload = {\n formatted?: string;\n street_address?: string;\n locality?: string;\n region?: string;\n postal_code?: string;\n country?: string;\n};\n\nexport type PassflowUserPayload = {\n password: string;\n username?: string;\n email?: string;\n given_name?: string;\n family_name?: string;\n middle_name?: string;\n nickname?: string;\n preferred_username?: string;\n phone_number?: string;\n profile?: string;\n picture?: string;\n website?: string;\n gender?: string;\n birthday?: Date;\n timezone?: string;\n locale?: string;\n addresses?: PassflowAddressPayload;\n} & ({ email: string } | { phone_number: string });\n\nexport type PassflowSignUpPayload = {\n user: PassflowUserPayload;\n scopes?: string[];\n create_tenant?: boolean;\n anonymous?: boolean;\n invite_token?: string;\n};\n\nexport type PassflowPasswordlessSignInPayload = {\n challenge_type: InternalStrategyChallenge;\n redirect_url: string;\n scopes?: string[];\n create_tenant?: boolean;\n email?: string;\n phone?: string;\n invite_token?: string;\n} & ({ email: string } | { phone: string });\n\nexport type PassflowPasswordlessResponse = {\n challenge_id: string;\n expires_at: Date | string;\n};\n\nexport type PassflowPasswordlessSignInExtendedPayload = PassflowPasswordlessSignInPayload & {\n device: string;\n os: OS;\n};\n\nexport type PassflowPasswordlessSignInCompletePayload = {\n challenge_id: string;\n otp: string;\n device?: string;\n scopes?: string[];\n challenge_type?: InternalStrategyChallenge;\n};\n\nexport enum Providers {\n google = 'google',\n facebook = 'facebook',\n}\n\nexport type FimStrategy = {\n fim_type: Providers;\n};\n\nexport type InternalStrategyIdentity = 'id' | 'email' | 'phone' | 'username' | 'anonymous' | 'none';\nexport type InternalStrategyChallenge = 'password' | 'otp' | 'magic_link' | 'recovery_codes' | 'guardian' | 'none';\nexport type InternalStrategyTransport = 'email' | 'sms' | 'push' | 'socket' | 'authenticator' | 'none';\n\nexport type InternalStrategy = {\n identity: InternalStrategyIdentity;\n challenge: InternalStrategyChallenge;\n transport: InternalStrategyTransport;\n};\n\nexport type OtherStrategy = Record<string, never>;\n\nexport type AuthTypeStrategy = 'internal' | 'passkey' | 'webauthn' | 'fim' | 'pkce' | 'anonymous';\n\nexport type AuthStrategies =\n | { type: Extract<AuthTypeStrategy, 'internal'>; strategy: InternalStrategy }\n | { type: Extract<AuthTypeStrategy, 'fim'>; strategy: FimStrategy }\n | {\n type: Exclude<AuthTypeStrategy, 'internal' | 'fim'>;\n strategy: OtherStrategy;\n };\n\nexport type AppType = 'web' | 'android' | 'ios' | 'desktop' | 'other';\n\nexport type AppSettings = {\n id: string;\n secret: string;\n active: boolean;\n name: string;\n description: string;\n offline: boolean;\n type: AppType;\n redirect_urls: string[] | null;\n origins: string[] | null;\n custom_email_templates: boolean;\n auth_strategies: AuthStrategies[];\n force_passwordless_login: boolean;\n pkce_enabled: boolean;\n custom_sms_messages: boolean;\n registration_allowed: boolean;\n invite_only_registration: boolean;\n passwordless_registration_allowed: boolean;\n anonymous_registration_allowed: boolean;\n create_tenant_on_registration: 'never' | 'always' | 'optional';\n fim_merge_by_email_allowed: boolean;\n debug_otp_code_allowed: boolean;\n debug_otp_code_for_registration: string;\n defaults: DefaultAppSettings;\n login_app_theme: LoginWebAppTheme;\n login_app_settings?: unknown;\n};\n\nexport type DefaultAppSettings = {\n app_id: string;\n redirect: string;\n scopes: string[];\n create_tenant_for_new_user: boolean;\n};\n\nexport enum OS {\n web = 'web',\n}\n\nexport type PassflowPasskeyRegisterStartPayload = {\n passkey_display_name?: string;\n passkey_username?: string;\n invite_token?: string;\n\n scopes: string[];\n create_tenant?: boolean;\n\n relying_party_id: string;\n redirect_url: string;\n};\n\nexport type PassflowPasskeyRegisterStartExtendedPayload = PassflowPasskeyRegisterStartPayload & {\n device: string;\n os: OS;\n};\n\nexport type PassflowPasskeyStart = {\n challenge_id: string;\n publicKey: PublicKeyCredentialCreationOptionsJSON;\n};\n\nexport type PassflowPasskeyCompleteMessageWithTokens = Tokens;\n\nexport type PassflowPasskeyPayload = {\n device: string;\n challenge_id: string;\n};\n\nexport type PassflowPasskeyRegisterPayload = PassflowPasskeyPayload & {\n passkey_data: RegistrationResponseJSON;\n};\n\nexport type PassflowPasskeyAuthenticatePayload = PassflowPasskeyPayload & {\n passkey_data: AuthenticationResponseJSON;\n};\n\nexport type PassflowPasskeyAuthenticateStartPayload = {\n relying_party_id: string;\n scopes?: string[];\n user_id?: string;\n invite_token?: string;\n};\n\nexport type PassflowPasskeyAuthenticateStartExtendedPayload = PassflowPasskeyAuthenticateStartPayload & {\n device: string;\n os: OS;\n};\n\nexport type PassflowFederatedAuthPayload = {\n provider: Providers;\n redirect_url: string;\n scopes?: string[];\n invite_token?: string;\n create_tenant?: boolean;\n};\n\nexport type PassflowFederatedAuthExtendedPayload = PassflowFederatedAuthPayload & {\n device?: string;\n};\n\nexport type PassflowValidatePayload = {\n otp: string;\n device: string;\n challenge_id: string;\n};\n\n// SETTINGS\nexport type PassflowPasskeyProviderOption = 'none' | 'required' | 'preferred' | 'discouraged';\n\nexport type PassflowSettingsAll = {\n password_policy: PassflowPasswordPolicySettings;\n passkey_provider: PassflowPasskeySettings;\n};\n\nexport type PassflowPasswordPolicySettings = {\n restrict_min_password_length: boolean;\n min_password_length: number;\n reject_compromised: boolean;\n enforce_password_strength: 'none' | 'weak' | 'average' | 'strong';\n require_lowercase: boolean;\n require_uppercase: boolean;\n require_number: boolean;\n require_symbol: boolean;\n};\n\nexport type PassflowPasskeySettings = {\n // name: string;\n id: string;\n display_name: string;\n // id_field: 'email' | 'phone' | 'username';\n // validation: InternalStrategyChallenge;\n registration?: {\n user_verification: PassflowPasskeyProviderOption;\n authenticator_attachment: 'platform' | 'cross-platform' | 'any';\n discoverable_key: PassflowPasskeyProviderOption;\n attestation_metadata: PassflowPasskeyProviderOption;\n extensions: unknown;\n };\n authentication?: {\n user_verification: PassflowPasskeyProviderOption;\n attestation_metadata: PassflowPasskeyProviderOption;\n extensions: unknown;\n };\n};\n\ntype PassflowCredentialFlags = {\n user_present: boolean;\n user_verified: boolean;\n backup_eligible: boolean;\n backup_state: boolean;\n};\n\ntype PassflowEnrolmentAuthenticator = {\n aaguid: string;\n sign_count: number;\n clone_warning: boolean;\n attachment: 'platform' | 'cross-platform';\n};\n\nexport type PassflowUserPasskey = {\n id: string;\n user_id: string;\n name: string;\n strategy: InternalStrategy;\n challenge_type: InternalStrategyChallenge;\n strategy_hash: string;\n enrolled_at: Date | string;\n enrollment_challenge_id: string;\n confirmed_at: Date | string;\n last_auth_at: Date | string;\n public_key: string;\n attestation_type: string;\n transport: string[];\n flags: PassflowCredentialFlags;\n authenticator: PassflowEnrolmentAuthenticator;\n archived: boolean;\n archived_at: Date | string;\n count?: number;\n enrolled_with_app_id?: string;\n};\n\nexport type PassflowSendPasswordResetEmailPayload = {\n email?: string;\n phone?: string;\n username?: string;\n reset_page_url?: string;\n redirect_url?: string;\n} & ({ email: string } | { phone: string } | { username: string });\n\nexport type PassflowInviteResponse = {\n link: string;\n};\n\nexport type PassflowInvitePayload = {\n invite_token: string;\n scopes: string[];\n};\n\nexport type PassflowUserWithRoles = {\n user_id: string;\n username: string;\n email: string;\n phone_number: string;\n tenant_id: string;\n group_id: string;\n role_id: string;\n preferred_username?: string;\n given_name?: string;\n family_name?: string;\n nickname?: string;\n picture?: string;\n roles: {\n [role_id: string]: string; // Maps role_id to role_name\n };\n};\n\nexport type PassflowGroup = {\n id: string;\n name: string;\n default: boolean;\n updated_at: string;\n created_at: string;\n};\n\nexport type PassflowRole = {\n id: string;\n tenant_id: string;\n name: string;\n};\n\nexport type PassflowTenantResponse = {\n tenant_id: string;\n tenant_name: string;\n users_in_groups?: PassflowUserInGroup[];\n groups?: PassflowGroup[];\n roles?: PassflowRole[];\n};\n\n/**\n * Represents a user's membership in a group with their assigned roles\n */\nexport type PassflowUserInGroup = {\n user: {\n id: string;\n name?: string | null;\n email?: string | null;\n phone?: string | null;\n };\n group_id: string;\n roles?: {\n id: string;\n }[];\n};\n\nexport type PassflowCreateTenantPayload = {\n name: string;\n};\n\nexport type LoginWebAppTemplateType = 'default' | 'simple' | 'extendable';\n\nexport type LoginWebAppTemplateColorScheme = 'system' | 'light' | 'dark';\n\nexport type LoginWebAppStyle = {\n primary_color: string;\n text_color: string;\n secondary_text_color: string;\n background_color: string;\n card_color: string;\n input_background_color: string;\n input_border_color: string;\n button_text_color: string;\n divider_color: string;\n federated_button_background_color: string;\n federated_button_text_color: string;\n logo_url: string;\n passkey_button_background_color: string;\n passkey_button_text_color: string;\n background_image: string;\n custom_css: string;\n};\n\nexport type LoginWebAppTheme = {\n template_type: LoginWebAppTemplateType;\n application_name: string;\n remove_passflow_logo: boolean;\n description: string;\n color_scheme: LoginWebAppTemplateColorScheme;\n light_style: LoginWebAppStyle;\n dark_style: LoginWebAppStyle;\n};\n\nexport type PassflowCreateTokenResponse = PassflowTenantResponse;\n\n// Helper function to create paths with parameters\nexport function pathWithParams(template: string, params: Record<string, string>): string {\n let result = template;\n Object.entries(params).forEach(([key, value]) => {\n result = result.replace(`:${key}`, value);\n });\n return result;\n}\n\n// Usage example:\n// const invitationsUrl = pathWithParams(PassflowEndpointPaths.invitationsPath, { tenantID: '123' });\n","import {\n APP_ID_HEADER_KEY,\n AUTHORIZATION_HEADER_KEY,\n DEVICE_ID_HEADER_KEY,\n DEVICE_TYPE_HEADER_KEY,\n PASSFLOW_CLOUD_URL,\n} from '../constants';\n\nimport axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';\n\nimport { DeviceService } from '../device-service';\nimport { StorageManager } from '../storage-manager';\nimport { TokenService, isTokenExpired, parseToken } from '../token-service';\n\nimport {\n PassflowAuthorizationResponse,\n PassflowConfig,\n PassflowEndpointPaths,\n PassflowError,\n PassflowResponseError,\n RequestMethod,\n RequestOptions,\n} from './model';\n\nexport enum HttpStatuses {\n badRequest = 400,\n unauthorized = 401,\n internalServerError = 500,\n success = 200,\n created = 201,\n}\n\nexport class AxiosClient {\n private instance: AxiosInstance;\n protected storageManager: StorageManager;\n protected deviceService: DeviceService;\n private refreshPromise: Promise<AxiosResponse<PassflowAuthorizationResponse>> | null = null;\n\n tokenService: TokenService;\n\n origin = window.location.origin;\n url: string;\n appId?: string;\n\n protected defaultHeaders: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n };\n\n private readonly nonAccessTokenEndpoints = ['/auth/', '/settings', '/settings/'];\n private readonly protectedEndpoints = ['logout', 'refresh'];\n\n constructor(config: PassflowConfig) {\n const { url, appId, keyStoragePrefix } = config;\n\n this.url = url || PASSFLOW_CLOUD_URL;\n\n this.storageManager = new StorageManager({\n prefix: keyStoragePrefix ?? '',\n });\n this.deviceService = new DeviceService();\n this.tokenService = new TokenService();\n\n if (appId) {\n this.appId = appId;\n\n this.defaultHeaders = {\n ...this.defaultHeaders,\n [APP_ID_HEADER_KEY]: appId,\n };\n }\n\n // Add device headers\n const deviceId = this.deviceService.getDeviceId();\n this.defaultHeaders = {\n ...this.defaultHeaders,\n [DEVICE_ID_HEADER_KEY]: deviceId,\n [DEVICE_TYPE_HEADER_KEY]: 'web',\n };\n\n this.instance = axios.create({\n baseURL: this.url,\n headers: { ...this.defaultHeaders },\n });\n\n this.instance.interceptors.request.use(async (axiosConfig: InternalAxiosRequestConfig) => {\n // Request to non-access token endpoints\n if (this.isNonAuthEndpoint(axiosConfig.url)) {\n return axiosConfig;\n }\n\n // Request to refresh token endpoint\n if (axiosConfig.url?.includes('refresh')) {\n if (this.refreshPromise) {\n const controller = new AbortController();\n controller.abort();\n axiosConfig.signal = controller.signal;\n return axiosConfig;\n }\n return axiosConfig;\n }\n\n // Request to access token endpoints\n const tokens = this.storageManager.getTokens();\n const scopes = this.storageManager.getScopes();\n\n if (tokens?.access_token) {\n const access = parseToken(tokens.access_token);\n\n if (isTokenExpired(access) && tokens.refresh_token) {\n try {\n if (this.refreshPromise) {\n const response = await this.refreshPromise;\n if (response.data) {\n axiosConfig.headers[AUTHORIZATION_HEADER_KEY] = `Bearer ${response.data.access_token}`;\n }\n return axiosConfig;\n }\n\n const payload = {\n refresh_token: tokens.refresh_token,\n scopes,\n };\n\n this.refreshPromise = this.instance.post<PassflowAuthorizationResponse>(PassflowEndpointPaths.refresh, payload, {\n headers: {\n [AUTHORIZATION_HEADER_KEY]: `Bearer ${tokens.refresh_token}`,\n },\n });\n\n const response = await this.refreshPromise;\n\n if (response.data) {\n this.storageManager.saveTokens(response.data);\n axiosConfig.headers[AUTHORIZATION_HEADER_KEY] = `Bearer ${response.data.access_token}`;\n }\n\n return axiosConfig;\n } catch (error) {\n this.refreshPromise = null;\n return Promise.reject(error);\n } finally {\n this.refreshPromise = null;\n }\n }\n\n axiosConfig.headers[AUTHORIZATION_HEADER_KEY] = `Bearer ${tokens.access_token}`;\n\n return axiosConfig;\n }\n return axiosConfig;\n });\n\n this.instance.interceptors.response.use(\n (response: AxiosResponse) => response,\n (e: AxiosError) => this.handleAxiosError(e),\n );\n }\n\n private isProtectedEndpoint(url?: string): boolean {\n return this.protectedEndpoints.some((endpoint) => url?.includes(endpoint));\n }\n\n private isNonAuthEndpoint(url?: string): boolean {\n return this.nonAccessTokenEndpoints.some((endpoint) => url?.includes(endpoint)) && !this.isProtectedEndpoint(url);\n }\n\n // eslint-disable-next-line complexity\n // biome-ignore lint/suspicious/useAwait: <explanation>\n private async handleAxiosError(e: AxiosError): Promise<unknown> {\n // Handle network\n if (!e.response) {\n return Promise.reject(e);\n }\n\n const status = e.response.status as HttpStatuses;\n const errorData = e.response.data as Record<string, unknown>;\n\n // If we have a response with error data in Passflow format\n if ('error' in errorData && typeof errorData.error === 'object' && errorData.error !== null) {\n const { error } = errorData as PassflowResponseError;\n\n return Promise.reject(new PassflowError(error));\n }\n\n // For non-Passflow format errors, create a generic PassflowError\n return Promise.reject(\n new PassflowError({\n id: `error.http.${status}`,\n message: e.message || 'An error occurred',\n status: status,\n location: e.config?.url || 'unknown',\n time: new Date().toISOString(),\n }),\n );\n }\n\n private async send<T, D>(method: RequestMethod, path: string, options?: RequestOptions<D>): Promise<T> {\n const response = await this.instance.request<T>({\n method,\n url: path,\n ...options,\n });\n return response.data;\n }\n\n get<T>(path: string, config?: AxiosRequestConfig): Promise<T> {\n return this.send(RequestMethod.GET, path, config);\n }\n\n post<T, D>(path: string, data?: D, config?: AxiosRequestConfig): Promise<T> {\n return this.send(RequestMethod.POST, path, { data, ...config });\n }\n\n put<T, D>(path: string, data?: D, config?: AxiosRequestConfig): Promise<T> {\n return this.send(RequestMethod.PUT, path, { data, ...config });\n }\n\n patch<T, D>(path: string, data?: D, config?: AxiosRequestConfig): Promise<T> {\n return this.send(RequestMethod.PATCH, path, { data, ...config });\n }\n\n delete<T>(path: string, config?: AxiosRequestConfig): Promise<T> {\n return this.send(RequestMethod.DELETE, path, config);\n }\n}\n","import { AuthenticationResponseJSON, RegistrationResponseJSON } from '@simplewebauthn/types';\nimport { APP_ID_HEADER_KEY, AUTHORIZATION_HEADER_KEY } from '../constants';\n\nimport { StorageManager } from '../storage-manager';\n\nimport { AxiosClient } from './axios-client';\nimport {\n OS,\n PassflowAdminEndpointPaths,\n PassflowAuthorizationResponse,\n PassflowConfig,\n PassflowEndpointPaths,\n PassflowLogoutResponse,\n PassflowPasskeyAuthenticatePayload,\n PassflowPasskeyAuthenticateStartExtendedPayload,\n PassflowPasskeyAuthenticateStartPayload,\n PassflowPasskeyRegisterPayload,\n PassflowPasskeyRegisterStartExtendedPayload,\n PassflowPasskeyRegisterStartPayload,\n PassflowPasskeyStart,\n PassflowPasswordlessResponse,\n PassflowPasswordlessSignInCompletePayload,\n PassflowPasswordlessSignInExtendedPayload,\n PassflowPasswordlessSignInPayload,\n PassflowSendPasswordResetEmailPayload,\n PassflowSignInExtendedPayload,\n PassflowSignInPayload,\n PassflowSignUpPayload,\n PassflowSuccessResponse,\n PassflowValidatePayload,\n PassflowValidationResponse,\n} from './model';\n\nexport class AuthAPI {\n protected axiosClient: AxiosClient;\n protected storageManager = new StorageManager();\n\n constructor(config: PassflowConfig) {\n this.axiosClient = new AxiosClient(config);\n }\n\n refreshToken(refreshToken: string, scopes: string[], accessToken?: string): Promise<PassflowAuthorizationResponse> {\n const payload = {\n access: accessToken,\n scopes,\n };\n\n return this.axiosClient.post<PassflowAuthorizationResponse, typeof payload>(PassflowEndpointPaths.refresh, payload, {\n headers: {\n [AUTHORIZATION_HEADER_KEY]: `Bearer ${refreshToken}`,\n },\n });\n }\n\n signIn(payload: PassflowSignInPayload, deviceId: string, os: OS): Promise<PassflowAuthorizationResponse> {\n const defaultPayload: PassflowSignInExtendedPayload = {\n ...payload,\n device: deviceId,\n os,\n };\n return this.axiosClient.post<PassflowAuthorizationResponse, PassflowSignInExtendedPayload>(\n PassflowEndpointPaths.signin,\n defaultPayload,\n );\n }\n\n signUp(payload: PassflowSignUpPayload): Promise<PassflowAuthorizationResponse> {\n const { create_tenant, anonymous } = payload;\n const defaultPayload: PassflowSignUpPayload = {\n ...payload,\n create_tenant: create_tenant ?? false,\n anonymous: anonymous ?? false,\n };\n return this.axiosClient.post<PassflowAuthorizationResponse, PassflowSignUpPayload>(\n PassflowEndpointPaths.signup,\n defaultPayload,\n );\n }\n\n passwordlessSignIn(\n payload: PassflowPasswordlessSignInPayload,\n deviceId: string,\n os: OS,\n ): Promise<PassflowPasswordlessResponse> {\n const { create_tenant } = payload;\n const defaultPayload: PassflowPasswordlessSignInExtendedPayload = {\n ...payload,\n create_tenant: create_tenant ?? false,\n device: deviceId,\n os,\n };\n return this.axiosClient.post<PassflowPasswordlessResponse, PassflowPasswordlessSignInExtendedPayload>(\n PassflowEndpointPaths.passwordless,\n defaultPayload,\n );\n }\n\n passwordlessSignInComplete(payload: PassflowPasswordlessSignInCompletePayload): Promise<PassflowValidationResponse> {\n return this.axiosClient.post<PassflowValidationResponse, PassflowPasswordlessSignInCompletePayload>(\n PassflowEndpointPaths.passwordlessComplete,\n payload,\n );\n }\n\n logOut(deviceId?: string, refreshToken?: string, isAdmin = false): Promise<PassflowLogoutResponse> {\n const payload = !isAdmin ? { refresh_token: refreshToken, device: deviceId } : undefined;\n const endpoint = isAdmin ? PassflowAdminEndpointPaths.logout : PassflowEndpointPaths.logout;\n\n return this.axiosClient.post<PassflowLogoutResponse, typeof payload>(endpoint, payload);\n }\n\n sendPasswordResetEmail(payload: PassflowSendPasswordResetEmailPayload): Promise<PassflowSuccessResponse> {\n return this.axiosClient.post<PassflowSuccessResponse, typeof payload>(\n PassflowEndpointPaths.sendPasswordResetEmail,\n payload,\n );\n }\n\n resetPassword(newPassword: string, scopes: string[], resetToken?: string): Promise<PassflowAuthorizationResponse> {\n const payload = {\n password: newPassword,\n scopes,\n };\n\n return this.axiosClient.post<PassflowAuthorizationResponse, typeof payload>(PassflowEndpointPaths.resetPassword, payload, {\n headers: {\n [AUTHORIZATION_HEADER_KEY]: `Bearer ${resetToken}`,\n [APP_ID_HEADER_KEY]: undefined,\n },\n });\n }\n\n passkeyRegisterStart(\n payload: PassflowPasskeyRegisterStartPayload,\n deviceId: string,\n os: OS,\n isAdmin = false,\n ): Promise<PassflowPasskeyStart> {\n const { create_tenant } = payload;\n const defaultPayload: PassflowPasskeyRegisterStartExtendedPayload = {\n ...payload,\n create_tenant: create_tenant ?? false,\n device: deviceId,\n os,\n };\n\n const endpoint = isAdmin ? PassflowAdminEndpointPaths.passkeyRegisterStart : PassflowEndpointPaths.passkeyRegisterStart;\n\n return this.axiosClient.post<PassflowPasskeyStart, PassflowPasskeyRegisterStartExtendedPayload>(endpoint, defaultPayload);\n }\n\n passkeyRegisterComplete(\n passkeyData: RegistrationResponseJSON,\n deviceId: string,\n challengeId: string,\n isAdmin = false,\n ): Promise<PassflowAuthorizationResponse> {\n const payload: PassflowPasskeyRegisterPayload = {\n challenge_id: challengeId,\n device: deviceId,\n passkey_data: passkeyData,\n };\n\n const endpoint = isAdmin\n ? PassflowAdminEndpointPaths.passkeyRegisterComplete\n : PassflowEndpointPaths.passkeyRegisterComplete;\n\n return this.axiosClient.post<PassflowAuthorizationResponse, PassflowPasskeyRegisterPayload>(endpoint, payload);\n }\n\n passkeyAuthenticateStart(\n payload: PassflowPasskeyAuthenticateStartPayload,\n deviceId: string,\n os: OS,\n isAdmin = false,\n ): Promise<PassflowPasskeyStart> {\n const defaultPayload: PassflowPasskeyAuthenticateStartExtendedPayload = {\n ...payload,\n user_id: payload.user_id ?? '',\n device: deviceId,\n os,\n };\n\n const endpoint = isAdmin\n ? PassflowAdminEndpointPaths.passkeyAuthenticateStart\n : PassflowEndpointPaths.passkeyAuthenticateStart;\n\n return this.axiosClient.post<PassflowPasskeyStart, PassflowPasskeyAuthenticateStartExtendedPayload>(\n endpoint,\n defaultPayload,\n );\n }\n\n passkeyAuthenticateComplete(\n passkeyData: AuthenticationResponseJSON,\n deviceId: string,\n challengeId: string,\n isAdmin = false,\n ): Promise<PassflowAuthorizationResponse> {\n const payload: PassflowPasskeyAuthenticatePayload = {\n challenge_id: challengeId,\n device: deviceId,\n passkey_data: passkeyData,\n };\n\n const endpoint = isAdmin\n ? PassflowAdminEndpointPaths.passkeyAuthenticateComplete\n : PassflowEndpointPaths.passkeyAuthenticateComplete;\n\n return this.axiosClient.post<PassflowAuthorizationResponse, PassflowPasskeyAuthenticatePayload>(endpoint, payload);\n }\n\n passkeyValidate(\n otp: string,\n deviceId: string,\n challengeId: string,\n isAdmin = false,\n appId?: string,\n ): Promise<PassflowValidationResponse> {\n const payload: PassflowValidatePayload = {\n otp,\n device: deviceId,\n challenge_id: challengeId,\n };\n\n let endpoint: PassflowEndpointPaths.passkeyValidate | PassflowAdminEndpointPaths.passkeyValidate =\n PassflowEndpointPaths.passkeyValidate;\n if (!appId && isAdmin) {\n endpoint = PassflowAdminEndpointPaths.passkeyValidate;\n }\n\n const headers = appId ? { [APP_ID_HEADER_KEY]: appId } : {};\n\n return this.axiosClient.post<PassflowValidationResponse, PassflowValidatePayload>(endpoint, payload, { headers });\n }\n}\n","import { AxiosClient } from './axios-client';\nimport { type AppSettings, type PassflowConfig, PassflowEndpointPaths } from './model';\n\nexport class AppAPI {\n protected axiosClient: AxiosClient;\n\n constructor(config: PassflowConfig) {\n this.axiosClient = new AxiosClient(config);\n }\n\n getAppSettings(): Promise<AppSettings> {\n return this.axiosClient.get<AppSettings>(PassflowEndpointPaths.appSettings);\n }\n}\n","import { AxiosClient } from './axios-client';\nimport {\n type PassflowConfig,\n PassflowEndpointPaths,\n type PassflowPasskeySettings,\n type PassflowPasswordPolicySettings,\n type PassflowSettingsAll,\n} from './model';\n\nexport class SettingAPI {\n protected axiosClient: AxiosClient;\n\n constructor(config: PassflowConfig) {\n this.axiosClient = new AxiosClient(config);\n }\n\n getSettingsAll(): Promise<PassflowSettingsAll> {\n return this.axiosClient.get<PassflowSettingsAll>(PassflowEndpointPaths.settingsAll);\n }\n\n getPasswordPolicySettings(): Promise<PassflowPasswordPolicySettings> {\n return this.axiosClient.get<PassflowPasswordPolicySettings>(PassflowEndpointPaths.settingsPasswordPolicy);\n }\n\n getPasskeySettings(): Promise<PassflowPasskeySettings> {\n return this.axiosClient.get<PassflowPasskeySettings>(PassflowEndpointPaths.settingsPasskey);\n }\n}\n","import { RegistrationResponseJSON } from '@simplewebauthn/types';\n\nimport { AxiosClient } from './axios-client';\nimport {\n OS,\n PassflowConfig,\n PassflowEndpointPaths,\n PassflowPasskeyRegisterPayload,\n PassflowPasskeyStart,\n PassflowSuccessResponse,\n PassflowUserPasskey,\n} from './model';\n\nexport class UserAPI {\n protected axiosClient: AxiosClient;\n\n constructor(config: PassflowConfig) {\n this.axiosClient = new AxiosClient(config);\n }\n\n getUserPasskeys() {\n return this.axiosClient.get<PassflowUserPasskey[]>(PassflowEndpointPaths.userPasskey);\n }\n\n renameUserPasskey(name: string, passkeyId: string): Promise<PassflowSuccessResponse> {\n return this.axiosClient.patch<PassflowSuccessResponse, { name: string }>(\n `${PassflowEndpointPaths.userPasskey}/${passkeyId}`,\n {\n name,\n },\n );\n }\n\n deleteUserPasskey(passkeyId: string): Promise<PassflowSuccessResponse> {\n return this.axiosClient.delete<PassflowSuccessResponse>(`${PassflowEndpointPaths.userPasskey}/${passkeyId}`);\n }\n\n addUserPasskeyStart({\n relyingPartyId,\n deviceId,\n os,\n passkeyDisplayName,\n passkeyUsername,\n }: {\n relyingPartyId: string;\n deviceId: string;\n os: OS;\n passkeyDisplayName?: string;\n passkeyUsername?: string;\n }): Promise<PassflowPasskeyStart> {\n const payload = {\n passkey_display_name: passkeyDisplayName,\n passkey_username: passkeyUsername,\n relying_party_id: relyingPartyId,\n deviceId,\n os,\n };\n\n return this.axiosClient.post<PassflowPasskeyStart, typeof payload>(PassflowEndpointPaths.addUserPasskey, payload);\n }\n\n addUserPasskeyComplete(passkeyData: RegistrationResponseJSON, deviceId: string, challengeId: string): Promise<void> {\n return this.axiosClient.post<void, PassflowPasskeyRegisterPayload>(PassflowEndpointPaths.completeAddUserPasskey, {\n challenge_id: challengeId,\n device: deviceId,\n passkey_data: passkeyData,\n });\n }\n}\n","import { AxiosClient } from './axios-client';\nimport {\n PassflowAuthorizationResponse,\n PassflowConfig,\n PassflowCreateTenantPayload,\n PassflowEndpointPaths,\n PassflowInvitePayload,\n PassflowTenantResponse,\n} from './model';\n\n// Response types\nexport type PassflowStatusResponse = {\n status: string;\n};\n\nexport type PassflowGroupResponse = {\n id: string;\n name: string;\n default?: boolean;\n updated_at: string;\n created_at: string;\n};\n\nexport type PassflowRoleResponse = {\n id: string;\n tenant_id: string;\n name: string;\n};\n\nexport type PassflowUserTenantMembershipResponse = Record<\n string, // tenant_id\n {\n tenant_id: string;\n tenant_name: string;\n groups: Record<string, string[]>; // group_id -> role_ids[]\n group_names: Record<string, string>; // group_id -> group_name\n }\n>;\n\nexport type PassflowInvitationItem = {\n id: string;\n archived: boolean;\n app_id: string;\n inviter_id: string;\n inviter_name: string;\n token: string;\n email: string;\n role: string;\n tenant: string;\n tenant_name: string;\n group: string;\n created_by: string;\n created_at: string;\n expires_at: string;\n};\n\nexport type PassflowInvitationsResponse = {\n invites: PassflowInvitationItem[];\n next_page_skip: string;\n};\n\n// Request payload types\nexport type PassflowUpdateTenantPayload = {\n name: string;\n};\n\nexport type PassflowCreateGroupPayload = {\n name: string;\n};\n\nexport type PassflowUpdateGroupPayload = {\n name: string;\n};\n\nexport type PassflowAddUserToGroupPayload = {\n user_id: string;\n role: string;\n};\n\nexport type PassflowRemoveUserRolesPayload = {\n user_id: string;\n roles: string[];\n};\n\nexport type PassflowChangeUserRolesPayload = {\n user_id: string;\n roles: string[];\n};\n\nexport type PassflowCreateRolePayload = {\n name: string;\n};\n\nexport type PassflowUpdateRolePayload = {\n name: string;\n};\n\nexport class TenantAPI {\n protected axiosClient: AxiosClient;\n\n constructor(config: PassflowConfig) {\n this.axiosClient = new AxiosClient(config);\n }\n\n joinInvitation(token: string, scopes: string[]): Promise<PassflowAuthorizationResponse> {\n const payload = {\n invite_token: token,\n scopes,\n };\n\n return this.axiosClient.post<PassflowAuthorizationResponse, PassflowInvitePayload>(\n PassflowEndpointPaths.joinInvitation,\n payload,\n );\n }\n\n createTenant(name: string): Promise<PassflowTenantResponse> {\n const payload = {\n name,\n };\n return this.axiosClient.post<PassflowTenantResponse, PassflowCreateTenantPayload>(\n PassflowEndpointPaths.tenantPath,\n payload,\n );\n }\n\n // 1. Tenant Management\n\n /**\n * Get tenant details\n * @param tenantId Tenant ID\n */\n getTenantDetails(tenantId: string): Promise<PassflowTenantResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}`;\n return this.axiosClient.get<PassflowTenantResponse>(path);\n }\n\n /**\n * Update tenant name\n * @param tenantId Tenant ID\n * @param name New tenant name\n */\n updateTenant(tenantId: string, name: string): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}`;\n const payload: PassflowUpdateTenantPayload = { name };\n return this.axiosClient.put<PassflowStatusResponse, PassflowUpdateTenantPayload>(path, payload);\n }\n\n /**\n * Delete a tenant\n * @param tenantId Tenant ID\n */\n deleteTenant(tenantId: string): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}`;\n return this.axiosClient.delete<PassflowStatusResponse>(path);\n }\n\n /**\n * Get user's tenant memberships\n */\n getUserTenantMembership(): Promise<PassflowUserTenantMembershipResponse> {\n return this.axiosClient.get<PassflowUserTenantMembershipResponse>(PassflowEndpointPaths.tenantPath);\n }\n\n // 2. Group Management\n\n /**\n * Create a group in a tenant\n * @param tenantId Tenant ID\n * @param name Group name\n */\n createGroup(tenantId: string, name: string): Promise<PassflowGroupResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group`;\n const payload: PassflowCreateGroupPayload = { name };\n return this.axiosClient.post<PassflowGroupResponse, PassflowCreateGroupPayload>(path, payload);\n }\n\n /**\n * Get group information\n * @param tenantId Tenant ID\n * @param groupId Group ID\n */\n getGroupInfo(tenantId: string, groupId: string): Promise<PassflowGroupResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}`;\n return this.axiosClient.get<PassflowGroupResponse>(path);\n }\n\n /**\n * Update a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param name New group name\n */\n updateGroup(tenantId: string, groupId: string, name: string): Promise<PassflowGroupResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}`;\n const payload: PassflowUpdateGroupPayload = { name };\n return this.axiosClient.put<PassflowGroupResponse, PassflowUpdateGroupPayload>(path, payload);\n }\n\n /**\n * Delete a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n */\n deleteGroup(tenantId: string, groupId: string): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}`;\n return this.axiosClient.delete<PassflowStatusResponse>(path);\n }\n\n /**\n * Add a user to a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n * @param role Role to assign\n */\n addUserToGroup(tenantId: string, groupId: string, userId: string, role: string): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}/add`;\n const payload: PassflowAddUserToGroupPayload = { user_id: userId, role };\n return this.axiosClient.post<PassflowStatusResponse, PassflowAddUserToGroupPayload>(path, payload);\n }\n\n /**\n * Remove user roles from a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n * @param roles Roles to remove\n */\n removeUserRolesFromGroup(\n tenantId: string,\n groupId: string,\n userId: string,\n roles: string[],\n ): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}/remove_roles`;\n const payload: PassflowRemoveUserRolesPayload = { user_id: userId, roles };\n return this.axiosClient.post<PassflowStatusResponse, PassflowRemoveUserRolesPayload>(path, payload);\n }\n\n /**\n * Change user roles in a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n * @param roles New roles to assign\n */\n changeUserRoles(tenantId: string, groupId: string, userId: string, roles: string[]): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}/change`;\n const payload: PassflowChangeUserRolesPayload = { user_id: userId, roles };\n return this.axiosClient.post<PassflowStatusResponse, PassflowChangeUserRolesPayload>(path, payload);\n }\n\n /**\n * Delete a user from a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n */\n deleteUserFromGroup(tenantId: string, groupId: string, userId: string): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}/${userId}`;\n return this.axiosClient.delete<PassflowStatusResponse>(path);\n }\n\n // 3. Role Management\n\n /**\n * Get roles for a tenant\n * @param tenantId Tenant ID\n */\n getRolesForTenant(tenantId: string): Promise<PassflowRoleResponse[]> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/role`;\n return this.axiosClient.get<PassflowRoleResponse[]>(path);\n }\n\n /**\n * Create a role for a tenant\n * @param tenantId Tenant ID\n * @param name Role name\n */\n createRoleForTenant(tenantId: string, name: string): Promise<PassflowRoleResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/role`;\n const payload: PassflowCreateRolePayload = { name };\n return this.axiosClient.post<PassflowRoleResponse, PassflowCreateRolePayload>(path, payload);\n }\n\n /**\n * Update a role\n * @param tenantId Tenant ID\n * @param roleId Role ID\n * @param name New role name\n */\n updateRole(tenantId: string, roleId: string, name: string): Promise<PassflowRoleResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/role/${roleId}`;\n const payload: PassflowUpdateRolePayload = { name };\n return this.axiosClient.put<PassflowRoleResponse, PassflowUpdateRolePayload>(path, payload);\n }\n\n /**\n * Delete a role\n * @param tenantId Tenant ID\n * @param roleId Role ID\n */\n deleteRole(tenantId: string, roleId: string): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/role/${roleId}`;\n return this.axiosClient.delete<PassflowStatusResponse>(path);\n }\n\n // 4. User Management in Tenants\n\n /**\n * Delete a user from a tenant\n * @param tenantId Tenant ID\n * @param userId User ID\n */\n deleteUserFromTenant(tenantId: string, userId: string): Promise<PassflowStatusResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/user/${userId}`;\n return this.axiosClient.delete<PassflowStatusResponse>(path);\n }\n\n // 5. Invitation Management\n\n /**\n * Get invitations to a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param limit Maximum number of invitations to return\n * @param skip Number of invitations to skip\n */\n getGroupInvitations(tenantId: string, groupId: string, limit: number, skip: number): Promise<PassflowInvitationsResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}/invitations`;\n return this.axiosClient.get<PassflowInvitationsResponse>(path, {\n params: { limit, skip },\n });\n }\n\n /**\n * Get invitations to a tenant\n * @param tenantId Tenant ID\n * @param limit Maximum number of invitations to return\n * @param skip Number of invitations to skip\n */\n getTenantInvitations(tenantId: string, limit: number, skip: number): Promise<PassflowInvitationsResponse> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/invitations`;\n return this.axiosClient.get<PassflowInvitationsResponse>(path, {\n params: { limit, skip },\n });\n }\n\n /**\n * Invalidate an invitation by ID\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param inviteId Invitation ID\n */\n invalidateInviteById(tenantId: string, groupId: string, inviteId: string): Promise<Record<string, never>> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}/invite/${inviteId}`;\n return this.axiosClient.delete<Record<string, never>>(path);\n }\n\n /**\n * Invalidate an invitation by email\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param email Email address\n */\n invalidateInviteByEmail(tenantId: string, groupId: string, email: string): Promise<Record<string, never>> {\n const path = `${PassflowEndpointPaths.tenantPath}/${tenantId}/group/${groupId}/invite/email/${email}`;\n return this.axiosClient.delete<Record<string, never>>(path);\n }\n}\n","import { AxiosClient } from './axios-client';\nimport { type PassflowConfig, PassflowEndpointPaths, type PassflowSuccessResponse, pathWithParams } from './model';\n\nexport interface RequestInviteLinkPayload {\n email?: string;\n tenant?: string;\n group?: string;\n role?: string;\n callback?: string;\n send_to_email?: boolean;\n data?: Record<string, unknown>;\n}\n\nexport interface InviteLinkResponse {\n link: string;\n token?: string;\n}\n\nexport interface Invitation {\n id: string;\n archived?: boolean;\n app_id: string;\n inviter_id: string;\n inviter_name: string;\n token: string;\n email?: string;\n role?: string;\n tenant?: string;\n tenant_name?: string;\n group?: string;\n created_by?: string;\n created_at: string;\n expires_at: string;\n callback?: string;\n data?: Record<string, unknown>;\n}\n\n// Internal API response type\ninterface InvitationsAPIResponse {\n invites: Invitation[];\n next_page_skip?: string;\n}\n\n// Public interface for external use\nexport interface InvitationsPaginatedList {\n invites: Invitation[];\n nextPageSkip?: string;\n}\n\nexport class InvitationAPI {\n protected axiosClient: AxiosClient;\n\n constructor(config: PassflowConfig) {\n this.axiosClient = new AxiosClient(config);\n }\n\n /**\n * Requests an invitation link that can be used to invite users\n * @param payload Request invitation payload\n * @returns Promise with invitation link and token\n */\n requestInviteLink(payload: RequestInviteLinkPayload): Promise<InviteLinkResponse> {\n return this.axiosClient.post<InviteLinkResponse, RequestInviteLinkPayload>(\n PassflowEndpointPaths.requestInvitation,\n payload,\n );\n }\n\n /**\n * Gets a list of active invitations\n * @param options Optional parameters for filtering and pagination\n * @returns Promise with paginated list of invitations\n */\n getInvitations(options: {\n tenantID: string;\n groupID?: string;\n skip?: number | string;\n limit?: number | string;\n }): Promise<InvitationsPaginatedList> {\n const params: Record<string, string> = {};\n\n if (options.groupID) params.group_id = options.groupID.toString();\n if (options.skip !== undefined) params.skip = options.skip.toString();\n if (options.limit !== undefined) params.limit = options.limit.toString();\n\n const path = pathWithParams(PassflowEndpointPaths.invitationsPath, {\n tenantID: options.tenantID,\n });\n\n return this.axiosClient.get<InvitationsAPIResponse>(path, { params }).then((response) => ({\n invites: response.invites,\n nextPageSkip: response.next_page_skip,\n }));\n }\n\n /**\n * Deletes an invitation by token\n * @param invitationID The invitation ID to delete\n * @returns Promise with success response\n */\n deleteInvitation(invitationID: string): Promise<PassflowSuccessResponse> {\n const path = pathWithParams(PassflowEndpointPaths.invitationDelete, {\n invitationID,\n });\n return this.axiosClient.delete<PassflowSuccessResponse>(path);\n }\n\n /**\n * Resend an invitation by token\n * @param invitationID The invitation ID to resend\n * @returns Promise with success response\n */\n resendInvitation(invitationID: string): Promise<PassflowSuccessResponse> {\n const path = pathWithParams(PassflowEndpointPaths.invitationResend, {\n invitationID,\n });\n return this.axiosClient.post<PassflowSuccessResponse, unknown>(path, {});\n }\n\n /**\n * Get a link to an invitation by id\n * @param invitationID The invitation ID to get link\n * @returns Promise with the link\n */\n getInvitationLink(invitationID: string): Promise<InviteLinkResponse> {\n const path = pathWithParams(PassflowEndpointPaths.invitationGetLink, {\n invitationID,\n });\n return this.axiosClient.get<InviteLinkResponse>(path);\n }\n}\n","import { ParsedTokens, Tokens } from './types';\n\n/**\n * Passflow event types\n */\nexport enum PassflowEvent {\n SignIn = 'signin',\n SignInStart = 'signin:start',\n Register = 'register',\n RegisterStart = 'register:start',\n SignOut = 'signout',\n Error = 'error',\n Refresh = 'refresh',\n RefreshStart = 'refresh:start',\n TokenCacheExpired = 'token-cache-expired',\n}\n\n/**\n * Error payload interface for structured error information\n */\nexport interface ErrorPayload {\n message: string;\n code?: string | number;\n details?: unknown;\n originalError?: unknown;\n}\n\n/**\n * Event-specific payload types\n */\nexport type PassflowEventPayload = {\n [PassflowEvent.SignIn]: { tokens?: Tokens; parsedTokens?: ParsedTokens };\n [PassflowEvent.SignInStart]: { email?: string; provider?: string };\n [PassflowEvent.Register]: { tokens?: Tokens; parsedTokens?: ParsedTokens };\n [PassflowEvent.RegisterStart]: { email?: string };\n [PassflowEvent.SignOut]: { userId?: string };\n [PassflowEvent.Error]: ErrorPayload;\n [PassflowEvent.Refresh]: { tokens?: Tokens; parsedTokens?: ParsedTokens };\n [PassflowEvent.RefreshStart]: { tokenId?: string };\n [PassflowEvent.TokenCacheExpired]: { isExpired: boolean };\n};\n\n/**\n * Passflow subscriber interface\n */\nexport interface PassflowSubscriber {\n onAuthChange<E extends PassflowEvent>(eventType: E, payload?: PassflowEventPayload[E]): void;\n}\n\n/**\n * Store for managing Passflow event subscriptions\n */\nexport class PassflowStore {\n private subscribers: Map<PassflowSubscriber, Set<PassflowEvent> | null> = new Map();\n\n /**\n * Subscribe to authentication events\n * @param subscriber The subscriber to register\n * @param events Optional specific events to subscribe to\n */\n subscribe(subscriber: PassflowSubscriber, events?: PassflowEvent[]): void {\n if (events?.length) {\n const eventSet = new Set<PassflowEvent>(events);\n this.subscribers.set(subscriber, eventSet);\n } else {\n this.subscribers.set(subscriber, null);\n }\n }\n\n /**\n * Unsubscribe from authentication events\n * @param subscriber The subscriber to unregister\n * @param events Optional specific events to unsubscribe from\n */\n unsubscribe(subscriber: PassflowSubscriber, events?: PassflowEvent[]): void {\n if (!events?.length) {\n this.subscribers.delete(subscriber);\n return;\n }\n\n const subscribedEvents = this.subscribers.get(subscriber);\n if (!subscribedEvents) {\n return;\n }\n\n events.forEach((event) => subscribedEvents.delete(event));\n if (subscribedEvents.size === 0) {\n this.subscribers.delete(subscriber);\n }\n }\n\n /**\n * Notify subscribers of an event\n * @param eventType The type of event that occurred\n * @param payload Event-specific payload data\n */\n notify<E extends PassflowEvent>(eventType: E, payload?: PassflowEventPayload[E]): void {\n this.subscribers.forEach((events, subscriber) => {\n if (!events || events.has(eventType)) {\n subscriber.onAuthChange?.(eventType, payload);\n }\n });\n }\n}\n","import { startAuthentication, startRegistration } from '@simplewebauthn/browser';\nimport axios from 'axios';\nimport {\n AuthAPI,\n OS,\n PassflowAuthorizationResponse,\n PassflowError,\n PassflowFederatedAuthExtendedPayload,\n PassflowFederatedAuthPayload,\n PassflowPasskeyAuthenticateStartPayload,\n PassflowPasskeyRegisterStartPayload,\n PassflowPasswordlessResponse,\n PassflowPasswordlessSignInCompletePayload,\n PassflowPasswordlessSignInPayload,\n PassflowSendPasswordResetEmailPayload,\n PassflowSignInPayload,\n PassflowSignUpPayload,\n PassflowSuccessResponse,\n PassflowValidationResponse,\n} from '../api';\nimport { DeviceService } from '../device-service';\nimport { StorageManager } from '../storage-manager';\nimport { ErrorPayload, PassflowEvent, PassflowStore } from '../store';\nimport { TokenType, isTokenExpired, parseToken } from '../token-service';\nimport { ParsedTokens, Tokens } from '../types';\nimport { TokenCacheService } from './token-cache-service';\n\n/**\n * Service for handling authentication related functionality\n */\nexport class AuthService {\n constructor(\n private authApi: AuthAPI,\n private deviceService: DeviceService,\n private storageManager: StorageManager,\n private subscribeStore: PassflowStore,\n private tokenCacheService: TokenCacheService,\n private scopes: string[],\n private createTenantForNewUser: boolean,\n private origin: string,\n private url: string,\n private sessionCallbacks: {\n createSession?: ({ tokens, parsedTokens }: { tokens?: Tokens; parsedTokens?: ParsedTokens }) => Promise<void>;\n expiredSession?: () => Promise<void>;\n },\n private appId?: string,\n ) {}\n\n async signIn(payload: PassflowSignInPayload): Promise<PassflowAuthorizationResponse> {\n this.subscribeStore.notify(PassflowEvent.SignInStart, { email: payload.email });\n const deviceId = this.deviceService.getDeviceId();\n const os = OS.web;\n payload.scopes = payload.scopes ?? this.scopes;\n\n try {\n const response = await this.authApi.signIn(payload, deviceId, os);\n response.scopes = payload.scopes;\n this.storageManager.saveTokens(response);\n this.tokenCacheService.setTokensCache(response);\n this.subscribeStore.notify(PassflowEvent.SignIn, {\n tokens: response,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n await this.submitSessionCheck();\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Sign in failed',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async signUp(payload: PassflowSignUpPayload): Promise<PassflowAuthorizationResponse> {\n this.subscribeStore.notify(PassflowEvent.RegisterStart, { email: payload.user.email });\n payload.scopes = payload.scopes ?? this.scopes;\n payload.create_tenant = this.createTenantForNewUser;\n\n try {\n const response = await this.authApi.signUp(payload);\n response.scopes = payload.scopes;\n this.storageManager.saveTokens(response);\n this.tokenCacheService.setTokensCache(response);\n this.subscribeStore.notify(PassflowEvent.Register, {\n tokens: response,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n await this.submitSessionCheck();\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Sign up failed',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async passwordlessSignIn(payload: PassflowPasswordlessSignInPayload): Promise<PassflowPasswordlessResponse> {\n this.subscribeStore.notify(PassflowEvent.SignInStart, { email: payload.email });\n payload.scopes = payload.scopes ?? this.scopes;\n const deviceId = this.deviceService.getDeviceId();\n const os = OS.web;\n\n try {\n const response = await this.authApi.passwordlessSignIn(payload, deviceId, os);\n // Don't emit SignIn event yet since this is just the first step (magic link sent)\n // We'll emit SignIn when passwordlessSignInComplete is called\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to send passwordless sign-in link',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async passwordlessSignInComplete(payload: PassflowPasswordlessSignInCompletePayload): Promise<PassflowValidationResponse> {\n this.subscribeStore.notify(PassflowEvent.SignInStart, {});\n payload.scopes = payload.scopes ?? this.scopes;\n payload.device = this.deviceService.getDeviceId();\n\n try {\n const response = await this.authApi.passwordlessSignInComplete(payload);\n response.scopes = payload.scopes;\n this.storageManager.saveTokens(response);\n this.tokenCacheService.setTokensCache(response);\n this.subscribeStore.notify(PassflowEvent.SignIn, {\n tokens: response,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n await this.submitSessionCheck();\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Passwordless sign in failed',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async logOut() {\n const refreshToken = this.storageManager.getToken(TokenType.refresh_token);\n const deviceId = this.storageManager.getDeviceId();\n\n try {\n const response = await this.authApi.logOut(deviceId, refreshToken, !this.appId);\n if (response.status !== 'ok') {\n throw new Error('Logout failed');\n }\n this.storageManager.deleteTokens();\n this.subscribeStore.notify(PassflowEvent.SignOut, {});\n } catch (error) {\n // biome-ignore lint/suspicious/noConsole: <explanation>\n console.error(error);\n throw error;\n }\n }\n\n async refreshToken(): Promise<PassflowAuthorizationResponse> {\n this.subscribeStore.notify(PassflowEvent.RefreshStart, {});\n const tokens = this.storageManager.getTokens();\n if (!tokens) {\n const error = new Error('No tokens found');\n const errorPayload: ErrorPayload = {\n message: 'No tokens found',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n } else if (!tokens?.refresh_token) {\n const error = new Error('No refresh token found');\n const errorPayload: ErrorPayload = {\n message: 'No refresh token found',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n\n const oldScopes = tokens?.scopes ?? this.scopes;\n try {\n const response = await this.authApi.refreshToken(tokens?.refresh_token ?? '', oldScopes, tokens?.access_token);\n response.scopes = oldScopes;\n this.storageManager.saveTokens(response);\n this.tokenCacheService.setTokensCache(response);\n this.subscribeStore.notify(PassflowEvent.Refresh, {\n tokens: response,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n this.subscribeStore.notify(PassflowEvent.TokenCacheExpired, { isExpired: false });\n this.tokenCacheService.isRefreshing = false;\n this.tokenCacheService.isExpired = false;\n this.tokenCacheService.startTokenCheck();\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Token refresh failed',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n details:\n axios.isAxiosError(error) && error.response\n ? {\n status: error.response.status,\n data: error.response.data,\n }\n : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n\n if (error instanceof PassflowError) {\n throw error;\n } else if (axios.isAxiosError(error) && error.response && error.response?.status >= 400 && error.response?.status < 500) {\n throw new Error(`Getting unknown error message from server with code:${error.response.status}`);\n } else {\n throw error;\n }\n }\n }\n\n async sendPasswordResetEmail(payload: PassflowSendPasswordResetEmailPayload): Promise<PassflowSuccessResponse> {\n try {\n return await this.authApi.sendPasswordResetEmail(payload);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to send password reset email',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async resetPassword(newPassword: string, scopes?: string[]): Promise<PassflowAuthorizationResponse> {\n this.subscribeStore.notify(PassflowEvent.SignInStart, {});\n const urlParams = new URLSearchParams(window.location.search);\n const resetToken = urlParams.get('token') ?? undefined;\n const sscopes = scopes ?? this.scopes;\n\n try {\n const response = await this.authApi.resetPassword(newPassword, sscopes, resetToken);\n response.scopes = sscopes;\n this.storageManager.saveTokens(response);\n this.tokenCacheService.setTokensCache(response);\n this.subscribeStore.notify(PassflowEvent.SignIn, {\n tokens: response,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n await this.submitSessionCheck();\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Password reset failed',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async passkeyRegister(payload: PassflowPasskeyRegisterStartPayload): Promise<PassflowAuthorizationResponse> {\n this.subscribeStore.notify(PassflowEvent.RegisterStart, {});\n const deviceId = this.deviceService.getDeviceId();\n const os = OS.web;\n payload.scopes = payload.scopes ?? this.scopes;\n payload.create_tenant = this.createTenantForNewUser;\n\n try {\n const { challenge_id, publicKey } = await this.authApi.passkeyRegisterStart(payload, deviceId, os, !this.appId);\n // user handle should be base64 encoded for simplewebauthn lib we are using\n publicKey.user.id = btoa(publicKey.user.id);\n const webauthn = await startRegistration({\n optionsJSON: publicKey,\n });\n\n const responseRegisterComplete = await this.authApi.passkeyRegisterComplete(\n webauthn,\n deviceId,\n challenge_id,\n !this.appId,\n );\n responseRegisterComplete.scopes = payload.scopes;\n this.storageManager.saveTokens(responseRegisterComplete);\n this.tokenCacheService.setTokensCache(responseRegisterComplete);\n this.subscribeStore.notify(PassflowEvent.Register, {\n tokens: responseRegisterComplete,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n await this.submitSessionCheck();\n return responseRegisterComplete;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Passkey registration failed',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async passkeyAuthenticate(payload: PassflowPasskeyAuthenticateStartPayload): Promise<PassflowAuthorizationResponse> {\n this.subscribeStore.notify(PassflowEvent.SignInStart, {});\n const deviceId = this.deviceService.getDeviceId();\n const os = OS.web;\n payload.scopes = payload.scopes ?? this.scopes;\n\n try {\n const { challenge_id, publicKey } = await this.authApi.passkeyAuthenticateStart(payload, deviceId, os, !this.appId);\n const webauthn = await startAuthentication({\n optionsJSON: publicKey,\n });\n\n const responseAuthenticateComplete = await this.authApi.passkeyAuthenticateComplete(\n webauthn,\n deviceId,\n challenge_id,\n !this.appId,\n );\n\n if ('access_token' in responseAuthenticateComplete) {\n responseAuthenticateComplete.scopes = payload.scopes;\n this.storageManager.saveTokens(responseAuthenticateComplete);\n this.tokenCacheService.setTokensCache(responseAuthenticateComplete);\n this.subscribeStore.notify(PassflowEvent.SignIn, {\n tokens: responseAuthenticateComplete,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n await this.submitSessionCheck();\n }\n\n return responseAuthenticateComplete;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Passkey authentication failed',\n originalError: error,\n code: error instanceof PassflowError ? error.id : undefined,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n createFederatedAuthUrl(payload: PassflowFederatedAuthExtendedPayload): string {\n const passflowPathWithProvider = `/auth/federated/start/${payload.provider}`;\n\n if (!this.appId) throw new Error('AppId is required for federated auth');\n const sscopes = payload.scopes ?? this.scopes;\n\n const params: Record<string, string> = {\n scopes: sscopes.join(' '),\n redirect_url: payload.redirect_url ?? this.origin,\n appId: this.appId,\n ...(payload.invite_token ? { invite_token: payload.invite_token } : {}),\n ...(payload.create_tenant ? { create_tenant: payload.create_tenant.toString() } : {}),\n ...(payload.device ? { device: payload.device } : {}),\n };\n\n const url = new URL(passflowPathWithProvider, this.url);\n const queryParams = new URLSearchParams(params);\n url.search = queryParams.toString();\n\n return url.toString();\n }\n\n federatedAuthWithPopup(payload: PassflowFederatedAuthPayload): void {\n this.subscribeStore.notify(PassflowEvent.SignInStart, { provider: payload.provider });\n const sscopes = payload.scopes ?? this.scopes;\n const deviceId = this.deviceService.getDeviceId();\n const passflowURL = this.createFederatedAuthUrl({ ...payload, scopes: sscopes, device: deviceId });\n\n const popupWindow = window.open(passflowURL, '_blank', 'width=500,height=500');\n\n if (!popupWindow) {\n this.federatedAuthWithRedirect(payload);\n } else {\n const checkInterval = setInterval(() => {\n if (popupWindow.location.href.startsWith(this.origin)) {\n const urlParams = new URLSearchParams(popupWindow.location.search);\n const access_token = urlParams.get('access_token') || '';\n const refresh_token = urlParams.get('refresh_token') || '';\n const id_token = urlParams.get('id_token') || '';\n\n const tokensData = {\n access_token,\n refresh_token,\n id_token,\n scopes: sscopes,\n };\n this.storageManager.saveTokens(tokensData);\n this.tokenCacheService.setTokensCache(tokensData);\n this.subscribeStore.notify(PassflowEvent.SignIn, {\n tokens: tokensData,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n window.location.href = `${this.origin}`;\n clearInterval(checkInterval);\n popupWindow.close();\n }\n }, 100);\n }\n }\n\n federatedAuthWithRedirect(payload: PassflowFederatedAuthPayload): void {\n this.subscribeStore.notify(PassflowEvent.SignInStart, { provider: payload.provider });\n const sscopes = payload.scopes ?? this.scopes;\n const deviceId = this.deviceService.getDeviceId();\n const passflowURL = this.createFederatedAuthUrl({ ...payload, scopes: sscopes, device: deviceId });\n window.location.href = passflowURL;\n }\n\n // Helper methods for authentication UI redirect\n authRedirectUrl(\n options: {\n url?: string;\n redirectUrl?: string;\n scopes?: string[];\n appId?: string;\n } = {},\n ): string {\n try {\n const { url, redirectUrl, scopes, appId } = options ?? {};\n const externalUrl = new URL(url ?? this.url);\n // add web to the pathname if it's not there\n externalUrl.pathname = (externalUrl.pathname.endsWith('/') ? externalUrl.pathname : externalUrl.pathname + '/') + 'web';\n const sscopes = scopes ?? this.scopes;\n const params: Record<string, string> = {\n appId: appId ?? this.appId ?? '',\n redirectto: redirectUrl ?? window.location.href,\n scopes: sscopes.join(','),\n };\n\n const queryParams = new URLSearchParams(params);\n externalUrl.search = queryParams.toString();\n return externalUrl.toString();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to create auth redirect URL',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n authRedirect(\n options: {\n url?: string;\n redirectUrl?: string;\n scopes?: string[];\n appId?: string;\n } = {},\n ): void {\n try {\n window.location.href = this.authRedirectUrl(options);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to redirect to auth page',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(parsedTokens: ParsedTokens): boolean {\n try {\n if (!parsedTokens) return false;\n\n return (\n !isTokenExpired(parsedTokens.access_token) ||\n (!!parsedTokens.refresh_token && !isTokenExpired(parsedTokens.refresh_token))\n );\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to check authentication status',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n return false;\n }\n }\n\n /**\n * Handle session check and callbacks\n */\n async submitSessionCheck(doRefresh = false): Promise<Tokens | undefined> {\n let tokens;\n let parsedTokens;\n try {\n tokens = await this.getTokens(doRefresh);\n parsedTokens = this.tokenCacheService.getParsedTokenCache();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error || error instanceof PassflowError ? error.message : 'Session check failed',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n tokens = undefined;\n }\n\n if (tokens && this.sessionCallbacks.createSession) {\n await this.sessionCallbacks.createSession({ tokens, parsedTokens });\n }\n\n if (!tokens && this.sessionCallbacks.expiredSession) {\n await this.sessionCallbacks.expiredSession();\n }\n\n return tokens;\n }\n\n /**\n * Get tokens and refresh if needed\n */\n async getTokens(doRefresh: boolean): Promise<Tokens | undefined> {\n try {\n const tokens = this.storageManager.getTokens();\n // we have no token in storage\n if (!tokens || !tokens.access_token) return undefined;\n\n const access = parseToken(tokens.access_token);\n\n if (isTokenExpired(access)) {\n // we have expired token and we need to refresh it or throw error if it's not possible\n if (doRefresh) return await this.refreshToken();\n\n // we need return undefined here, because we have expired token and we no need to refresh it\n return undefined;\n } else {\n return tokens;\n }\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get tokens',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n return undefined;\n }\n }\n}\n","import type {\n InvitationAPI,\n InvitationsPaginatedList,\n InviteLinkResponse,\n PassflowSuccessResponse,\n RequestInviteLinkPayload,\n} from '../api';\n\n/**\n * Service for managing invitations\n */\nexport class InvitationService {\n constructor(private invitationAPI: InvitationAPI) {}\n\n /**\n * Requests an invitation link that can be used to invite users\n * @param payload Request invitation payload\n * @returns Promise with invitation link and token\n */\n requestInviteLink(payload: RequestInviteLinkPayload): Promise<InviteLinkResponse> {\n return this.invitationAPI.requestInviteLink(payload);\n }\n\n /**\n * Gets a list of active invitations\n * @param options Optional parameters for filtering and pagination\n * @returns Promise with paginated list of invitations\n */\n getInvitations(options: {\n tenantID: string;\n groupID?: string;\n skip?: number | string;\n limit?: number | string;\n }): Promise<InvitationsPaginatedList> {\n return this.invitationAPI.getInvitations(options);\n }\n\n /**\n * Deletes an invitation by token\n * @param token The invitation token to delete\n * @returns Promise with success response\n */\n deleteInvitation(token: string): Promise<PassflowSuccessResponse> {\n return this.invitationAPI.deleteInvitation(token);\n }\n\n /**\n * Resends an invitation by token\n * @param token The invitation token to resend\n * @returns Promise with success response\n */\n resendInvitation(token: string): Promise<PassflowSuccessResponse> {\n return this.invitationAPI.resendInvitation(token);\n }\n\n /**\n * Gets a link to an invitation by id\n * @param invitationID The invitation ID to get link\n * @returns Promise with the link\n */\n getInvitationLink(invitationID: string): Promise<InviteLinkResponse> {\n return this.invitationAPI.getInvitationLink(invitationID);\n }\n}\n","/**\n * Logger interface for Passflow services\n */\nexport interface Logger {\n error(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n debug(message: string, ...args: unknown[]): void;\n}\n\n/**\n * Default console logger implementation\n */\nexport class ConsoleLogger implements Logger {\n error(message: string, ...args: unknown[]): void {\n // biome-ignore lint/suspicious/noConsole: <explanation>\n console.error(message, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n // biome-ignore lint/suspicious/noConsole: <explanation>\n console.warn(message, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n // biome-ignore lint/suspicious/noConsole: <explanation>\n console.info(message, ...args);\n }\n\n debug(message: string, ...args: unknown[]): void {\n // biome-ignore lint/suspicious/noConsole: <explanation>\n console.debug(message, ...args);\n }\n}\n\n/**\n * Get the default logger\n * @returns Default logger instance\n */\nexport function getDefaultLogger(): Logger {\n return new ConsoleLogger();\n}\n","// lib/services/tenant-user-membership.ts\n\nimport type { PassflowGroup, PassflowRole, PassflowTenantResponse, PassflowUserInGroup } from '../api/model';\n\n/**\n * Flat user representation\n */\nexport interface User {\n id: string;\n name: string | null;\n email: string | null;\n phone: string | null;\n}\n\n/**\n * Flat group representation\n */\nexport interface Group {\n id: string;\n name: string;\n default: boolean;\n updated_at: string;\n created_at: string;\n}\n\n/**\n * Flat role representation\n */\nexport interface Role {\n id: string;\n tenant_id: string;\n name: string;\n}\n\n/**\n * Maps a user to a group with specific roles\n */\nexport interface Membership {\n userId: string;\n groupId: string;\n roleIds: string[];\n}\n\n/**\n * Full tenant view with lookup maps\n */\nexport interface TenantData {\n tenant_id: string;\n tenant_name: string;\n users: User[];\n groups: Group[];\n roles: Role[];\n memberships: Membership[];\n usersById: Map<string, User>;\n groupsById: Map<string, Group>;\n rolesById: Map<string, Role>;\n}\n\n/**\n * Utility for transforming raw PassflowTenantResponse\n * into a flattened TenantData model with quick lookup methods.\n */\nexport class TenantUserMembership {\n private data: TenantData;\n\n constructor(raw: PassflowTenantResponse) {\n this.data = this.normalize(raw);\n }\n\n private normalize(raw: PassflowTenantResponse): TenantData {\n const users = new Map<string, User>();\n const groups = new Map<string, Group>();\n const roles = new Map<string, Role>();\n const memberships: Membership[] = [];\n\n // process groups\n raw.groups?.forEach((g: PassflowGroup) => {\n groups.set(g.id, {\n id: g.id,\n name: g.name,\n default: g.default ?? false,\n updated_at: g.updated_at,\n created_at: g.created_at,\n });\n });\n\n // process roles\n raw.roles?.forEach((r: PassflowRole) => {\n roles.set(r.id, {\n id: r.id,\n tenant_id: r.tenant_id,\n name: r.name,\n });\n });\n\n // process users and memberships\n raw.users_in_groups?.forEach((uig: PassflowUserInGroup) => {\n const u = uig.user;\n if (u && !users.has(u.id)) {\n users.set(u.id, {\n id: u.id,\n name: u.name ?? null,\n email: u.email ?? null,\n phone: u.phone ?? null,\n });\n }\n if (u && uig.group_id && groups.has(uig.group_id)) {\n memberships.push({\n userId: u.id,\n groupId: uig.group_id,\n roleIds: uig.roles?.map((r) => r.id) ?? [],\n });\n }\n });\n\n return {\n tenant_id: raw.tenant_id,\n tenant_name: raw.tenant_name,\n users: Array.from(users.values()),\n groups: Array.from(groups.values()),\n roles: Array.from(roles.values()),\n memberships,\n usersById: users,\n groupsById: groups,\n rolesById: roles,\n };\n }\n\n /**\n * Returns all users in the specified group.\n */\n getUsersInGroup(groupId: string): User[] {\n return this.data.memberships\n .filter((m) => m.groupId === groupId)\n .map((m) => this.data.usersById.get(m.userId))\n .filter((u): u is User => u !== undefined);\n }\n\n /**\n * Returns all groups to which the specified user belongs.\n */\n getGroupsForUser(userId: string): Group[] {\n return this.data.memberships\n .filter((m) => m.userId === userId)\n .map((m) => this.data.groupsById.get(m.groupId))\n .filter((g): g is Group => g !== undefined);\n }\n\n /**\n * Returns all roles that the specified user has in the specified group.\n */\n getUserRolesInGroup(userId: string, groupId: string): Role[] {\n const membership = this.data.memberships.find((m) => m.userId === userId && m.groupId === groupId);\n if (!membership) {\n return [];\n }\n return membership.roleIds.map((roleId) => this.data.rolesById.get(roleId)).filter((r): r is Role => r !== undefined);\n }\n\n /**\n * Returns the full TenantData object.\n */\n getData(): TenantData {\n return this.data;\n }\n}\n","import axios from 'axios';\nimport {\n PassflowAuthorizationResponse,\n PassflowGroupResponse,\n PassflowInvitationsResponse,\n PassflowRoleResponse,\n PassflowStatusResponse,\n PassflowTenantResponse,\n PassflowUserTenantMembershipResponse,\n TenantAPI,\n} from '../api';\nimport { Logger, getDefaultLogger } from './logger';\nimport { TenantUserMembership } from './tenant-user-membership';\n\n/**\n * Service for managing tenants\n */\nexport class TenantService {\n private logger: Logger;\n\n constructor(\n private tenantAPI: TenantAPI,\n private scopes: string[],\n logger?: Logger,\n ) {\n this.logger = logger || getDefaultLogger();\n }\n\n /**\n * Handle Passflow API errors\n * @param error The error object\n * @param context Context information for logging\n * @throws Formatted error with Passflow API error details\n */\n private handlePassflowError(error: unknown, context: string): never {\n // Check if it's an Axios error with a response\n if (axios.isAxiosError(error) && error.response?.data) {\n const responseData = error.response.data;\n\n // Check if it's a Passflow API error format\n if (\n typeof responseData === 'object' &&\n responseData !== null &&\n 'error' in responseData &&\n typeof responseData.error === 'object' &&\n responseData.error !== null\n ) {\n const passflowError = responseData.error as {\n id: string;\n message: string;\n status: number;\n location: string;\n time: string;\n };\n\n // Log the formatted error\n this.logger.error(`${context}: ${passflowError.id} - ${passflowError.message} (Status: ${passflowError.status})`);\n\n // Throw a new error with the formatted message\n throw new Error(`Passflow API Error: ${passflowError.id} - ${passflowError.message} (Status: ${passflowError.status})`);\n }\n }\n\n // If it's not a Passflow API error, log and rethrow\n this.logger.error(`${context}:`, error);\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(String(error));\n }\n\n /**\n * Join a tenant invitation\n * @param token The invitation token\n * @param scopes Optional scopes to request\n * @returns Promise with invite response\n */\n async joinInvitation(token: string, scopes?: string[]): Promise<PassflowAuthorizationResponse> {\n try {\n const sscopes = scopes ?? this.scopes;\n return await this.tenantAPI.joinInvitation(token, sscopes);\n } catch (error) {\n this.handlePassflowError(error, 'Join invitation failed');\n }\n }\n\n /**\n * Create a new tenant\n * @param name The name of the tenant\n * @returns Promise with tenant response\n */\n async createTenant(name: string): Promise<PassflowTenantResponse> {\n try {\n return await this.tenantAPI.createTenant(name);\n } catch (error) {\n this.handlePassflowError(error, 'Tenant creation failed');\n }\n }\n\n // 1. Tenant Management\n\n /**\n * Get tenant details\n * @param tenantId Tenant ID\n * @returns Promise with tenant response\n */\n /**\n * Get tenant details\n * @param tenantId Tenant ID\n * @returns Promise with tenant response\n */\n async getTenantDetails(tenantId: string): Promise<PassflowTenantResponse> {\n try {\n const response = await this.tenantAPI.getTenantDetails(tenantId);\n return response;\n } catch (error) {\n this.handlePassflowError(error, `Get tenant details failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Get tenant details and transform into TenantUserMembership\n * @param tenantId Tenant ID\n * @returns Promise with TenantUserMembership instance\n */\n async getTenantUserMembership(tenantId: string): Promise<TenantUserMembership> {\n try {\n const response = await this.tenantAPI.getTenantDetails(tenantId);\n return new TenantUserMembership(response);\n } catch (error) {\n this.handlePassflowError(error, `Get tenant user membership failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Update tenant name\n * @param tenantId Tenant ID\n * @param name New tenant name\n * @returns Promise with status response\n */\n async updateTenant(tenantId: string, name: string): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.updateTenant(tenantId, name);\n } catch (error) {\n this.handlePassflowError(error, `Update tenant failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Delete a tenant\n * @param tenantId Tenant ID\n * @returns Promise with status response\n */\n async deleteTenant(tenantId: string): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.deleteTenant(tenantId);\n } catch (error) {\n this.handlePassflowError(error, `Delete tenant failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Get user's tenant memberships\n * @returns Promise with user tenant membership response\n */\n async getUserTenantMembership(): Promise<PassflowUserTenantMembershipResponse> {\n try {\n return await this.tenantAPI.getUserTenantMembership();\n } catch (error) {\n this.handlePassflowError(error, 'Get user tenant memberships failed');\n }\n }\n\n // 2. Group Management\n\n /**\n * Create a group in a tenant\n * @param tenantId Tenant ID\n * @param name Group name\n * @returns Promise with group response\n */\n async createGroup(tenantId: string, name: string): Promise<PassflowGroupResponse> {\n try {\n return await this.tenantAPI.createGroup(tenantId, name);\n } catch (error) {\n this.handlePassflowError(error, `Group creation failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Get group information\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @returns Promise with group response\n */\n async getGroupInfo(tenantId: string, groupId: string): Promise<PassflowGroupResponse> {\n try {\n return await this.tenantAPI.getGroupInfo(tenantId, groupId);\n } catch (error) {\n this.handlePassflowError(error, `Get group info failed for tenant ID ${tenantId}, group ID ${groupId}`);\n }\n }\n\n /**\n * Update a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param name New group name\n * @returns Promise with group response\n */\n async updateGroup(tenantId: string, groupId: string, name: string): Promise<PassflowGroupResponse> {\n try {\n return await this.tenantAPI.updateGroup(tenantId, groupId, name);\n } catch (error) {\n this.handlePassflowError(error, `Update group failed for tenant ID ${tenantId}, group ID ${groupId}`);\n }\n }\n\n /**\n * Delete a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @returns Promise with status response\n */\n async deleteGroup(tenantId: string, groupId: string): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.deleteGroup(tenantId, groupId);\n } catch (error) {\n this.handlePassflowError(error, `Delete group failed for tenant ID ${tenantId}, group ID ${groupId}`);\n }\n }\n\n /**\n * Add a user to a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n * @param role Role to assign\n * @returns Promise with status response\n */\n async addUserToGroup(tenantId: string, groupId: string, userId: string, role: string): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.addUserToGroup(tenantId, groupId, userId, role);\n } catch (error) {\n this.handlePassflowError(\n error,\n `Add user to group failed for tenant ID ${tenantId}, group ID ${groupId}, user ID ${userId}`,\n );\n }\n }\n\n /**\n * Remove user roles from a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n * @param roles Roles to remove\n * @returns Promise with status response\n */\n async removeUserRolesFromGroup(\n tenantId: string,\n groupId: string,\n userId: string,\n roles: string[],\n ): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.removeUserRolesFromGroup(tenantId, groupId, userId, roles);\n } catch (error) {\n this.handlePassflowError(\n error,\n `Remove user roles from group failed for tenant ID ${tenantId}, group ID ${groupId}, user ID ${userId}`,\n );\n }\n }\n\n /**\n * Change user roles in a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n * @param roles New roles to assign\n * @returns Promise with status response\n */\n async changeUserRoles(tenantId: string, groupId: string, userId: string, roles: string[]): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.changeUserRoles(tenantId, groupId, userId, roles);\n } catch (error) {\n this.handlePassflowError(\n error,\n `Change user roles failed for tenant ID ${tenantId}, group ID ${groupId}, user ID ${userId}`,\n );\n }\n }\n\n /**\n * Delete a user from a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param userId User ID\n * @returns Promise with status response\n */\n async deleteUserFromGroup(tenantId: string, groupId: string, userId: string): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.deleteUserFromGroup(tenantId, groupId, userId);\n } catch (error) {\n this.handlePassflowError(\n error,\n `Delete user from group failed for tenant ID ${tenantId}, group ID ${groupId}, user ID ${userId}`,\n );\n }\n }\n\n // 3. Role Management\n\n /**\n * Get roles for a tenant\n * @param tenantId Tenant ID\n * @returns Promise with array of role responses\n */\n async getRolesForTenant(tenantId: string): Promise<PassflowRoleResponse[]> {\n try {\n return await this.tenantAPI.getRolesForTenant(tenantId);\n } catch (error) {\n this.handlePassflowError(error, `Get roles for tenant failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Create a role for a tenant\n * @param tenantId Tenant ID\n * @param name Role name\n * @returns Promise with role response\n */\n async createRoleForTenant(tenantId: string, name: string): Promise<PassflowRoleResponse> {\n try {\n return await this.tenantAPI.createRoleForTenant(tenantId, name);\n } catch (error) {\n this.handlePassflowError(error, `Create role for tenant failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Update a role\n * @param tenantId Tenant ID\n * @param roleId Role ID\n * @param name New role name\n * @returns Promise with role response\n */\n async updateRole(tenantId: string, roleId: string, name: string): Promise<PassflowRoleResponse> {\n try {\n return await this.tenantAPI.updateRole(tenantId, roleId, name);\n } catch (error) {\n this.handlePassflowError(error, `Update role failed for tenant ID ${tenantId}, role ID ${roleId}`);\n }\n }\n\n /**\n * Delete a role\n * @param tenantId Tenant ID\n * @param roleId Role ID\n * @returns Promise with status response\n */\n async deleteRole(tenantId: string, roleId: string): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.deleteRole(tenantId, roleId);\n } catch (error) {\n this.handlePassflowError(error, `Delete role failed for tenant ID ${tenantId}, role ID ${roleId}`);\n }\n }\n\n // 4. User Management in Tenants\n\n /**\n * Delete a user from a tenant\n * @param tenantId Tenant ID\n * @param userId User ID\n * @returns Promise with status response\n */\n async deleteUserFromTenant(tenantId: string, userId: string): Promise<PassflowStatusResponse> {\n try {\n return await this.tenantAPI.deleteUserFromTenant(tenantId, userId);\n } catch (error) {\n this.handlePassflowError(error, `Delete user from tenant failed for tenant ID ${tenantId}, user ID ${userId}`);\n }\n }\n\n // 5. Invitation Management\n\n /**\n * Get invitations to a group\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param limit Maximum number of invitations to return\n * @param skip Number of invitations to skip\n * @returns Promise with invitations response\n */\n async getGroupInvitations(\n tenantId: string,\n groupId: string,\n limit: number,\n skip: number,\n ): Promise<PassflowInvitationsResponse> {\n try {\n return await this.tenantAPI.getGroupInvitations(tenantId, groupId, limit, skip);\n } catch (error) {\n this.handlePassflowError(error, `Get group invitations failed for tenant ID ${tenantId}, group ID ${groupId}`);\n }\n }\n\n /**\n * Get invitations to a tenant\n * @param tenantId Tenant ID\n * @param limit Maximum number of invitations to return\n * @param skip Number of invitations to skip\n * @returns Promise with invitations response\n */\n async getTenantInvitations(tenantId: string, limit: number, skip: number): Promise<PassflowInvitationsResponse> {\n try {\n return await this.tenantAPI.getTenantInvitations(tenantId, limit, skip);\n } catch (error) {\n this.handlePassflowError(error, `Get tenant invitations failed for tenant ID ${tenantId}`);\n }\n }\n\n /**\n * Invalidate an invitation by ID\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param inviteId Invitation ID\n * @returns Promise with empty record\n */\n async invalidateInviteById(tenantId: string, groupId: string, inviteId: string): Promise<Record<string, never>> {\n try {\n return await this.tenantAPI.invalidateInviteById(tenantId, groupId, inviteId);\n } catch (error) {\n this.handlePassflowError(\n error,\n `Invalidate invite by ID failed for tenant ID ${tenantId}, group ID ${groupId}, invite ID ${inviteId}`,\n );\n }\n }\n\n /**\n * Invalidate an invitation by email\n * @param tenantId Tenant ID\n * @param groupId Group ID\n * @param email Email address\n * @returns Promise with empty record\n */\n async invalidateInviteByEmail(tenantId: string, groupId: string, email: string): Promise<Record<string, never>> {\n try {\n return await this.tenantAPI.invalidateInviteByEmail(tenantId, groupId, email);\n } catch (error) {\n this.handlePassflowError(\n error,\n `Invalidate invite by email failed for tenant ID ${tenantId}, group ID ${groupId}, email ${email}`,\n );\n }\n }\n}\n","import { startRegistration } from '@simplewebauthn/browser';\nimport { OS, PassflowSuccessResponse, UserAPI } from '../api';\n\n/**\n * Service for managing user profile and passkeys\n */\nexport class UserService {\n constructor(\n private userAPI: UserAPI,\n private deviceService: DeviceService,\n ) {}\n\n /**\n * Get user's registered passkeys\n * @returns Promise with passkeys array\n */\n getUserPasskeys() {\n return this.userAPI.getUserPasskeys();\n }\n\n /**\n * Rename a user passkey\n * @param name The new name for the passkey\n * @param passkeyId The ID of the passkey to rename\n * @returns Promise with success response\n */\n renameUserPasskey(name: string, passkeyId: string): Promise<PassflowSuccessResponse> {\n return this.userAPI.renameUserPasskey(name, passkeyId);\n }\n\n /**\n * Delete a user passkey\n * @param passkeyId The ID of the passkey to delete\n * @returns Promise with success response\n */\n deleteUserPasskey(passkeyId: string): Promise<PassflowSuccessResponse> {\n return this.userAPI.deleteUserPasskey(passkeyId);\n }\n\n /**\n * Add a new passkey for the current user\n * @param options Optional parameters for the passkey\n * @returns Promise that resolves when the passkey is added\n */\n async addUserPasskey({\n relyingPartyId,\n passkeyUsername,\n passkeyDisplayName,\n }: {\n relyingPartyId?: string;\n passkeyUsername?: string;\n passkeyDisplayName?: string;\n } = {}): Promise<void> {\n const deviceId = this.deviceService.getDeviceId();\n const os = OS.web;\n const { challenge_id, publicKey } = await this.userAPI.addUserPasskeyStart({\n relyingPartyId: relyingPartyId || window?.location?.hostname,\n deviceId,\n os,\n passkeyDisplayName,\n passkeyUsername,\n });\n // user handle should be base64 encoded for simplewebauthn lib we are using\n publicKey.user.id = btoa(publicKey.user.id);\n const webauthn = await startRegistration({ optionsJSON: publicKey });\n return await this.userAPI.addUserPasskeyComplete(webauthn, deviceId, challenge_id);\n }\n}\n\n// We need to import DeviceService after the class definition to avoid circular dependency\nimport { DeviceService } from '../device-service';\n","import { AuthAPI } from '../api';\nimport { StorageManager } from '../storage-manager';\nimport { ErrorPayload, PassflowEvent, PassflowStore } from '../store';\nimport { isTokenExpired, parseToken } from '../token-service';\nimport type { ParsedTokens, Tokens } from '../types';\n\nexport class TokenCacheService {\n tokensCache: Tokens | undefined;\n parsedTokensCache: ParsedTokens | undefined;\n\n private checkInterval: NodeJS.Timeout | null = null;\n private readonly CHECK_INTERVAL = 10;\n isRefreshing = false;\n isExpired = false;\n\n constructor(\n private storageManager: StorageManager,\n private authApi: AuthAPI,\n private subscribeStore: PassflowStore,\n ) {\n this.storageManager = storageManager;\n this.authApi = authApi;\n }\n\n initialize() {\n try {\n const tokens = this.storageManager.getTokens();\n if (!tokens || !tokens.access_token) {\n this.startTokenCheck();\n return;\n }\n\n const access = parseToken(tokens.access_token);\n\n if (isTokenExpired(access)) {\n this.isExpired = true;\n this.stopTokenCheck();\n this.subscribeStore.notify(PassflowEvent.TokenCacheExpired, { isExpired: true });\n } else {\n this.setTokensCache(tokens);\n this.startTokenCheck();\n }\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get tokens',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n this.setTokensCache(undefined);\n }\n }\n\n private async refreshTokensCache(tokens: Tokens) {\n if (this.isRefreshing) return;\n\n try {\n this.isRefreshing = true;\n this.subscribeStore.notify(PassflowEvent.RefreshStart, {});\n\n const response = await this.authApi.refreshToken(tokens?.refresh_token ?? '', tokens.scopes ?? [], tokens.access_token);\n this.setTokensCache(response);\n\n this.subscribeStore.notify(PassflowEvent.Refresh, { tokens: response, parsedTokens: this.getParsedTokenCache() });\n this.subscribeStore.notify(PassflowEvent.TokenCacheExpired, { isExpired: false });\n this.isExpired = false;\n this.startTokenCheck();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get tokens',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n this.setTokensCache(undefined);\n } finally {\n this.isRefreshing = false;\n }\n }\n\n startTokenCheck() {\n if (this.checkInterval) {\n clearInterval(this.checkInterval);\n }\n\n if (this.isExpired) return;\n\n this.checkInterval = setInterval(() => {\n if (this.isRefreshing || this.isExpired) return;\n\n if (this.tokensCacheIsExpired() && !this.isExpired) {\n this.isExpired = true;\n this.subscribeStore.notify(PassflowEvent.TokenCacheExpired, { isExpired: true });\n this.stopTokenCheck();\n }\n }, this.CHECK_INTERVAL);\n }\n\n private stopTokenCheck() {\n if (this.checkInterval) {\n clearInterval(this.checkInterval);\n this.checkInterval = null;\n }\n }\n\n setTokensCache(tokens: Tokens | undefined): void {\n this.tokensCache = tokens;\n if (tokens) {\n this.parsedTokensCache = {\n access_token: parseToken(tokens.access_token),\n id_token: tokens.id_token ? parseToken(tokens.id_token) : undefined,\n refresh_token: tokens.refresh_token ? parseToken(tokens.refresh_token) : undefined,\n scopes: tokens.scopes,\n };\n } else {\n this.parsedTokensCache = undefined;\n }\n }\n\n getTokensCache() {\n return this.tokensCache;\n }\n\n async getTokensCacheWithRefresh() {\n try {\n if (!this.tokensCache) return this.tokensCache;\n\n const access = parseToken(this.tokensCache.access_token);\n\n if (isTokenExpired(access) && !this.isExpired) {\n await this.refreshTokensCache(this.tokensCache);\n return this.tokensCache;\n } else {\n return this.tokensCache;\n }\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get tokens',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n return undefined;\n }\n }\n\n getParsedTokenCache() {\n return this.parsedTokensCache;\n }\n\n tokensCacheIsExpired() {\n if (!this.tokensCache) return true;\n const access = parseToken(this.tokensCache.access_token);\n return isTokenExpired(access);\n }\n}\n","import {\n AppAPI,\n type AppSettings,\n AuthAPI,\n InvitationAPI,\n type InvitationsPaginatedList,\n type InviteLinkResponse,\n type PassflowAuthorizationResponse,\n type PassflowConfig,\n PassflowError,\n PassflowFederatedAuthPayload,\n type PassflowPasskeyAuthenticateStartPayload,\n type PassflowPasskeyRegisterStartPayload,\n type PassflowPasskeySettings,\n type PassflowPasswordPolicySettings,\n type PassflowPasswordlessResponse,\n type PassflowPasswordlessSignInCompletePayload,\n type PassflowPasswordlessSignInPayload,\n type PassflowSendPasswordResetEmailPayload,\n type PassflowSettingsAll,\n type PassflowSignInPayload,\n type PassflowSignUpPayload,\n type PassflowSuccessResponse,\n type PassflowTenantResponse,\n type PassflowValidationResponse,\n type RequestInviteLinkPayload,\n SettingAPI,\n TenantAPI,\n UserAPI,\n} from './api';\nimport { DEFAULT_SCOPES, PASSFLOW_CLOUD_URL } from './constants';\nimport { DeviceService } from './device-service';\nimport { AuthService, InvitationService, TenantService, TokenCacheService, UserService } from './services';\nimport { StorageManager } from './storage-manager';\nimport { type ErrorPayload, PassflowEvent, PassflowStore, type PassflowSubscriber } from './store';\nimport { type TokenType, parseToken } from './token-service';\n\nimport type { ParsedTokens, SessionParams, Tokens } from './types';\n\nexport class Passflow {\n // API clients\n private authApi: AuthAPI;\n private appApi: AppAPI;\n private userApi: UserAPI;\n private settingApi: SettingAPI;\n private tenantAPI: TenantAPI;\n private invitationAPI: InvitationAPI;\n\n // Configuration\n private scopes: string[];\n private createTenantForNewUser: boolean;\n private doRefreshTokens = false;\n\n // Services\n private deviceService: DeviceService;\n private storageManager: StorageManager;\n private subscribeStore: PassflowStore;\n private authService: AuthService;\n private userService: UserService;\n private tenantService: TenantService;\n private invitationService: InvitationService;\n private tokenCacheService: TokenCacheService;\n\n // Public services\n public tenant: TenantService;\n\n // Session callbacks\n private createSessionCallback?: ({ tokens, parsedTokens }: { tokens?: Tokens; parsedTokens?: ParsedTokens }) => Promise<void>;\n private expiredSessionCallback?: () => Promise<void>;\n\n // State\n error?: Error;\n origin = window.location.origin;\n url: string;\n appId?: string;\n\n constructor(config: PassflowConfig) {\n const { url, appId, scopes } = config;\n this.url = url || PASSFLOW_CLOUD_URL;\n this.appId = appId;\n\n // Initialize API clients\n this.authApi = new AuthAPI(config);\n this.appApi = new AppAPI(config);\n this.userApi = new UserAPI(config);\n this.settingApi = new SettingAPI(config);\n this.tenantAPI = new TenantAPI(config);\n this.invitationAPI = new InvitationAPI(config);\n\n // Initialize services\n this.storageManager = new StorageManager({\n prefix: config.keyStoragePrefix ?? '',\n });\n this.deviceService = new DeviceService();\n this.subscribeStore = new PassflowStore();\n\n this.tokenCacheService = new TokenCacheService(this.storageManager, this.authApi, this.subscribeStore);\n\n this.scopes = scopes ?? DEFAULT_SCOPES;\n this.createTenantForNewUser = config.createTenantForNewUser ?? false;\n\n // Initialize domain services with dependencies\n this.authService = new AuthService(\n this.authApi,\n this.deviceService,\n this.storageManager,\n this.subscribeStore,\n this.tokenCacheService,\n this.scopes,\n this.createTenantForNewUser,\n this.origin,\n this.url,\n {\n createSession: this.createSessionCallback,\n expiredSession: this.expiredSessionCallback,\n },\n this.appId ?? '',\n );\n\n this.userService = new UserService(this.userApi, this.deviceService);\n\n this.tenantService = new TenantService(this.tenantAPI, this.scopes);\n this.tenant = this.tenantService;\n\n this.invitationService = new InvitationService(this.invitationAPI);\n\n // Check for tokens in query params if configured\n if (config.parseQueryParams) {\n this.checkAndSetTokens();\n }\n\n this.setTokensToCacheFromLocalStorage();\n }\n\n // Session management\n session: ({ createSession, expiredSession, doRefresh }: SessionParams) => Promise<void> = async ({\n createSession,\n expiredSession,\n doRefresh = false,\n }) => {\n this.createSessionCallback = createSession;\n this.expiredSessionCallback = expiredSession;\n this.doRefreshTokens = doRefresh;\n\n await this.submitSessionCheck();\n };\n\n private async submitSessionCheck() {\n let tokens;\n let parsedTokens;\n try {\n tokens = await this.authService.getTokens(this.doRefreshTokens);\n parsedTokens = this.tokenCacheService.getParsedTokenCache();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error || error instanceof PassflowError ? error.message : 'Session check failed',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n tokens = undefined;\n }\n\n if (tokens && this.createSessionCallback) {\n await this.createSessionCallback({ tokens, parsedTokens });\n }\n\n if (!tokens && this.expiredSessionCallback) {\n await this.expiredSessionCallback();\n }\n }\n\n // Event subscription\n subscribe(s: PassflowSubscriber, t?: PassflowEvent[]) {\n this.subscribeStore.subscribe(s, t);\n\n // Initialize token cache service and token event listener\n this.tokenCacheService.initialize();\n }\n\n unsubscribe(s: PassflowSubscriber, t?: PassflowEvent[]) {\n this.subscribeStore.unsubscribe(s, t);\n }\n\n // Token handling\n handleTokensRedirect(): Tokens | undefined {\n return this.checkAndSetTokens();\n }\n\n private checkAndSetTokens(): Tokens | undefined {\n const urlParams = new URLSearchParams(window.location.search);\n const access_token = urlParams.get('access_token');\n const refresh_token = urlParams.get('refresh_token');\n const id_token = urlParams.get('id_token');\n const scopes: string[] = urlParams.get('scopes')?.split(',') ?? this.scopes;\n let tokens: Tokens | undefined = undefined;\n\n if (access_token) {\n tokens = {\n access_token,\n refresh_token: refresh_token ?? undefined,\n id_token: id_token ?? undefined,\n scopes,\n };\n this.storageManager.saveTokens(tokens);\n this.tokenCacheService.setTokensCache(tokens);\n this.subscribeStore.notify(PassflowEvent.SignIn, { tokens, parsedTokens: this.getParsedTokenCache() });\n this.submitSessionCheck();\n\n urlParams.delete('access_token');\n urlParams.delete('refresh_token');\n urlParams.delete('id_token');\n urlParams.delete('client_challenge');\n\n if (urlParams.size > 0) {\n window.history.replaceState({}, document.title, `${window.location.pathname}?${urlParams.toString()}`);\n } else {\n window.history.replaceState({}, document.title, window.location.pathname);\n }\n this.error = undefined;\n return tokens;\n } else {\n this.error = this.checkErrorsFromURL();\n }\n return undefined;\n }\n\n private checkErrorsFromURL(): Error | undefined {\n const urlParams = new URLSearchParams(window.location.search);\n const error = urlParams.get('error');\n if (error) {\n return new Error(error);\n }\n return undefined;\n }\n\n private setTokensToCacheFromLocalStorage(): void {\n const tokens = this.storageManager.getTokens();\n if (tokens) {\n this.tokenCacheService.setTokensCache(tokens);\n }\n }\n\n getTokensCache() {\n return this.tokenCacheService.getTokensCache();\n }\n\n getTokensCacheWithRefresh() {\n return this.tokenCacheService.getTokensCacheWithRefresh();\n }\n\n getParsedTokenCache() {\n return this.tokenCacheService.getParsedTokenCache();\n }\n\n tokensCacheIsExpired() {\n return this.tokenCacheService.tokensCacheIsExpired();\n }\n\n // Auth delegation methods\n isAuthenticated(): boolean {\n const tokens = this.storageManager.getTokens();\n if (!tokens || !tokens.access_token) return false;\n\n const parsedTokens = {\n access_token: parseToken(tokens.access_token),\n refresh_token: tokens.refresh_token ? parseToken(tokens.refresh_token) : undefined,\n };\n\n return this.authService.isAuthenticated(parsedTokens);\n }\n\n async signIn(payload: PassflowSignInPayload): Promise<PassflowAuthorizationResponse> {\n const response = await this.authService.signIn(payload);\n\n return response;\n }\n\n async signUp(payload: PassflowSignUpPayload): Promise<PassflowAuthorizationResponse> {\n const response = await this.authService.signUp(payload);\n\n return response;\n }\n\n passwordlessSignIn(payload: PassflowPasswordlessSignInPayload): Promise<PassflowPasswordlessResponse> {\n return this.authService.passwordlessSignIn(payload);\n }\n\n async passwordlessSignInComplete(payload: PassflowPasswordlessSignInCompletePayload): Promise<PassflowValidationResponse> {\n const response = await this.authService.passwordlessSignInComplete(payload);\n\n return response;\n }\n\n async logOut(): Promise<void> {\n try {\n await this.authService.logOut();\n this.storageManager.deleteTokens();\n await this.submitSessionCheck();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to log out',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n }\n this.tokenCacheService.setTokensCache(undefined);\n this.subscribeStore.notify(PassflowEvent.SignOut, {});\n }\n\n federatedAuthWithPopup(payload: PassflowFederatedAuthPayload): void {\n this.authService.federatedAuthWithPopup(payload);\n }\n\n federatedAuthWithRedirect(payload: PassflowFederatedAuthPayload): void {\n this.authService.federatedAuthWithRedirect(payload);\n }\n\n reset(error?: string) {\n this.storageManager.deleteTokens();\n this.tokenCacheService.setTokensCache(undefined);\n this.subscribeStore.notify(PassflowEvent.SignOut, {});\n if (error) {\n this.error = new Error(error);\n const errorPayload: ErrorPayload = {\n message: error,\n code: 'RESET_ERROR',\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw this.error;\n }\n }\n\n async refreshToken(): Promise<PassflowAuthorizationResponse> {\n if (!this.tokenCacheService.parsedTokensCache?.refresh_token) {\n throw new Error('No refresh token found');\n }\n\n try {\n const response = await this.authService.refreshToken();\n\n return response;\n } catch (error) {\n if (error instanceof PassflowError) {\n throw error;\n } else {\n this.subscribeStore.notify(PassflowEvent.Error, {\n message: 'Failed to refresh token',\n originalError: error,\n });\n throw error;\n }\n }\n }\n\n sendPasswordResetEmail(payload: PassflowSendPasswordResetEmailPayload): Promise<PassflowSuccessResponse> {\n return this.authService.sendPasswordResetEmail(payload);\n }\n\n async resetPassword(newPassword: string, scopes?: string[]): Promise<PassflowAuthorizationResponse> {\n const response = await this.authService.resetPassword(newPassword, scopes);\n\n return response;\n }\n\n // App settings\n async getAppSettings(): Promise<AppSettings> {\n try {\n return await this.appApi.getAppSettings();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get app settings',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async getSettingsAll(): Promise<PassflowSettingsAll> {\n try {\n return await this.settingApi.getSettingsAll();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get all settings',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async getPasswordPolicySettings(): Promise<PassflowPasswordPolicySettings> {\n try {\n return await this.settingApi.getPasswordPolicySettings();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get password policy settings',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async getPasskeySettings(): Promise<PassflowPasskeySettings> {\n try {\n return await this.settingApi.getPasskeySettings();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get passkey settings',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n // Passkey methods\n async passkeyRegister(payload: PassflowPasskeyRegisterStartPayload): Promise<PassflowAuthorizationResponse> {\n const response = await this.authService.passkeyRegister(payload);\n\n return response;\n }\n\n async passkeyAuthenticate(payload: PassflowPasskeyAuthenticateStartPayload): Promise<PassflowAuthorizationResponse> {\n const response = await this.authService.passkeyAuthenticate(payload);\n\n return response;\n }\n\n // Token management\n setTokens(tokensData: Tokens): void {\n this.storageManager.saveTokens(tokensData);\n this.tokenCacheService.setTokensCache(tokensData);\n this.subscribeStore.notify(PassflowEvent.SignIn, {\n tokens: tokensData,\n parsedTokens: this.tokenCacheService.getParsedTokenCache(),\n });\n }\n\n // Add getTokens method\n async getTokens(doRefresh = false): Promise<Tokens | undefined> {\n return await this.authService.getTokens(doRefresh);\n }\n\n // Get token from storage by key\n getToken(tokenType: TokenType): string | undefined {\n return this.storageManager.getToken(tokenType);\n }\n\n // User passkey methods delegated to UserService\n async getUserPasskeys() {\n try {\n return await this.userService.getUserPasskeys();\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get user passkeys',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async renameUserPasskey(name: string, passkeyId: string): Promise<PassflowSuccessResponse> {\n try {\n return await this.userService.renameUserPasskey(name, passkeyId);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to rename user passkey',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async deleteUserPasskey(passkeyId: string): Promise<PassflowSuccessResponse> {\n try {\n return await this.userService.deleteUserPasskey(passkeyId);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to delete user passkey',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async addUserPasskey(options?: {\n relyingPartyId?: string;\n passkeyUsername?: string;\n passkeyDisplayName?: string;\n }): Promise<void> {\n try {\n return await this.userService.addUserPasskey(options);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to add user passkey',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n // Tenant methods delegated to TenantService\n /**\n * Join a tenant invitation\n * @param token The invitation token\n * @param scopes Optional scopes to request\n * @returns Promise with invite response\n */\n async joinInvitation(token: string, scopes?: string[]): Promise<PassflowAuthorizationResponse> {\n try {\n const response = await this.tenant.joinInvitation(token, scopes);\n response.scopes = scopes ?? this.scopes;\n this.storageManager.saveTokens(response);\n this.tokenCacheService.setTokensCache(response);\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to join invitation',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n /**\n * Create a new tenant\n * @param name The name of the tenant\n * @param refreshToken Whether to refresh the token after creating the tenant\n * @returns Promise with tenant response\n */\n async createTenant(name: string, refreshToken?: boolean): Promise<PassflowTenantResponse> {\n try {\n const response = await this.tenant.createTenant(name);\n if (refreshToken) {\n await this.refreshToken();\n }\n return response;\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to create tenant',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n // Invitation methods delegated to InvitationService\n async requestInviteLink(payload: RequestInviteLinkPayload): Promise<InviteLinkResponse> {\n try {\n // default is true\n if (payload.send_to_email === undefined) {\n payload.send_to_email = true;\n }\n return await this.invitationService.requestInviteLink(payload);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to request invite link',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n /**\n * Gets a list of active invitations\n * @param options Optional parameters for filtering and pagination\n * @returns Promise with paginated list of invitations\n */\n async getInvitations(options: {\n tenantID: string;\n groupID?: string;\n skip?: number | string;\n limit?: number | string;\n }): Promise<InvitationsPaginatedList> {\n try {\n return await this.invitationService.getInvitations(options);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get invitations',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async deleteInvitation(token: string): Promise<PassflowSuccessResponse> {\n try {\n return await this.invitationService.deleteInvitation(token);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to delete invitation',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async resendInvitation(token: string): Promise<PassflowSuccessResponse> {\n try {\n return await this.invitationService.resendInvitation(token);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to resend invitation',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n async getInvitationLink(invitationID: string): Promise<InviteLinkResponse> {\n try {\n return await this.invitationService.getInvitationLink(invitationID);\n } catch (error) {\n const errorPayload: ErrorPayload = {\n message: error instanceof Error ? error.message : 'Failed to get invitation link',\n originalError: error,\n };\n this.subscribeStore.notify(PassflowEvent.Error, errorPayload);\n throw error;\n }\n }\n\n // Auth redirect helpers\n authRedirectUrl(\n options: {\n url?: string;\n redirectUrl?: string;\n scopes?: string[];\n appId?: string;\n } = {},\n ): string {\n return this.authService.authRedirectUrl(options);\n }\n\n authRedirect(\n options: {\n url?: string;\n redirectUrl?: string;\n scopes?: string[];\n appId?: string;\n } = {},\n ): void {\n this.authService.authRedirect(options);\n }\n}\n"],"names":["APP_ID_HEADER_KEY","AUTHORIZATION_HEADER_KEY","DEVICE_ID_HEADER_KEY","DEVICE_TYPE_HEADER_KEY","DEFAULT_SCOPES","PASSFLOW_CLOUD_URL","DEFAULT_GROUP_NAME","parseMembership","raw","tenants","k","v","tnt","gk","roles","g","TokenService","StorageManager","ttype","tokenString","token","parseToken","isTokenExpired","tokenType","base64Url","base64","jsonPayload","c","parsedToken","TokenType","storage","prefix","tokens","id_token","access_token","refresh_token","scopes","key","access","deviceId","url","DeviceService","newDeviceId","uuidv4","RequestMethod","PassflowEndpointPaths","PassflowAdminEndpointPaths","PassflowError","error","Providers","OS","pathWithParams","template","params","result","value","AxiosClient","config","appId","keyStoragePrefix","axios","axiosConfig","controller","response","payload","e","endpoint","status","errorData","method","path","options","data","AuthAPI","refreshToken","accessToken","os","defaultPayload","create_tenant","anonymous","isAdmin","newPassword","resetToken","passkeyData","challengeId","otp","headers","AppAPI","SettingAPI","UserAPI","name","passkeyId","relyingPartyId","passkeyDisplayName","passkeyUsername","TenantAPI","tenantId","groupId","userId","role","roleId","limit","skip","inviteId","email","InvitationAPI","invitationID","PassflowEvent","PassflowStore","subscriber","events","eventSet","subscribedEvents","event","eventType","AuthService","authApi","deviceService","storageManager","subscribeStore","tokenCacheService","createTenantForNewUser","origin","sessionCallbacks","errorPayload","oldScopes","sscopes","challenge_id","publicKey","webauthn","startRegistration","responseRegisterComplete","startAuthentication","responseAuthenticateComplete","passflowPathWithProvider","queryParams","passflowURL","popupWindow","checkInterval","urlParams","tokensData","redirectUrl","externalUrl","parsedTokens","doRefresh","InvitationService","invitationAPI","ConsoleLogger","message","args","getDefaultLogger","TenantUserMembership","users","groups","memberships","r","uig","u","m","membership","TenantService","tenantAPI","logger","context","responseData","passflowError","UserService","userAPI","TokenCacheService","Passflow","createSession","expiredSession","s"],"mappings":"gKAAaA,EAAoB,sBACpBC,EAA2B,gBAC3BC,EAAuB,sBACvBC,EAAyB,wBACzBC,EAAiB,CAAC,KAAM,UAAW,SAAU,QAAS,OAAQ,SAAU,mBAAmB,EAC3FC,EAAqB,8BACrBC,EAAqB,UCiCrBC,EAAmBC,GAA2C,CACzE,MAAMC,EAA8B,CAAC,EACjC,IAAAC,EACJ,IAAKA,KAAKF,EAAK,CACP,MAAAG,EAAIH,EAAIE,CAAC,EACf,GAAIC,IAAM,OACR,SAEI,MAAAC,EAAwB,CAAE,OAAQ,CAAE,GAAID,EAAE,UAAW,KAAMA,EAAE,YAAc,EAC7EC,EAAA,OAASD,EAAE,OACX,OAAO,KAAKA,EAAE,MAAM,EAAE,IAAKE,GAAO,CAChC,MAAMC,EAAQH,EAAE,OAAOE,CAAE,GAAK,CAAC,EAC/B,MAAO,CAAE,MAAO,CAAE,GAAIA,EAAI,KAAMF,EAAE,cAAcE,CAAE,GAAK,SAAU,EAAG,MAAAC,CAAM,CAC3E,CAAA,EACD,CAAC,EACDF,EAAA,YAAcA,EAAI,QAAQ,KAAMG,GAAMA,EAAE,MAAM,KAAOJ,EAAE,aAAa,EACxEF,EAAQ,KAAKG,CAAG,CAAA,CAEX,MAAA,CAAE,IAAAJ,EAAK,QAAAC,CAAQ,CACxB,ECrDO,MAAMO,CAAa,CAAnB,aAAA,CACK,KAAA,eAAiB,IAAIC,CAAe,CAQ9C,mBAAmBC,EAA2B,CAC5C,MAAMC,EAAc,KAAK,eAAe,SAASD,CAAK,EAClD,GAAA,CAACC,EAAoB,MAAA,GAEnB,MAAAC,EAAQC,EAAWF,CAAW,EAC7B,OAAAC,EAAQE,EAAeF,CAAK,EAAI,EAAA,CAUzC,eAAeG,EAAyC,CACtD,MAAMH,EAAQ,KAAK,eAAe,SAASG,CAAS,EAChD,GAACH,EACL,OAAOC,EAAWD,CAAK,CAAA,CAE3B,CAQO,SAASE,EAAeF,EAAuB,CAEpD,OADwB,KAAK,MAAM,KAAK,MAAQ,GAAI,EAC3BA,EAAM,GACjC,CAQO,SAASC,EAAWF,EAA4B,CACrD,MAAMK,EAAYL,EAAY,MAAM,GAAG,EAAE,CAAC,EAE1C,GAAI,CAACK,EAAiB,MAAA,IAAI,MAAM,sBAAsB,EAChD,MAAAC,EAASD,EAAU,QAAQ,KAAM,GAAG,EAAE,QAAQ,KAAM,GAAG,EACvDE,EAAc,mBAClB,OACG,KAAKD,CAAM,EACX,MAAM,EAAE,EACR,IAAKE,GAAM,KAAO,KAAOA,EAAE,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,EAChE,KAAK,EAAE,CACZ,EAEMC,EAAc,KAAK,MAAMF,CAAW,EAC9B,OAAAE,EAAA,WACVA,EAAY,aAAeA,EAAY,OAAS,SAAWrB,EAAgBqB,EAAY,WAAW,EAAI,OACjGA,CACT,CC7CY,IAAAC,GAAAA,IACVA,EAAA,SAAW,WACXA,EAAA,aAAe,SACfA,EAAA,cAAgB,UAChBA,EAAA,aAAe,SACfA,EAAA,YAAc,QACdA,EAAA,WAAa,aACbA,EAAA,WAAa,aACbA,EAAA,OAAS,SACTA,EAAA,MAAQ,QATEA,IAAAA,GAAA,CAAA,CAAA,ECXL,MAAMZ,CAAe,CAS1B,YAAY,CAAE,QAAAa,EAAS,OAAAC,CAAO,EAA0B,CAAA,EAAI,CAR5D,KAAQ,iBAAmB,GAClB,KAAA,OAAS,GAAG,KAAK,gBAAgB,gBACjC,KAAA,SAAW,GAAG,KAAK,gBAAgB,mBACnC,KAAA,gBAAkB,GAAG,KAAK,gBAAgB,0BAC1C,KAAA,oBAAsB,GAAG,KAAK,gBAAgB,8BAKrD,KAAK,QAAUD,GAAW,aAC1B,KAAK,iBAAmBC,EAAS,GAAGA,CAAM,IAAM,EAAA,CAGlD,WAAWC,EAAsB,CAC/B,KAAM,CAAE,SAAAC,EAAU,aAAAC,EAAc,cAAAC,EAAe,OAAAC,CAAW,EAAAJ,EACtDC,QAAe,QAAQ,QAAQ,KAAK,mBAAmBJ,EAAU,QAAQ,EAAGI,CAAQ,EACpFC,QAAmB,QAAQ,QAAQ,KAAK,mBAAmBL,EAAU,YAAY,EAAGK,CAAY,EAChGC,QAAoB,QAAQ,QAAQ,KAAK,mBAAmBN,EAAU,aAAa,EAAGM,CAAa,EACnGC,QAAa,QAAQ,QAAQ,KAAK,OAAQA,EAAO,KAAK,GAAG,CAAC,CAAA,CAGhE,SAASb,EAA0C,CAC3C,MAAAc,EAAM,KAAK,mBAAmBd,CAAS,EAC7C,OAAO,KAAK,QAAQ,QAAQc,CAAG,GAAK,MAAA,CAGtC,WAAgC,CACxB,MAAAC,EAAS,KAAK,QAAQ,QAAQ,KAAK,mBAAmBT,EAAU,YAAY,CAAC,EAC/E,GAACS,EACE,MAAA,CACL,aAAcA,EACd,SAAU,KAAK,QAAQ,QAAQ,KAAK,mBAAmBT,EAAU,QAAQ,CAAC,GAAK,OAC/E,cAAe,KAAK,QAAQ,QAAQ,KAAK,mBAAmBA,EAAU,aAAa,CAAC,GAAK,OACzF,OAAQ,KAAK,QAAQ,QAAQ,KAAK,MAAM,GAAG,MAAM,GAAG,GAAK,MAC3D,CAAA,CAGF,WAAkC,CACzB,OAAA,KAAK,QAAQ,QAAQ,KAAK,MAAM,GAAG,MAAM,GAAG,GAAK,MAAA,CAG1D,YAAYN,EAA4B,CAChC,MAAAc,EAAM,KAAK,mBAAmBd,CAAS,EACxC,KAAA,QAAQ,WAAWc,CAAG,CAAA,CAG7B,cAAqB,CACnB,KAAK,QAAQ,WAAW,KAAK,mBAAmBR,EAAU,QAAQ,CAAC,EACnE,KAAK,QAAQ,WAAW,KAAK,mBAAmBA,EAAU,YAAY,CAAC,EACvE,KAAK,QAAQ,WAAW,KAAK,mBAAmBA,EAAU,aAAa,CAAC,EACnE,KAAA,QAAQ,WAAW,KAAK,MAAM,CAAA,CAGrC,aAAkC,CAChC,OAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ,GAAK,MAAA,CAGhD,YAAYU,EAAwB,CAClC,KAAK,QAAQ,QAAQ,KAAK,SAAUA,CAAQ,CAAA,CAG9C,gBAAuB,CAChB,KAAA,QAAQ,WAAW,KAAK,QAAQ,CAAA,CAGvC,mBAAmBnB,EAAqB,CACtC,KAAK,QAAQ,QAAQ,KAAK,gBAAiBA,CAAK,CAAA,CAGlD,oBAAyC,CACvC,OAAO,KAAK,QAAQ,QAAQ,KAAK,eAAe,GAAK,MAAA,CAGvD,uBAA8B,CACvB,KAAA,QAAQ,WAAW,KAAK,eAAe,CAAA,CAG9C,uBAAuBoB,EAAmB,CACxC,KAAK,QAAQ,QAAQ,KAAK,oBAAqBA,CAAG,CAAA,CAGpD,wBAA6C,CAC3C,OAAO,KAAK,QAAQ,QAAQ,KAAK,mBAAmB,GAAK,MAAA,CAG3D,2BAAkC,CAC3B,KAAA,QAAQ,WAAW,KAAK,mBAAmB,CAAA,CAG1C,mBAAmBjB,EAA8B,CACvD,MAAO,GAAG,KAAK,gBAAgB,GAAGA,CAAS,EAAA,CAE/C,CCvGO,MAAMkB,CAAc,CAGzB,aAAc,CACP,KAAA,eAAiB,IAAIxB,CAAe,CAG3C,aAAsB,CACd,MAAAsB,EAAW,KAAK,eAAe,YAAY,EACjD,GAAI,CAACA,EAAU,CACP,MAAAG,EAAc,KAAK,uBAAuB,EAC3C,YAAA,eAAe,YAAYA,CAAW,EACpCA,CAAA,CAEF,OAAAH,CAAA,CAGT,wBAAiC,CAC/B,OAAOI,KAAO,CAAA,CAElB,CCVY,IAAAC,GAAAA,IACVA,EAAA,IAAM,MACNA,EAAA,KAAO,OACPA,EAAA,IAAM,MACNA,EAAA,MAAQ,QACRA,EAAA,OAAS,SALCA,IAAAA,GAAA,CAAA,CAAA,EAQAC,GAAAA,IACVA,EAAA,OAAS,cACTA,EAAA,OAAS,iBACTA,EAAA,mBAAqB,yBACrBA,EAAA,aAAe,2BACfA,EAAA,qBAAuB,8BACvBA,EAAA,OAAS,eACTA,EAAA,QAAU,gBACVA,EAAA,uBAAyB,uBACzBA,EAAA,cAAgB,wBAChBA,EAAA,YAAc,gBACdA,EAAA,qBAAuB,+BACvBA,EAAA,wBAA0B,kCAC1BA,EAAA,yBAA2B,mCAC3BA,EAAA,4BAA8B,sCAC9BA,EAAA,gBAAkB,iBAClBA,EAAA,YAAc,YACdA,EAAA,uBAAyB,qBACzBA,EAAA,gBAAkB,oBAClBA,EAAA,YAAc,gBACdA,EAAA,eAAiB,0BACjBA,EAAA,uBAAyB,6BACzBA,EAAA,eAAiB,oBACjBA,EAAA,WAAa,eACbA,EAAA,gBAAkB,qCAClBA,EAAA,kBAAoB,eACpBA,EAAA,iBAAmB,6BACnBA,EAAA,iBAAmB,oCACnBA,EAAA,kBAAoB,kCA5BVA,IAAAA,GAAA,CAAA,CAAA,EA+BAC,GAAAA,IACVA,EAAA,qBAAuB,qCACvBA,EAAA,wBAA0B,wCAC1BA,EAAA,yBAA2B,yCAC3BA,EAAA,4BAA8B,4CAC9BA,EAAA,gBAAkB,uBAClBA,EAAA,OAAS,qBANCA,IAAAA,GAAA,CAAA,CAAA,EA0CL,MAAMC,UAAsB,KAAM,CAOvC,YAAYC,EAAuC,CAC3C,MAAA,EACD,KAAA,GAAKA,GAAO,IAAM,UAClB,KAAA,QAAUA,GAAO,SAAWA,GAAS,uBACrC,KAAA,OAASA,GAAO,QAAU,IAC1B,KAAA,SAAWA,GAAO,UAAY,UACnC,KAAK,KAAOA,GAAO,MAAY,IAAA,OAAO,YAAY,CAAA,CAEtD,CAiFY,IAAAC,GAAAA,IACVA,EAAA,OAAS,SACTA,EAAA,SAAW,WAFDA,IAAAA,GAAA,CAAA,CAAA,EAoEAC,GAAAA,IACVA,EAAA,IAAM,MADIA,IAAAA,GAAA,CAAA,CAAA,EAmQI,SAAAC,EAAeC,EAAkBC,EAAwC,CACvF,IAAIC,EAASF,EACN,cAAA,QAAQC,CAAM,EAAE,QAAQ,CAAC,CAAChB,EAAKkB,CAAK,IAAM,CAC/CD,EAASA,EAAO,QAAQ,IAAIjB,CAAG,GAAIkB,CAAK,CAAA,CACzC,EACMD,CACT,CC5eO,MAAME,CAAY,CAoBvB,YAAYC,EAAwB,CAhBpC,KAAQ,eAA+E,KAIvF,KAAA,OAAS,OAAO,SAAS,OAIzB,KAAU,eAAyC,CACjD,OAAQ,mBACR,eAAgB,kBAClB,EAEA,KAAiB,wBAA0B,CAAC,SAAU,YAAa,YAAY,EAC9D,KAAA,mBAAqB,CAAC,SAAU,SAAS,EAGxD,KAAM,CAAE,IAAAjB,EAAK,MAAAkB,EAAO,iBAAAC,CAAqB,EAAAF,EAEzC,KAAK,IAAMjB,GAAOnC,EAEb,KAAA,eAAiB,IAAIY,EAAe,CACvC,OAAQ0C,GAAoB,EAAA,CAC7B,EACI,KAAA,cAAgB,IAAIlB,EACpB,KAAA,aAAe,IAAIzB,EAEpB0C,IACF,KAAK,MAAQA,EAEb,KAAK,eAAiB,CACpB,GAAG,KAAK,eACR,CAAC1D,CAAiB,EAAG0D,CACvB,GAII,MAAAnB,EAAW,KAAK,cAAc,YAAY,EAChD,KAAK,eAAiB,CACpB,GAAG,KAAK,eACR,CAACrC,CAAoB,EAAGqC,EACxB,CAACpC,CAAsB,EAAG,KAC5B,EAEK,KAAA,SAAWyD,EAAM,OAAO,CAC3B,QAAS,KAAK,IACd,QAAS,CAAE,GAAG,KAAK,cAAe,CAAA,CACnC,EAED,KAAK,SAAS,aAAa,QAAQ,IAAI,MAAOC,GAA4C,CAExF,GAAI,KAAK,kBAAkBA,EAAY,GAAG,EACjC,OAAAA,EAIT,GAAIA,EAAY,KAAK,SAAS,SAAS,EAAG,CACxC,GAAI,KAAK,eAAgB,CACjB,MAAAC,EAAa,IAAI,gBACvB,OAAAA,EAAW,MAAM,EACjBD,EAAY,OAASC,EAAW,OACzBD,CAAA,CAEF,OAAAA,CAAA,CAIH,MAAA7B,EAAS,KAAK,eAAe,UAAU,EACvCI,EAAS,KAAK,eAAe,UAAU,EAE7C,GAAIJ,GAAQ,aAAc,CAClB,MAAAM,EAASjB,EAAWW,EAAO,YAAY,EAE7C,GAAIV,EAAegB,CAAM,GAAKN,EAAO,cAC/B,GAAA,CACF,GAAI,KAAK,eAAgB,CACjB+B,MAAAA,EAAW,MAAM,KAAK,eAC5B,OAAIA,EAAS,OACXF,EAAY,QAAQ5D,CAAwB,EAAI,UAAU8D,EAAS,KAAK,YAAY,IAE/EF,CAAA,CAGT,MAAMG,EAAU,CACd,cAAehC,EAAO,cACtB,OAAAI,CACF,EAEA,KAAK,eAAiB,KAAK,SAAS,KAAoCS,EAAsB,QAASmB,EAAS,CAC9G,QAAS,CACP,CAAC/D,CAAwB,EAAG,UAAU+B,EAAO,aAAa,EAAA,CAC5D,CACD,EAEK,MAAA+B,EAAW,MAAM,KAAK,eAE5B,OAAIA,EAAS,OACN,KAAA,eAAe,WAAWA,EAAS,IAAI,EAC5CF,EAAY,QAAQ5D,CAAwB,EAAI,UAAU8D,EAAS,KAAK,YAAY,IAG/EF,QACAb,EAAO,CACd,YAAK,eAAiB,KACf,QAAQ,OAAOA,CAAK,CAAA,QAC3B,CACA,KAAK,eAAiB,IAAA,CAI1B,OAAAa,EAAY,QAAQ5D,CAAwB,EAAI,UAAU+B,EAAO,YAAY,GAEtE6B,CAAA,CAEF,OAAAA,CAAA,CACR,EAEI,KAAA,SAAS,aAAa,SAAS,IACjCE,GAA4BA,EAC5BE,GAAkB,KAAK,iBAAiBA,CAAC,CAC5C,CAAA,CAGM,oBAAoBzB,EAAuB,CAC1C,OAAA,KAAK,mBAAmB,KAAM0B,GAAa1B,GAAK,SAAS0B,CAAQ,CAAC,CAAA,CAGnE,kBAAkB1B,EAAuB,CAC/C,OAAO,KAAK,wBAAwB,KAAM0B,GAAa1B,GAAK,SAAS0B,CAAQ,CAAC,GAAK,CAAC,KAAK,oBAAoB1B,CAAG,CAAA,CAKlH,MAAc,iBAAiB,EAAiC,CAE1D,GAAA,CAAC,EAAE,SACE,OAAA,QAAQ,OAAO,CAAC,EAGnB,MAAA2B,EAAS,EAAE,SAAS,OACpBC,EAAY,EAAE,SAAS,KAGzB,GAAA,UAAWA,GAAa,OAAOA,EAAU,OAAU,UAAYA,EAAU,QAAU,KAAM,CACrF,KAAA,CAAE,MAAApB,GAAUoB,EAElB,OAAO,QAAQ,OAAO,IAAIrB,EAAcC,CAAK,CAAC,CAAA,CAIhD,OAAO,QAAQ,OACb,IAAID,EAAc,CAChB,GAAI,cAAcoB,CAAM,GACxB,QAAS,EAAE,SAAW,oBACtB,OAAAA,EACA,SAAU,EAAE,QAAQ,KAAO,UAC3B,KAAM,IAAI,KAAK,EAAE,YAAY,CAC9B,CAAA,CACH,CAAA,CAGF,MAAc,KAAWE,EAAuBC,EAAcC,EAAyC,CAMrG,OALiB,MAAM,KAAK,SAAS,QAAW,CAC9C,OAAAF,EACA,IAAKC,EACL,GAAGC,CAAA,CACJ,GACe,IAAA,CAGlB,IAAOD,EAAcb,EAAyC,CAC5D,OAAO,KAAK,KAAKb,EAAc,IAAK0B,EAAMb,CAAM,CAAA,CAGlD,KAAWa,EAAcE,EAAUf,EAAyC,CACnE,OAAA,KAAK,KAAKb,EAAc,KAAM0B,EAAM,CAAE,KAAAE,EAAM,GAAGf,EAAQ,CAAA,CAGhE,IAAUa,EAAcE,EAAUf,EAAyC,CAClE,OAAA,KAAK,KAAKb,EAAc,IAAK0B,EAAM,CAAE,KAAAE,EAAM,GAAGf,EAAQ,CAAA,CAG/D,MAAYa,EAAcE,EAAUf,EAAyC,CACpE,OAAA,KAAK,KAAKb,EAAc,MAAO0B,EAAM,CAAE,KAAAE,EAAM,GAAGf,EAAQ,CAAA,CAGjE,OAAUa,EAAcb,EAAyC,CAC/D,OAAO,KAAK,KAAKb,EAAc,OAAQ0B,EAAMb,CAAM,CAAA,CAEvD,CChMO,MAAMgB,CAAQ,CAInB,YAAYhB,EAAwB,CAF1B,KAAA,eAAiB,IAAIxC,EAGxB,KAAA,YAAc,IAAIuC,EAAYC,CAAM,CAAA,CAG3C,aAAaiB,EAAsBtC,EAAkBuC,EAA8D,CACjH,MAAMX,EAAU,CACd,OAAQW,EACR,OAAAvC,CACF,EAEA,OAAO,KAAK,YAAY,KAAoDS,EAAsB,QAASmB,EAAS,CAClH,QAAS,CACP,CAAC/D,CAAwB,EAAG,UAAUyE,CAAY,EAAA,CACpD,CACD,CAAA,CAGH,OAAOV,EAAgCzB,EAAkBqC,EAAgD,CACvG,MAAMC,EAAgD,CACpD,GAAGb,EACH,OAAQzB,EACR,GAAAqC,CACF,EACA,OAAO,KAAK,YAAY,KACtB/B,EAAsB,OACtBgC,CACF,CAAA,CAGF,OAAOb,EAAwE,CACvE,KAAA,CAAE,cAAAc,EAAe,UAAAC,CAAA,EAAcf,EAC/Ba,EAAwC,CAC5C,GAAGb,EACH,cAAec,GAAiB,GAChC,UAAWC,GAAa,EAC1B,EACA,OAAO,KAAK,YAAY,KACtBlC,EAAsB,OACtBgC,CACF,CAAA,CAGF,mBACEb,EACAzB,EACAqC,EACuC,CACjC,KAAA,CAAE,cAAAE,GAAkBd,EACpBa,EAA4D,CAChE,GAAGb,EACH,cAAec,GAAiB,GAChC,OAAQvC,EACR,GAAAqC,CACF,EACA,OAAO,KAAK,YAAY,KACtB/B,EAAsB,aACtBgC,CACF,CAAA,CAGF,2BAA2Bb,EAAyF,CAClH,OAAO,KAAK,YAAY,KACtBnB,EAAsB,qBACtBmB,CACF,CAAA,CAGF,OAAOzB,EAAmBmC,EAAuBM,EAAU,GAAwC,CAC3F,MAAAhB,EAAWgB,EAA8D,OAApD,CAAE,cAAeN,EAAc,OAAQnC,GAC5D2B,EAAWc,EAAUlC,EAA2B,OAASD,EAAsB,OAErF,OAAO,KAAK,YAAY,KAA6CqB,EAAUF,CAAO,CAAA,CAGxF,uBAAuBA,EAAkF,CACvG,OAAO,KAAK,YAAY,KACtBnB,EAAsB,uBACtBmB,CACF,CAAA,CAGF,cAAciB,EAAqB7C,EAAkB8C,EAA6D,CAChH,MAAMlB,EAAU,CACd,SAAUiB,EACV,OAAA7C,CACF,EAEA,OAAO,KAAK,YAAY,KAAoDS,EAAsB,cAAemB,EAAS,CACxH,QAAS,CACP,CAAC/D,CAAwB,EAAG,UAAUiF,CAAU,GAChD,CAAClF,CAAiB,EAAG,MAAA,CACvB,CACD,CAAA,CAGH,qBACEgE,EACAzB,EACAqC,EACAI,EAAU,GACqB,CACzB,KAAA,CAAE,cAAAF,GAAkBd,EACpBa,EAA8D,CAClE,GAAGb,EACH,cAAec,GAAiB,GAChC,OAAQvC,EACR,GAAAqC,CACF,EAEMV,EAAWc,EAAUlC,EAA2B,qBAAuBD,EAAsB,qBAEnG,OAAO,KAAK,YAAY,KAAwEqB,EAAUW,CAAc,CAAA,CAG1H,wBACEM,EACA5C,EACA6C,EACAJ,EAAU,GAC8B,CACxC,MAAMhB,EAA0C,CAC9C,aAAcoB,EACd,OAAQ7C,EACR,aAAc4C,CAChB,EAEMjB,EAAWc,EACblC,EAA2B,wBAC3BD,EAAsB,wBAE1B,OAAO,KAAK,YAAY,KAAoEqB,EAAUF,CAAO,CAAA,CAG/G,yBACEA,EACAzB,EACAqC,EACAI,EAAU,GACqB,CAC/B,MAAMH,EAAkE,CACtE,GAAGb,EACH,QAASA,EAAQ,SAAW,GAC5B,OAAQzB,EACR,GAAAqC,CACF,EAEMV,EAAWc,EACblC,EAA2B,yBAC3BD,EAAsB,yBAE1B,OAAO,KAAK,YAAY,KACtBqB,EACAW,CACF,CAAA,CAGF,4BACEM,EACA5C,EACA6C,EACAJ,EAAU,GAC8B,CACxC,MAAMhB,EAA8C,CAClD,aAAcoB,EACd,OAAQ7C,EACR,aAAc4C,CAChB,EAEMjB,EAAWc,EACblC,EAA2B,4BAC3BD,EAAsB,4BAE1B,OAAO,KAAK,YAAY,KAAwEqB,EAAUF,CAAO,CAAA,CAGnH,gBACEqB,EACA9C,EACA6C,EACAJ,EAAU,GACVtB,EACqC,CACrC,MAAMM,EAAmC,CACvC,IAAAqB,EACA,OAAQ9C,EACR,aAAc6C,CAChB,EAEA,IAAIlB,EACFrB,EAAsB,gBACpB,CAACa,GAASsB,IACZd,EAAWpB,EAA2B,iBAGlC,MAAAwC,EAAU5B,EAAQ,CAAE,CAAC1D,CAAiB,EAAG0D,GAAU,CAAC,EAE1D,OAAO,KAAK,YAAY,KAA0DQ,EAAUF,EAAS,CAAE,QAAAsB,EAAS,CAAA,CAEpH,CCxOO,MAAMC,CAAO,CAGlB,YAAY9B,EAAwB,CAC7B,KAAA,YAAc,IAAID,EAAYC,CAAM,CAAA,CAG3C,gBAAuC,CACrC,OAAO,KAAK,YAAY,IAAiBZ,EAAsB,WAAW,CAAA,CAE9E,CCJO,MAAM2C,CAAW,CAGtB,YAAY/B,EAAwB,CAC7B,KAAA,YAAc,IAAID,EAAYC,CAAM,CAAA,CAG3C,gBAA+C,CAC7C,OAAO,KAAK,YAAY,IAAyBZ,EAAsB,WAAW,CAAA,CAGpF,2BAAqE,CACnE,OAAO,KAAK,YAAY,IAAoCA,EAAsB,sBAAsB,CAAA,CAG1G,oBAAuD,CACrD,OAAO,KAAK,YAAY,IAA6BA,EAAsB,eAAe,CAAA,CAE9F,CCdO,MAAM4C,CAAQ,CAGnB,YAAYhC,EAAwB,CAC7B,KAAA,YAAc,IAAID,EAAYC,CAAM,CAAA,CAG3C,iBAAkB,CAChB,OAAO,KAAK,YAAY,IAA2BZ,EAAsB,WAAW,CAAA,CAGtF,kBAAkB6C,EAAcC,EAAqD,CACnF,OAAO,KAAK,YAAY,MACtB,GAAG9C,EAAsB,WAAW,IAAI8C,CAAS,GACjD,CACE,KAAAD,CAAA,CAEJ,CAAA,CAGF,kBAAkBC,EAAqD,CAC9D,OAAA,KAAK,YAAY,OAAgC,GAAG9C,EAAsB,WAAW,IAAI8C,CAAS,EAAE,CAAA,CAG7G,oBAAoB,CAClB,eAAAC,EACA,SAAArD,EACA,GAAAqC,EACA,mBAAAiB,EACA,gBAAAC,CAAA,EAOgC,CAChC,MAAM9B,EAAU,CACd,qBAAsB6B,EACtB,iBAAkBC,EAClB,iBAAkBF,EAClB,SAAArD,EACA,GAAAqC,CACF,EAEA,OAAO,KAAK,YAAY,KAA2C/B,EAAsB,eAAgBmB,CAAO,CAAA,CAGlH,uBAAuBmB,EAAuC5C,EAAkB6C,EAAoC,CAClH,OAAO,KAAK,YAAY,KAA2CvC,EAAsB,uBAAwB,CAC/G,aAAcuC,EACd,OAAQ7C,EACR,aAAc4C,CAAA,CACf,CAAA,CAEL,CC6BO,MAAMY,CAAU,CAGrB,YAAYtC,EAAwB,CAC7B,KAAA,YAAc,IAAID,EAAYC,CAAM,CAAA,CAG3C,eAAerC,EAAegB,EAA0D,CACtF,MAAM4B,EAAU,CACd,aAAc5C,EACd,OAAAgB,CACF,EAEA,OAAO,KAAK,YAAY,KACtBS,EAAsB,eACtBmB,CACF,CAAA,CAGF,aAAa0B,EAA+C,CAC1D,MAAM1B,EAAU,CACd,KAAA0B,CACF,EACA,OAAO,KAAK,YAAY,KACtB7C,EAAsB,WACtBmB,CACF,CAAA,CASF,iBAAiBgC,EAAmD,CAClE,MAAM1B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,GACrD,OAAA,KAAK,YAAY,IAA4B1B,CAAI,CAAA,CAQ1D,aAAa0B,EAAkBN,EAA+C,CAC5E,MAAMpB,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,GACtDhC,EAAuC,CAAE,KAAA0B,CAAK,EACpD,OAAO,KAAK,YAAY,IAAyDpB,EAAMN,CAAO,CAAA,CAOhG,aAAagC,EAAmD,CAC9D,MAAM1B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,GACrD,OAAA,KAAK,YAAY,OAA+B1B,CAAI,CAAA,CAM7D,yBAAyE,CACvE,OAAO,KAAK,YAAY,IAA0CzB,EAAsB,UAAU,CAAA,CAUpG,YAAYmD,EAAkBN,EAA8C,CAC1E,MAAMpB,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,SACtDhC,EAAsC,CAAE,KAAA0B,CAAK,EACnD,OAAO,KAAK,YAAY,KAAwDpB,EAAMN,CAAO,CAAA,CAQ/F,aAAagC,EAAkBC,EAAiD,CAC9E,MAAM3B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,GACtE,OAAA,KAAK,YAAY,IAA2B3B,CAAI,CAAA,CASzD,YAAY0B,EAAkBC,EAAiBP,EAA8C,CAC3F,MAAMpB,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,GACvEjC,EAAsC,CAAE,KAAA0B,CAAK,EACnD,OAAO,KAAK,YAAY,IAAuDpB,EAAMN,CAAO,CAAA,CAQ9F,YAAYgC,EAAkBC,EAAkD,CAC9E,MAAM3B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,GACtE,OAAA,KAAK,YAAY,OAA+B3B,CAAI,CAAA,CAU7D,eAAe0B,EAAkBC,EAAiBC,EAAgBC,EAA+C,CAC/G,MAAM7B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,OACvEjC,EAAyC,CAAE,QAASkC,EAAQ,KAAAC,CAAK,EACvE,OAAO,KAAK,YAAY,KAA4D7B,EAAMN,CAAO,CAAA,CAUnG,yBACEgC,EACAC,EACAC,EACApF,EACiC,CACjC,MAAMwD,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,gBACvEjC,EAA0C,CAAE,QAASkC,EAAQ,MAAApF,CAAM,EACzE,OAAO,KAAK,YAAY,KAA6DwD,EAAMN,CAAO,CAAA,CAUpG,gBAAgBgC,EAAkBC,EAAiBC,EAAgBpF,EAAkD,CACnH,MAAMwD,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,UACvEjC,EAA0C,CAAE,QAASkC,EAAQ,MAAApF,CAAM,EACzE,OAAO,KAAK,YAAY,KAA6DwD,EAAMN,CAAO,CAAA,CASpG,oBAAoBgC,EAAkBC,EAAiBC,EAAiD,CAChG,MAAA5B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,IAAIC,CAAM,GAChF,OAAA,KAAK,YAAY,OAA+B5B,CAAI,CAAA,CAS7D,kBAAkB0B,EAAmD,CACnE,MAAM1B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,QACrD,OAAA,KAAK,YAAY,IAA4B1B,CAAI,CAAA,CAQ1D,oBAAoB0B,EAAkBN,EAA6C,CACjF,MAAMpB,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,QACtDhC,EAAqC,CAAE,KAAA0B,CAAK,EAClD,OAAO,KAAK,YAAY,KAAsDpB,EAAMN,CAAO,CAAA,CAS7F,WAAWgC,EAAkBI,EAAgBV,EAA6C,CACxF,MAAMpB,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,SAASI,CAAM,GACrEpC,EAAqC,CAAE,KAAA0B,CAAK,EAClD,OAAO,KAAK,YAAY,IAAqDpB,EAAMN,CAAO,CAAA,CAQ5F,WAAWgC,EAAkBI,EAAiD,CAC5E,MAAM9B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,SAASI,CAAM,GACpE,OAAA,KAAK,YAAY,OAA+B9B,CAAI,CAAA,CAU7D,qBAAqB0B,EAAkBE,EAAiD,CACtF,MAAM5B,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,SAASE,CAAM,GACpE,OAAA,KAAK,YAAY,OAA+B5B,CAAI,CAAA,CAY7D,oBAAoB0B,EAAkBC,EAAiBI,EAAeC,EAAoD,CACxH,MAAMhC,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,eACtE,OAAA,KAAK,YAAY,IAAiC3B,EAAM,CAC7D,OAAQ,CAAE,MAAA+B,EAAO,KAAAC,CAAK,CAAA,CACvB,CAAA,CASH,qBAAqBN,EAAkBK,EAAeC,EAAoD,CACxG,MAAMhC,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,eACrD,OAAA,KAAK,YAAY,IAAiC1B,EAAM,CAC7D,OAAQ,CAAE,MAAA+B,EAAO,KAAAC,CAAK,CAAA,CACvB,CAAA,CASH,qBAAqBN,EAAkBC,EAAiBM,EAAkD,CAClG,MAAAjC,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,WAAWM,CAAQ,GACzF,OAAA,KAAK,YAAY,OAA8BjC,CAAI,CAAA,CAS5D,wBAAwB0B,EAAkBC,EAAiBO,EAA+C,CAClG,MAAAlC,EAAO,GAAGzB,EAAsB,UAAU,IAAImD,CAAQ,UAAUC,CAAO,iBAAiBO,CAAK,GAC5F,OAAA,KAAK,YAAY,OAA8BlC,CAAI,CAAA,CAE9D,CCjUO,MAAMmC,CAAc,CAGzB,YAAYhD,EAAwB,CAC7B,KAAA,YAAc,IAAID,EAAYC,CAAM,CAAA,CAQ3C,kBAAkBO,EAAgE,CAChF,OAAO,KAAK,YAAY,KACtBnB,EAAsB,kBACtBmB,CACF,CAAA,CAQF,eAAeO,EAKuB,CACpC,MAAMlB,EAAiC,CAAC,EAEpCkB,EAAQ,UAASlB,EAAO,SAAWkB,EAAQ,QAAQ,SAAS,GAC5DA,EAAQ,OAAS,WAAkB,KAAOA,EAAQ,KAAK,SAAS,GAChEA,EAAQ,QAAU,WAAkB,MAAQA,EAAQ,MAAM,SAAS,GAEjE,MAAAD,EAAOnB,EAAeN,EAAsB,gBAAiB,CACjE,SAAU0B,EAAQ,QAAA,CACnB,EAEM,OAAA,KAAK,YAAY,IAA4BD,EAAM,CAAE,OAAAjB,EAAQ,EAAE,KAAMU,IAAc,CACxF,QAASA,EAAS,QAClB,aAAcA,EAAS,cAAA,EACvB,CAAA,CAQJ,iBAAiB2C,EAAwD,CACjE,MAAApC,EAAOnB,EAAeN,EAAsB,iBAAkB,CAClE,aAAA6D,CAAA,CACD,EACM,OAAA,KAAK,YAAY,OAAgCpC,CAAI,CAAA,CAQ9D,iBAAiBoC,EAAwD,CACjE,MAAApC,EAAOnB,EAAeN,EAAsB,iBAAkB,CAClE,aAAA6D,CAAA,CACD,EACD,OAAO,KAAK,YAAY,KAAuCpC,EAAM,CAAA,CAAE,CAAA,CAQzE,kBAAkBoC,EAAmD,CAC7D,MAAApC,EAAOnB,EAAeN,EAAsB,kBAAmB,CACnE,aAAA6D,CAAA,CACD,EACM,OAAA,KAAK,YAAY,IAAwBpC,CAAI,CAAA,CAExD,CC7HY,IAAAqC,GAAAA,IACVA,EAAA,OAAS,SACTA,EAAA,YAAc,eACdA,EAAA,SAAW,WACXA,EAAA,cAAgB,iBAChBA,EAAA,QAAU,UACVA,EAAA,MAAQ,QACRA,EAAA,QAAU,UACVA,EAAA,aAAe,gBACfA,EAAA,kBAAoB,sBATVA,IAAAA,GAAA,CAAA,CAAA,EA+CL,MAAMC,CAAc,CAApB,aAAA,CACG,KAAA,gBAAsE,GAAI,CAOlF,UAAUC,EAAgCC,EAAgC,CACxE,GAAIA,GAAQ,OAAQ,CACZ,MAAAC,EAAW,IAAI,IAAmBD,CAAM,EACzC,KAAA,YAAY,IAAID,EAAYE,CAAQ,CAAA,MAEpC,KAAA,YAAY,IAAIF,EAAY,IAAI,CACvC,CAQF,YAAYA,EAAgCC,EAAgC,CACtE,GAAA,CAACA,GAAQ,OAAQ,CACd,KAAA,YAAY,OAAOD,CAAU,EAClC,MAAA,CAGF,MAAMG,EAAmB,KAAK,YAAY,IAAIH,CAAU,EACnDG,IAILF,EAAO,QAASG,GAAUD,EAAiB,OAAOC,CAAK,CAAC,EACpDD,EAAiB,OAAS,GACvB,KAAA,YAAY,OAAOH,CAAU,EACpC,CAQF,OAAgCK,EAAclD,EAAyC,CACrF,KAAK,YAAY,QAAQ,CAAC8C,EAAQD,IAAe,EAC3C,CAACC,GAAUA,EAAO,IAAII,CAAS,IACtBL,EAAA,eAAeK,EAAWlD,CAAO,CAC9C,CACD,CAAA,CAEL,CCzEO,MAAMmD,CAAY,CACvB,YACUC,EACAC,EACAC,EACAC,EACAC,EACApF,EACAqF,EACAC,EACAlF,EACAmF,EAIAjE,EACR,CAdQ,KAAA,QAAA0D,EACA,KAAA,cAAAC,EACA,KAAA,eAAAC,EACA,KAAA,eAAAC,EACA,KAAA,kBAAAC,EACA,KAAA,OAAApF,EACA,KAAA,uBAAAqF,EACA,KAAA,OAAAC,EACA,KAAA,IAAAlF,EACA,KAAA,iBAAAmF,EAIA,KAAA,MAAAjE,CAAA,CAGV,MAAM,OAAOM,EAAwE,CAC9E,KAAA,eAAe,OAAO2C,EAAc,YAAa,CAAE,MAAO3C,EAAQ,MAAO,EACxE,MAAAzB,EAAW,KAAK,cAAc,YAAY,EAC1CqC,EAAK1B,EAAG,IACNc,EAAA,OAASA,EAAQ,QAAU,KAAK,OAEpC,GAAA,CACF,MAAMD,EAAW,MAAM,KAAK,QAAQ,OAAOC,EAASzB,EAAUqC,CAAE,EAChE,OAAAb,EAAS,OAASC,EAAQ,OACrB,KAAA,eAAe,WAAWD,CAAQ,EAClC,KAAA,kBAAkB,eAAeA,CAAQ,EACzC,KAAA,eAAe,OAAO4C,EAAc,OAAQ,CAC/C,OAAQ5C,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,MAAM,KAAK,mBAAmB,EACvBA,QACAf,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,iBAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,OAAOgB,EAAwE,CAC9E,KAAA,eAAe,OAAO2C,EAAc,cAAe,CAAE,MAAO3C,EAAQ,KAAK,MAAO,EAC7EA,EAAA,OAASA,EAAQ,QAAU,KAAK,OACxCA,EAAQ,cAAgB,KAAK,uBAEzB,GAAA,CACF,MAAMD,EAAW,MAAM,KAAK,QAAQ,OAAOC,CAAO,EAClD,OAAAD,EAAS,OAASC,EAAQ,OACrB,KAAA,eAAe,WAAWD,CAAQ,EAClC,KAAA,kBAAkB,eAAeA,CAAQ,EACzC,KAAA,eAAe,OAAO4C,EAAc,SAAU,CACjD,OAAQ5C,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,MAAM,KAAK,mBAAmB,EACvBA,QACAf,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,iBAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,mBAAmBgB,EAAmF,CACrG,KAAA,eAAe,OAAO2C,EAAc,YAAa,CAAE,MAAO3C,EAAQ,MAAO,EACtEA,EAAA,OAASA,EAAQ,QAAU,KAAK,OAClC,MAAAzB,EAAW,KAAK,cAAc,YAAY,EAC1CqC,EAAK1B,EAAG,IAEV,GAAA,CAIK,OAHU,MAAM,KAAK,QAAQ,mBAAmBc,EAASzB,EAAUqC,CAAE,QAIrE5B,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,2CAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,2BAA2BgB,EAAyF,CACxH,KAAK,eAAe,OAAO2C,EAAc,YAAa,CAAA,CAAE,EAChD3C,EAAA,OAASA,EAAQ,QAAU,KAAK,OAChCA,EAAA,OAAS,KAAK,cAAc,YAAY,EAE5C,GAAA,CACF,MAAMD,EAAW,MAAM,KAAK,QAAQ,2BAA2BC,CAAO,EACtE,OAAAD,EAAS,OAASC,EAAQ,OACrB,KAAA,eAAe,WAAWD,CAAQ,EAClC,KAAA,kBAAkB,eAAeA,CAAQ,EACzC,KAAA,eAAe,OAAO4C,EAAc,OAAQ,CAC/C,OAAQ5C,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,MAAM,KAAK,mBAAmB,EACvBA,QACAf,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,8BAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,QAAS,CACb,MAAM0B,EAAe,KAAK,eAAe,SAAS7C,EAAU,aAAa,EACnEU,EAAW,KAAK,eAAe,YAAY,EAE7C,GAAA,CAEE,IADa,MAAM,KAAK,QAAQ,OAAOA,EAAUmC,EAAc,CAAC,KAAK,KAAK,GACjE,SAAW,KAChB,MAAA,IAAI,MAAM,eAAe,EAEjC,KAAK,eAAe,aAAa,EACjC,KAAK,eAAe,OAAOiC,EAAc,QAAS,CAAA,CAAE,QAC7C3D,EAAO,CAEd,cAAQ,MAAMA,CAAK,EACbA,CAAA,CACR,CAGF,MAAM,cAAuD,CAC3D,KAAK,eAAe,OAAO2D,EAAc,aAAc,CAAA,CAAE,EACnD,MAAA3E,EAAS,KAAK,eAAe,UAAU,EAC7C,GAAKA,GAQL,GAAW,CAACA,GAAQ,cAAe,CAC3B,MAAAgB,EAAQ,IAAI,MAAM,wBAAwB,EAC1C4E,EAA6B,CACjC,QAAS,yBACT,cAAe5E,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,MAfK,CACL,MAAAA,EAAQ,IAAI,MAAM,iBAAiB,EACnC4E,EAA6B,CACjC,QAAS,kBACT,cAAe5E,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CAWF,MAAA6E,EAAY7F,GAAQ,QAAU,KAAK,OACrC,GAAA,CACI,MAAA+B,EAAW,MAAM,KAAK,QAAQ,aAAa/B,GAAQ,eAAiB,GAAI6F,EAAW7F,GAAQ,YAAY,EAC7G,OAAA+B,EAAS,OAAS8D,EACb,KAAA,eAAe,WAAW9D,CAAQ,EAClC,KAAA,kBAAkB,eAAeA,CAAQ,EACzC,KAAA,eAAe,OAAO4C,EAAc,QAAS,CAChD,OAAQ5C,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,KAAK,eAAe,OAAO4C,EAAc,kBAAmB,CAAE,UAAW,GAAO,EAChF,KAAK,kBAAkB,aAAe,GACtC,KAAK,kBAAkB,UAAY,GACnC,KAAK,kBAAkB,gBAAgB,EAChC5C,QACAf,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,uBAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,OAClD,QACEY,EAAM,aAAaZ,CAAK,GAAKA,EAAM,SAC/B,CACE,OAAQA,EAAM,SAAS,OACvB,KAAMA,EAAM,SAAS,IAAA,EAEvB,MACR,EAGA,MAFA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EAExD5E,aAAiBD,EACbC,EACGY,EAAM,aAAaZ,CAAK,GAAKA,EAAM,UAAYA,EAAM,UAAU,QAAU,KAAOA,EAAM,UAAU,OAAS,IAC5G,IAAI,MAAM,uDAAuDA,EAAM,SAAS,MAAM,EAAE,EAExFA,CACR,CACF,CAGF,MAAM,uBAAuBgB,EAAkF,CACzG,GAAA,CACF,OAAO,MAAM,KAAK,QAAQ,uBAAuBA,CAAO,QACjDhB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,sCAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,cAAciC,EAAqB7C,EAA2D,CAClG,KAAK,eAAe,OAAOuE,EAAc,YAAa,CAAA,CAAE,EAExD,MAAMzB,EADY,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAC/B,IAAI,OAAO,GAAK,OACvC4C,EAAU1F,GAAU,KAAK,OAE3B,GAAA,CACF,MAAM2B,EAAW,MAAM,KAAK,QAAQ,cAAckB,EAAa6C,EAAS5C,CAAU,EAClF,OAAAnB,EAAS,OAAS+D,EACb,KAAA,eAAe,WAAW/D,CAAQ,EAClC,KAAA,kBAAkB,eAAeA,CAAQ,EACzC,KAAA,eAAe,OAAO4C,EAAc,OAAQ,CAC/C,OAAQ5C,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,MAAM,KAAK,mBAAmB,EACvBA,QACAf,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,wBAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,gBAAgBgB,EAAsF,CAC1G,KAAK,eAAe,OAAO2C,EAAc,cAAe,CAAA,CAAE,EACpD,MAAApE,EAAW,KAAK,cAAc,YAAY,EAC1CqC,EAAK1B,EAAG,IACNc,EAAA,OAASA,EAAQ,QAAU,KAAK,OACxCA,EAAQ,cAAgB,KAAK,uBAEzB,GAAA,CACF,KAAM,CAAE,aAAA+D,EAAc,UAAAC,GAAc,MAAM,KAAK,QAAQ,qBAAqBhE,EAASzB,EAAUqC,EAAI,CAAC,KAAK,KAAK,EAE9GoD,EAAU,KAAK,GAAK,KAAKA,EAAU,KAAK,EAAE,EACpC,MAAAC,EAAW,MAAMC,oBAAkB,CACvC,YAAaF,CAAA,CACd,EAEKG,EAA2B,MAAM,KAAK,QAAQ,wBAClDF,EACA1F,EACAwF,EACA,CAAC,KAAK,KACR,EACA,OAAAI,EAAyB,OAASnE,EAAQ,OACrC,KAAA,eAAe,WAAWmE,CAAwB,EAClD,KAAA,kBAAkB,eAAeA,CAAwB,EACzD,KAAA,eAAe,OAAOxB,EAAc,SAAU,CACjD,OAAQwB,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,MAAM,KAAK,mBAAmB,EACvBA,QACAnF,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,8BAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,oBAAoBgB,EAA0F,CAClH,KAAK,eAAe,OAAO2C,EAAc,YAAa,CAAA,CAAE,EAClD,MAAApE,EAAW,KAAK,cAAc,YAAY,EAC1CqC,EAAK1B,EAAG,IACNc,EAAA,OAASA,EAAQ,QAAU,KAAK,OAEpC,GAAA,CACF,KAAM,CAAE,aAAA+D,EAAc,UAAAC,GAAc,MAAM,KAAK,QAAQ,yBAAyBhE,EAASzB,EAAUqC,EAAI,CAAC,KAAK,KAAK,EAC5GqD,EAAW,MAAMG,sBAAoB,CACzC,YAAaJ,CAAA,CACd,EAEKK,EAA+B,MAAM,KAAK,QAAQ,4BACtDJ,EACA1F,EACAwF,EACA,CAAC,KAAK,KACR,EAEA,MAAI,iBAAkBM,IACpBA,EAA6B,OAASrE,EAAQ,OACzC,KAAA,eAAe,WAAWqE,CAA4B,EACtD,KAAA,kBAAkB,eAAeA,CAA4B,EAC7D,KAAA,eAAe,OAAO1B,EAAc,OAAQ,CAC/C,OAAQ0B,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,MAAM,KAAK,mBAAmB,GAGzBA,QACArF,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,gCAClD,cAAeA,EACf,KAAMA,aAAiBD,EAAgBC,EAAM,GAAK,MACpD,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,uBAAuBgB,EAAuD,CACtE,MAAAsE,EAA2B,yBAAyBtE,EAAQ,QAAQ,GAE1E,GAAI,CAAC,KAAK,MAAa,MAAA,IAAI,MAAM,sCAAsC,EAGvE,MAAMX,EAAiC,CACrC,QAHcW,EAAQ,QAAU,KAAK,QAGrB,KAAK,GAAG,EACxB,aAAcA,EAAQ,cAAgB,KAAK,OAC3C,MAAO,KAAK,MACZ,GAAIA,EAAQ,aAAe,CAAE,aAAcA,EAAQ,YAAA,EAAiB,CAAC,EACrE,GAAIA,EAAQ,cAAgB,CAAE,cAAeA,EAAQ,cAAc,SAAW,CAAA,EAAI,CAAC,EACnF,GAAIA,EAAQ,OAAS,CAAE,OAAQA,EAAQ,MAAA,EAAW,CAAA,CACpD,EAEMxB,EAAM,IAAI,IAAI8F,EAA0B,KAAK,GAAG,EAChDC,EAAc,IAAI,gBAAgBlF,CAAM,EAC1C,OAAAb,EAAA,OAAS+F,EAAY,SAAS,EAE3B/F,EAAI,SAAS,CAAA,CAGtB,uBAAuBwB,EAA6C,CAC7D,KAAA,eAAe,OAAO2C,EAAc,YAAa,CAAE,SAAU3C,EAAQ,SAAU,EAC9E,MAAA8D,EAAU9D,EAAQ,QAAU,KAAK,OACjCzB,EAAW,KAAK,cAAc,YAAY,EAC1CiG,EAAc,KAAK,uBAAuB,CAAE,GAAGxE,EAAS,OAAQ8D,EAAS,OAAQvF,EAAU,EAE3FkG,EAAc,OAAO,KAAKD,EAAa,SAAU,sBAAsB,EAE7E,GAAI,CAACC,EACH,KAAK,0BAA0BzE,CAAO,MACjC,CACC,MAAA0E,EAAgB,YAAY,IAAM,CACtC,GAAID,EAAY,SAAS,KAAK,WAAW,KAAK,MAAM,EAAG,CACrD,MAAME,EAAY,IAAI,gBAAgBF,EAAY,SAAS,MAAM,EAC3DvG,EAAeyG,EAAU,IAAI,cAAc,GAAK,GAChDxG,EAAgBwG,EAAU,IAAI,eAAe,GAAK,GAClD1G,EAAW0G,EAAU,IAAI,UAAU,GAAK,GAExCC,EAAa,CACjB,aAAA1G,EACA,cAAAC,EACA,SAAAF,EACA,OAAQ6F,CACV,EACK,KAAA,eAAe,WAAWc,CAAU,EACpC,KAAA,kBAAkB,eAAeA,CAAU,EAC3C,KAAA,eAAe,OAAOjC,EAAc,OAAQ,CAC/C,OAAQiC,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,EACD,OAAO,SAAS,KAAO,GAAG,KAAK,MAAM,GACrC,cAAcF,CAAa,EAC3BD,EAAY,MAAM,CAAA,GAEnB,GAAG,CAAA,CACR,CAGF,0BAA0BzE,EAA6C,CAChE,KAAA,eAAe,OAAO2C,EAAc,YAAa,CAAE,SAAU3C,EAAQ,SAAU,EAC9E,MAAA8D,EAAU9D,EAAQ,QAAU,KAAK,OACjCzB,EAAW,KAAK,cAAc,YAAY,EAC1CiG,EAAc,KAAK,uBAAuB,CAAE,GAAGxE,EAAS,OAAQ8D,EAAS,OAAQvF,EAAU,EACjG,OAAO,SAAS,KAAOiG,CAAA,CAIzB,gBACEjE,EAKI,GACI,CACJ,GAAA,CACF,KAAM,CAAE,IAAA/B,EAAK,YAAAqG,EAAa,OAAAzG,EAAQ,MAAAsB,CAAM,EAAIa,GAAW,CAAC,EAClDuE,EAAc,IAAI,IAAItG,GAAO,KAAK,GAAG,EAE/BsG,EAAA,UAAYA,EAAY,SAAS,SAAS,GAAG,EAAIA,EAAY,SAAWA,EAAY,SAAW,KAAO,MAC5G,MAAAhB,EAAU1F,GAAU,KAAK,OACzBiB,EAAiC,CACrC,MAAOK,GAAS,KAAK,OAAS,GAC9B,WAAYmF,GAAe,OAAO,SAAS,KAC3C,OAAQf,EAAQ,KAAK,GAAG,CAC1B,EAEMS,EAAc,IAAI,gBAAgBlF,CAAM,EAClC,OAAAyF,EAAA,OAASP,EAAY,SAAS,EACnCO,EAAY,SAAS,QACrB9F,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,qCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,aACEuB,EAKI,GACE,CACF,GAAA,CACF,OAAO,SAAS,KAAO,KAAK,gBAAgBA,CAAO,QAC5CvB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,kCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAMF,gBAAgB+F,EAAqC,CAC/C,GAAA,CACE,OAACA,EAGH,CAACzH,EAAeyH,EAAa,YAAY,GACxC,CAAC,CAACA,EAAa,eAAiB,CAACzH,EAAeyH,EAAa,aAAa,EAJnD,SAMnB/F,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,wCAClD,cAAeA,CACjB,EACA,YAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACrD,EAAA,CACT,CAMF,MAAM,mBAAmBoB,EAAY,GAAoC,CACnE,IAAAhH,EACA+G,EACA,GAAA,CACO/G,EAAA,MAAM,KAAK,UAAUgH,CAAS,EACxBD,EAAA,KAAK,kBAAkB,oBAAoB,QACnD/F,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,OAASA,aAAiBD,EAAgBC,EAAM,QAAU,uBACpF,cAAeA,CACjB,EACA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACnD5F,EAAA,MAAA,CAGP,OAAAA,GAAU,KAAK,iBAAiB,eAClC,MAAM,KAAK,iBAAiB,cAAc,CAAE,OAAAA,EAAQ,aAAA+G,EAAc,EAGhE,CAAC/G,GAAU,KAAK,iBAAiB,gBAC7B,MAAA,KAAK,iBAAiB,eAAe,EAGtCA,CAAA,CAMT,MAAM,UAAUgH,EAAiD,CAC3D,GAAA,CACI,MAAAhH,EAAS,KAAK,eAAe,UAAU,EAE7C,GAAI,CAACA,GAAU,CAACA,EAAO,aAAqB,OAEtC,MAAAM,EAASjB,EAAWW,EAAO,YAAY,EAEzC,OAAAV,EAAegB,CAAM,EAEnB0G,EAAkB,MAAM,KAAK,aAAa,EAGvC,OAEAhH,QAEFgB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,uBAClD,cAAeA,CACjB,EACA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACrD,MAAA,CACT,CAEJ,CCliBO,MAAMqB,CAAkB,CAC7B,YAAoBC,EAA8B,CAA9B,KAAA,cAAAA,CAAA,CAOpB,kBAAkBlF,EAAgE,CACzE,OAAA,KAAK,cAAc,kBAAkBA,CAAO,CAAA,CAQrD,eAAeO,EAKuB,CAC7B,OAAA,KAAK,cAAc,eAAeA,CAAO,CAAA,CAQlD,iBAAiBnD,EAAiD,CACzD,OAAA,KAAK,cAAc,iBAAiBA,CAAK,CAAA,CAQlD,iBAAiBA,EAAiD,CACzD,OAAA,KAAK,cAAc,iBAAiBA,CAAK,CAAA,CAQlD,kBAAkBsF,EAAmD,CAC5D,OAAA,KAAK,cAAc,kBAAkBA,CAAY,CAAA,CAE5D,CClDO,MAAMyC,CAAgC,CAC3C,MAAMC,KAAoBC,EAAuB,CAEvC,QAAA,MAAMD,EAAS,GAAGC,CAAI,CAAA,CAGhC,KAAKD,KAAoBC,EAAuB,CAEtC,QAAA,KAAKD,EAAS,GAAGC,CAAI,CAAA,CAG/B,KAAKD,KAAoBC,EAAuB,CAEtC,QAAA,KAAKD,EAAS,GAAGC,CAAI,CAAA,CAG/B,MAAMD,KAAoBC,EAAuB,CAEvC,QAAA,MAAMD,EAAS,GAAGC,CAAI,CAAA,CAElC,CAMO,SAASC,GAA2B,CACzC,OAAO,IAAIH,CACb,CCqBO,MAAMI,CAAqB,CAGhC,YAAY/I,EAA6B,CAClC,KAAA,KAAO,KAAK,UAAUA,CAAG,CAAA,CAGxB,UAAUA,EAAyC,CACnD,MAAAgJ,MAAY,IACZC,MAAa,IACb3I,MAAY,IACZ4I,EAA4B,CAAC,EAG/B,OAAAlJ,EAAA,QAAQ,QAASO,GAAqB,CACjC0I,EAAA,IAAI1I,EAAE,GAAI,CACf,GAAIA,EAAE,GACN,KAAMA,EAAE,KACR,QAASA,EAAE,SAAW,GACtB,WAAYA,EAAE,WACd,WAAYA,EAAE,UAAA,CACf,CAAA,CACF,EAGGP,EAAA,OAAO,QAASmJ,GAAoB,CAChC7I,EAAA,IAAI6I,EAAE,GAAI,CACd,GAAIA,EAAE,GACN,UAAWA,EAAE,UACb,KAAMA,EAAE,IAAA,CACT,CAAA,CACF,EAGGnJ,EAAA,iBAAiB,QAASoJ,GAA6B,CACzD,MAAMC,EAAID,EAAI,KACVC,GAAK,CAACL,EAAM,IAAIK,EAAE,EAAE,GAChBL,EAAA,IAAIK,EAAE,GAAI,CACd,GAAIA,EAAE,GACN,KAAMA,EAAE,MAAQ,KAChB,MAAOA,EAAE,OAAS,KAClB,MAAOA,EAAE,OAAS,IAAA,CACnB,EAECA,GAAKD,EAAI,UAAYH,EAAO,IAAIG,EAAI,QAAQ,GAC9CF,EAAY,KAAK,CACf,OAAQG,EAAE,GACV,QAASD,EAAI,SACb,QAASA,EAAI,OAAO,IAAKD,GAAMA,EAAE,EAAE,GAAK,CAAA,CAAC,CAC1C,CACH,CACD,EAEM,CACL,UAAWnJ,EAAI,UACf,YAAaA,EAAI,YACjB,MAAO,MAAM,KAAKgJ,EAAM,QAAQ,EAChC,OAAQ,MAAM,KAAKC,EAAO,QAAQ,EAClC,MAAO,MAAM,KAAK3I,EAAM,QAAQ,EAChC,YAAA4I,EACA,UAAWF,EACX,WAAYC,EACZ,UAAW3I,CACb,CAAA,CAMF,gBAAgBmF,EAAyB,CAChC,OAAA,KAAK,KAAK,YACd,OAAQ6D,GAAMA,EAAE,UAAY7D,CAAO,EACnC,IAAK6D,GAAM,KAAK,KAAK,UAAU,IAAIA,EAAE,MAAM,CAAC,EAC5C,OAAQD,GAAiBA,IAAM,MAAS,CAAA,CAM7C,iBAAiB3D,EAAyB,CACjC,OAAA,KAAK,KAAK,YACd,OAAQ4D,GAAMA,EAAE,SAAW5D,CAAM,EACjC,IAAK4D,GAAM,KAAK,KAAK,WAAW,IAAIA,EAAE,OAAO,CAAC,EAC9C,OAAQ/I,GAAkBA,IAAM,MAAS,CAAA,CAM9C,oBAAoBmF,EAAgBD,EAAyB,CAC3D,MAAM8D,EAAa,KAAK,KAAK,YAAY,KAAMD,GAAMA,EAAE,SAAW5D,GAAU4D,EAAE,UAAY7D,CAAO,EACjG,OAAK8D,EAGEA,EAAW,QAAQ,IAAK3D,GAAW,KAAK,KAAK,UAAU,IAAIA,CAAM,CAAC,EAAE,OAAQ,GAAiB,IAAM,MAAS,EAF1G,CAAC,CAEyG,CAMrH,SAAsB,CACpB,OAAO,KAAK,IAAA,CAEhB,CCpJO,MAAM4D,CAAc,CAGzB,YACUC,EACA7H,EACR8H,EACA,CAHQ,KAAA,UAAAD,EACA,KAAA,OAAA7H,EAGH,KAAA,OAAS8H,GAAUZ,EAAiB,CAAA,CASnC,oBAAoBtG,EAAgBmH,EAAwB,CAElE,GAAIvG,EAAM,aAAaZ,CAAK,GAAKA,EAAM,UAAU,KAAM,CAC/C,MAAAoH,EAAepH,EAAM,SAAS,KAGpC,GACE,OAAOoH,GAAiB,UACxBA,IAAiB,MACjB,UAAWA,GACX,OAAOA,EAAa,OAAU,UAC9BA,EAAa,QAAU,KACvB,CACA,MAAMC,EAAgBD,EAAa,MASnC,WAAK,OAAO,MAAM,GAAGD,CAAO,KAAKE,EAAc,EAAE,MAAMA,EAAc,OAAO,aAAaA,EAAc,MAAM,GAAG,EAG1G,IAAI,MAAM,uBAAuBA,EAAc,EAAE,MAAMA,EAAc,OAAO,aAAaA,EAAc,MAAM,GAAG,CAAA,CACxH,CAKF,MADA,KAAK,OAAO,MAAM,GAAGF,CAAO,IAAKnH,CAAK,EAClCA,aAAiB,MACbA,EAEF,IAAI,MAAM,OAAOA,CAAK,CAAC,CAAA,CAS/B,MAAM,eAAe5B,EAAegB,EAA2D,CACzF,GAAA,CACI,MAAA0F,EAAU1F,GAAU,KAAK,OAC/B,OAAO,MAAM,KAAK,UAAU,eAAehB,EAAO0G,CAAO,QAClD9E,EAAO,CACT,KAAA,oBAAoBA,EAAO,wBAAwB,CAAA,CAC1D,CAQF,MAAM,aAAa0C,EAA+C,CAC5D,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,aAAaA,CAAI,QACtC1C,EAAO,CACT,KAAA,oBAAoBA,EAAO,wBAAwB,CAAA,CAC1D,CAeF,MAAM,iBAAiBgD,EAAmD,CACpE,GAAA,CAEK,OADU,MAAM,KAAK,UAAU,iBAAiBA,CAAQ,QAExDhD,EAAO,CACd,KAAK,oBAAoBA,EAAO,2CAA2CgD,CAAQ,EAAE,CAAA,CACvF,CAQF,MAAM,wBAAwBA,EAAiD,CACzE,GAAA,CACF,MAAMjC,EAAW,MAAM,KAAK,UAAU,iBAAiBiC,CAAQ,EACxD,OAAA,IAAIuD,EAAqBxF,CAAQ,QACjCf,EAAO,CACd,KAAK,oBAAoBA,EAAO,mDAAmDgD,CAAQ,EAAE,CAAA,CAC/F,CASF,MAAM,aAAaA,EAAkBN,EAA+C,CAC9E,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,aAAaM,EAAUN,CAAI,QAChD1C,EAAO,CACd,KAAK,oBAAoBA,EAAO,sCAAsCgD,CAAQ,EAAE,CAAA,CAClF,CAQF,MAAM,aAAaA,EAAmD,CAChE,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,aAAaA,CAAQ,QAC1ChD,EAAO,CACd,KAAK,oBAAoBA,EAAO,sCAAsCgD,CAAQ,EAAE,CAAA,CAClF,CAOF,MAAM,yBAAyE,CACzE,GAAA,CACK,OAAA,MAAM,KAAK,UAAU,wBAAwB,QAC7ChD,EAAO,CACT,KAAA,oBAAoBA,EAAO,oCAAoC,CAAA,CACtE,CAWF,MAAM,YAAYgD,EAAkBN,EAA8C,CAC5E,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,YAAYM,EAAUN,CAAI,QAC/C1C,EAAO,CACd,KAAK,oBAAoBA,EAAO,uCAAuCgD,CAAQ,EAAE,CAAA,CACnF,CASF,MAAM,aAAaA,EAAkBC,EAAiD,CAChF,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,aAAaD,EAAUC,CAAO,QACnDjD,EAAO,CACd,KAAK,oBAAoBA,EAAO,uCAAuCgD,CAAQ,cAAcC,CAAO,EAAE,CAAA,CACxG,CAUF,MAAM,YAAYD,EAAkBC,EAAiBP,EAA8C,CAC7F,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,YAAYM,EAAUC,EAASP,CAAI,QACxD1C,EAAO,CACd,KAAK,oBAAoBA,EAAO,qCAAqCgD,CAAQ,cAAcC,CAAO,EAAE,CAAA,CACtG,CASF,MAAM,YAAYD,EAAkBC,EAAkD,CAChF,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,YAAYD,EAAUC,CAAO,QAClDjD,EAAO,CACd,KAAK,oBAAoBA,EAAO,qCAAqCgD,CAAQ,cAAcC,CAAO,EAAE,CAAA,CACtG,CAWF,MAAM,eAAeD,EAAkBC,EAAiBC,EAAgBC,EAA+C,CACjH,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,eAAeH,EAAUC,EAASC,EAAQC,CAAI,QACnEnD,EAAO,CACT,KAAA,oBACHA,EACA,0CAA0CgD,CAAQ,cAAcC,CAAO,aAAaC,CAAM,EAC5F,CAAA,CACF,CAWF,MAAM,yBACJF,EACAC,EACAC,EACApF,EACiC,CAC7B,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,yBAAyBkF,EAAUC,EAASC,EAAQpF,CAAK,QAC9EkC,EAAO,CACT,KAAA,oBACHA,EACA,qDAAqDgD,CAAQ,cAAcC,CAAO,aAAaC,CAAM,EACvG,CAAA,CACF,CAWF,MAAM,gBAAgBF,EAAkBC,EAAiBC,EAAgBpF,EAAkD,CACrH,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,gBAAgBkF,EAAUC,EAASC,EAAQpF,CAAK,QACrEkC,EAAO,CACT,KAAA,oBACHA,EACA,0CAA0CgD,CAAQ,cAAcC,CAAO,aAAaC,CAAM,EAC5F,CAAA,CACF,CAUF,MAAM,oBAAoBF,EAAkBC,EAAiBC,EAAiD,CACxG,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,oBAAoBF,EAAUC,EAASC,CAAM,QAClElD,EAAO,CACT,KAAA,oBACHA,EACA,+CAA+CgD,CAAQ,cAAcC,CAAO,aAAaC,CAAM,EACjG,CAAA,CACF,CAUF,MAAM,kBAAkBF,EAAmD,CACrE,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,kBAAkBA,CAAQ,QAC/ChD,EAAO,CACd,KAAK,oBAAoBA,EAAO,6CAA6CgD,CAAQ,EAAE,CAAA,CACzF,CASF,MAAM,oBAAoBA,EAAkBN,EAA6C,CACnF,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,oBAAoBM,EAAUN,CAAI,QACvD1C,EAAO,CACd,KAAK,oBAAoBA,EAAO,+CAA+CgD,CAAQ,EAAE,CAAA,CAC3F,CAUF,MAAM,WAAWA,EAAkBI,EAAgBV,EAA6C,CAC1F,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,WAAWM,EAAUI,EAAQV,CAAI,QACtD1C,EAAO,CACd,KAAK,oBAAoBA,EAAO,oCAAoCgD,CAAQ,aAAaI,CAAM,EAAE,CAAA,CACnG,CASF,MAAM,WAAWJ,EAAkBI,EAAiD,CAC9E,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,WAAWJ,EAAUI,CAAM,QAChDpD,EAAO,CACd,KAAK,oBAAoBA,EAAO,oCAAoCgD,CAAQ,aAAaI,CAAM,EAAE,CAAA,CACnG,CAWF,MAAM,qBAAqBJ,EAAkBE,EAAiD,CACxF,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,qBAAqBF,EAAUE,CAAM,QAC1DlD,EAAO,CACd,KAAK,oBAAoBA,EAAO,gDAAgDgD,CAAQ,aAAaE,CAAM,EAAE,CAAA,CAC/G,CAaF,MAAM,oBACJF,EACAC,EACAI,EACAC,EACsC,CAClC,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,oBAAoBN,EAAUC,EAASI,EAAOC,CAAI,QACvEtD,EAAO,CACd,KAAK,oBAAoBA,EAAO,8CAA8CgD,CAAQ,cAAcC,CAAO,EAAE,CAAA,CAC/G,CAUF,MAAM,qBAAqBD,EAAkBK,EAAeC,EAAoD,CAC1G,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,qBAAqBN,EAAUK,EAAOC,CAAI,QAC/DtD,EAAO,CACd,KAAK,oBAAoBA,EAAO,+CAA+CgD,CAAQ,EAAE,CAAA,CAC3F,CAUF,MAAM,qBAAqBA,EAAkBC,EAAiBM,EAAkD,CAC1G,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,qBAAqBP,EAAUC,EAASM,CAAQ,QACrEvD,EAAO,CACT,KAAA,oBACHA,EACA,gDAAgDgD,CAAQ,cAAcC,CAAO,eAAeM,CAAQ,EACtG,CAAA,CACF,CAUF,MAAM,wBAAwBP,EAAkBC,EAAiBO,EAA+C,CAC1G,GAAA,CACF,OAAO,MAAM,KAAK,UAAU,wBAAwBR,EAAUC,EAASO,CAAK,QACrExD,EAAO,CACT,KAAA,oBACHA,EACA,mDAAmDgD,CAAQ,cAAcC,CAAO,WAAWO,CAAK,EAClG,CAAA,CACF,CAEJ,CCrcO,MAAM8D,CAAY,CACvB,YACUC,EACAlD,EACR,CAFQ,KAAA,QAAAkD,EACA,KAAA,cAAAlD,CAAA,CAOV,iBAAkB,CACT,OAAA,KAAK,QAAQ,gBAAgB,CAAA,CAStC,kBAAkB3B,EAAcC,EAAqD,CACnF,OAAO,KAAK,QAAQ,kBAAkBD,EAAMC,CAAS,CAAA,CAQvD,kBAAkBA,EAAqD,CAC9D,OAAA,KAAK,QAAQ,kBAAkBA,CAAS,CAAA,CAQjD,MAAM,eAAe,CACnB,eAAAC,EACA,gBAAAE,EACA,mBAAAD,CACF,EAII,GAAmB,CACf,MAAAtD,EAAW,KAAK,cAAc,YAAY,EAC1CqC,EAAK1B,EAAG,IACR,CAAE,aAAA6E,EAAc,UAAAC,CAAA,EAAc,MAAM,KAAK,QAAQ,oBAAoB,CACzE,eAAgBpC,GAAkB,QAAQ,UAAU,SACpD,SAAArD,EACA,GAAAqC,EACA,mBAAAiB,EACA,gBAAAC,CAAA,CACD,EAEDkC,EAAU,KAAK,GAAK,KAAKA,EAAU,KAAK,EAAE,EAC1C,MAAMC,EAAW,MAAMC,EAAAA,kBAAkB,CAAE,YAAaF,EAAW,EACnE,OAAO,MAAM,KAAK,QAAQ,uBAAuBC,EAAU1F,EAAUwF,CAAY,CAAA,CAErF,CC7DO,MAAMyC,CAAkB,CAS7B,YACUlD,EACAF,EACAG,EACR,CAHQ,KAAA,eAAAD,EACA,KAAA,QAAAF,EACA,KAAA,eAAAG,EARV,KAAQ,cAAuC,KAC/C,KAAiB,eAAiB,GACnB,KAAA,aAAA,GACH,KAAA,UAAA,GAOV,KAAK,eAAiBD,EACtB,KAAK,QAAUF,CAAA,CAGjB,YAAa,CACP,GAAA,CACI,MAAApF,EAAS,KAAK,eAAe,UAAU,EAC7C,GAAI,CAACA,GAAU,CAACA,EAAO,aAAc,CACnC,KAAK,gBAAgB,EACrB,MAAA,CAGI,MAAAM,EAASjB,EAAWW,EAAO,YAAY,EAEzCV,EAAegB,CAAM,GACvB,KAAK,UAAY,GACjB,KAAK,eAAe,EACpB,KAAK,eAAe,OAAOqE,EAAc,kBAAmB,CAAE,UAAW,GAAM,IAE/E,KAAK,eAAe3E,CAAM,EAC1B,KAAK,gBAAgB,SAEhBgB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,uBAClD,cAAeA,CACjB,EACA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EAC5D,KAAK,eAAe,MAAS,CAAA,CAC/B,CAGF,MAAc,mBAAmB5F,EAAgB,CAC/C,GAAI,MAAK,aAEL,GAAA,CACF,KAAK,aAAe,GACpB,KAAK,eAAe,OAAO2E,EAAc,aAAc,CAAA,CAAE,EAEzD,MAAM5C,EAAW,MAAM,KAAK,QAAQ,aAAa/B,GAAQ,eAAiB,GAAIA,EAAO,QAAU,CAAA,EAAIA,EAAO,YAAY,EACtH,KAAK,eAAe+B,CAAQ,EAEvB,KAAA,eAAe,OAAO4C,EAAc,QAAS,CAAE,OAAQ5C,EAAU,aAAc,KAAK,oBAAoB,CAAA,CAAG,EAChH,KAAK,eAAe,OAAO4C,EAAc,kBAAmB,CAAE,UAAW,GAAO,EAChF,KAAK,UAAY,GACjB,KAAK,gBAAgB,QACd3D,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,uBAClD,cAAeA,CACjB,EACA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EAC5D,KAAK,eAAe,MAAS,CAAA,QAC7B,CACA,KAAK,aAAe,EAAA,CACtB,CAGF,iBAAkB,CACZ,KAAK,eACP,cAAc,KAAK,aAAa,EAG9B,MAAK,YAEJ,KAAA,cAAgB,YAAY,IAAM,CACjC,KAAK,cAAgB,KAAK,WAE1B,KAAK,qBAAA,GAA0B,CAAC,KAAK,YACvC,KAAK,UAAY,GACjB,KAAK,eAAe,OAAOjB,EAAc,kBAAmB,CAAE,UAAW,GAAM,EAC/E,KAAK,eAAe,EACtB,EACC,KAAK,cAAc,EAAA,CAGhB,gBAAiB,CACnB,KAAK,gBACP,cAAc,KAAK,aAAa,EAChC,KAAK,cAAgB,KACvB,CAGF,eAAe3E,EAAkC,CAC/C,KAAK,YAAcA,EACfA,EACF,KAAK,kBAAoB,CACvB,aAAcX,EAAWW,EAAO,YAAY,EAC5C,SAAUA,EAAO,SAAWX,EAAWW,EAAO,QAAQ,EAAI,OAC1D,cAAeA,EAAO,cAAgBX,EAAWW,EAAO,aAAa,EAAI,OACzE,OAAQA,EAAO,MACjB,EAEA,KAAK,kBAAoB,MAC3B,CAGF,gBAAiB,CACf,OAAO,KAAK,WAAA,CAGd,MAAM,2BAA4B,CAC5B,GAAA,CACF,GAAI,CAAC,KAAK,YAAa,OAAO,KAAK,YAEnC,MAAMM,EAASjB,EAAW,KAAK,YAAY,YAAY,EAEvD,OAAIC,EAAegB,CAAM,GAAK,CAAC,KAAK,WAC5B,MAAA,KAAK,mBAAmB,KAAK,WAAW,EACvC,KAAK,aAEL,KAAK,kBAEPU,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,uBAClD,cAAeA,CACjB,EACA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACrD,MAAA,CACT,CAGF,qBAAsB,CACpB,OAAO,KAAK,iBAAA,CAGd,sBAAuB,CACjB,GAAA,CAAC,KAAK,YAAoB,MAAA,GAC9B,MAAMtF,EAASjB,EAAW,KAAK,YAAY,YAAY,EACvD,OAAOC,EAAegB,CAAM,CAAA,CAEhC,CCjHO,MAAMmI,EAAS,CAqCpB,YAAYhH,EAAwB,CAzBpC,KAAQ,gBAAkB,GAqB1B,KAAA,OAAS,OAAO,SAAS,OA+DzB,KAAA,QAA0F,MAAO,CAC/F,cAAAiH,EACA,eAAAC,EACA,UAAA3B,EAAY,EAAA,IACR,CACJ,KAAK,sBAAwB0B,EAC7B,KAAK,uBAAyBC,EAC9B,KAAK,gBAAkB3B,EAEvB,MAAM,KAAK,mBAAmB,CAChC,EApEE,KAAM,CAAE,IAAAxG,EAAK,MAAAkB,EAAO,OAAAtB,CAAW,EAAAqB,EAC/B,KAAK,IAAMjB,GAAOnC,EAClB,KAAK,MAAQqD,EAGR,KAAA,QAAU,IAAIe,EAAQhB,CAAM,EAC5B,KAAA,OAAS,IAAI8B,EAAO9B,CAAM,EAC1B,KAAA,QAAU,IAAIgC,EAAQhC,CAAM,EAC5B,KAAA,WAAa,IAAI+B,EAAW/B,CAAM,EAClC,KAAA,UAAY,IAAIsC,EAAUtC,CAAM,EAChC,KAAA,cAAgB,IAAIgD,EAAchD,CAAM,EAGxC,KAAA,eAAiB,IAAIxC,EAAe,CACvC,OAAQwC,EAAO,kBAAoB,EAAA,CACpC,EACI,KAAA,cAAgB,IAAIhB,EACpB,KAAA,eAAiB,IAAImE,EAErB,KAAA,kBAAoB,IAAI4D,EAAkB,KAAK,eAAgB,KAAK,QAAS,KAAK,cAAc,EAErG,KAAK,OAASpI,GAAUhC,EACnB,KAAA,uBAAyBqD,EAAO,wBAA0B,GAG/D,KAAK,YAAc,IAAI0D,EACrB,KAAK,QACL,KAAK,cACL,KAAK,eACL,KAAK,eACL,KAAK,kBACL,KAAK,OACL,KAAK,uBACL,KAAK,OACL,KAAK,IACL,CACE,cAAe,KAAK,sBACpB,eAAgB,KAAK,sBACvB,EACA,KAAK,OAAS,EAChB,EAEA,KAAK,YAAc,IAAImD,EAAY,KAAK,QAAS,KAAK,aAAa,EAEnE,KAAK,cAAgB,IAAIN,EAAc,KAAK,UAAW,KAAK,MAAM,EAClE,KAAK,OAAS,KAAK,cAEnB,KAAK,kBAAoB,IAAIf,EAAkB,KAAK,aAAa,EAG7DxF,EAAO,kBACT,KAAK,kBAAkB,EAGzB,KAAK,iCAAiC,CAAA,CAgBxC,MAAc,oBAAqB,CAC7B,IAAAzB,EACA+G,EACA,GAAA,CACF/G,EAAS,MAAM,KAAK,YAAY,UAAU,KAAK,eAAe,EAC/C+G,EAAA,KAAK,kBAAkB,oBAAoB,QACnD/F,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,OAASA,aAAiBD,EAAgBC,EAAM,QAAU,uBACpF,cAAeA,CACjB,EACA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACnD5F,EAAA,MAAA,CAGPA,GAAU,KAAK,uBACjB,MAAM,KAAK,sBAAsB,CAAE,OAAAA,EAAQ,aAAA+G,EAAc,EAGvD,CAAC/G,GAAU,KAAK,wBAClB,MAAM,KAAK,uBAAuB,CACpC,CAIF,UAAU4I,EAAuB,EAAqB,CAC/C,KAAA,eAAe,UAAUA,EAAG,CAAC,EAGlC,KAAK,kBAAkB,WAAW,CAAA,CAGpC,YAAYA,EAAuB,EAAqB,CACjD,KAAA,eAAe,YAAYA,EAAG,CAAC,CAAA,CAItC,sBAA2C,CACzC,OAAO,KAAK,kBAAkB,CAAA,CAGxB,mBAAwC,CAC9C,MAAMjC,EAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM,EACtDzG,EAAeyG,EAAU,IAAI,cAAc,EAC3CxG,EAAgBwG,EAAU,IAAI,eAAe,EAC7C1G,EAAW0G,EAAU,IAAI,UAAU,EACnCvG,EAAmBuG,EAAU,IAAI,QAAQ,GAAG,MAAM,GAAG,GAAK,KAAK,OACrE,IAAI3G,EAEJ,GAAIE,EACO,OAAAF,EAAA,CACP,aAAAE,EACA,cAAeC,GAAiB,OAChC,SAAUF,GAAY,OACtB,OAAAG,CACF,EACK,KAAA,eAAe,WAAWJ,CAAM,EAChC,KAAA,kBAAkB,eAAeA,CAAM,EACvC,KAAA,eAAe,OAAO2E,EAAc,OAAQ,CAAE,OAAA3E,EAAQ,aAAc,KAAK,oBAAoB,EAAG,EACrG,KAAK,mBAAmB,EAExB2G,EAAU,OAAO,cAAc,EAC/BA,EAAU,OAAO,eAAe,EAChCA,EAAU,OAAO,UAAU,EAC3BA,EAAU,OAAO,kBAAkB,EAE/BA,EAAU,KAAO,EACnB,OAAO,QAAQ,aAAa,CAAC,EAAG,SAAS,MAAO,GAAG,OAAO,SAAS,QAAQ,IAAIA,EAAU,SAAA,CAAU,EAAE,EAE9F,OAAA,QAAQ,aAAa,CAAC,EAAG,SAAS,MAAO,OAAO,SAAS,QAAQ,EAE1E,KAAK,MAAQ,OACN3G,EAEF,KAAA,MAAQ,KAAK,mBAAmB,CAEhC,CAGD,oBAAwC,CAExC,MAAAgB,EADY,IAAI,gBAAgB,OAAO,SAAS,MAAM,EACpC,IAAI,OAAO,EACnC,GAAIA,EACK,OAAA,IAAI,MAAMA,CAAK,CAEjB,CAGD,kCAAyC,CACzC,MAAAhB,EAAS,KAAK,eAAe,UAAU,EACzCA,GACG,KAAA,kBAAkB,eAAeA,CAAM,CAC9C,CAGF,gBAAiB,CACR,OAAA,KAAK,kBAAkB,eAAe,CAAA,CAG/C,2BAA4B,CACnB,OAAA,KAAK,kBAAkB,0BAA0B,CAAA,CAG1D,qBAAsB,CACb,OAAA,KAAK,kBAAkB,oBAAoB,CAAA,CAGpD,sBAAuB,CACd,OAAA,KAAK,kBAAkB,qBAAqB,CAAA,CAIrD,iBAA2B,CACnB,MAAAA,EAAS,KAAK,eAAe,UAAU,EAC7C,GAAI,CAACA,GAAU,CAACA,EAAO,aAAqB,MAAA,GAE5C,MAAM+G,EAAe,CACnB,aAAc1H,EAAWW,EAAO,YAAY,EAC5C,cAAeA,EAAO,cAAgBX,EAAWW,EAAO,aAAa,EAAI,MAC3E,EAEO,OAAA,KAAK,YAAY,gBAAgB+G,CAAY,CAAA,CAGtD,MAAM,OAAO/E,EAAwE,CAG5E,OAFU,MAAM,KAAK,YAAY,OAAOA,CAAO,CAE/C,CAGT,MAAM,OAAOA,EAAwE,CAG5E,OAFU,MAAM,KAAK,YAAY,OAAOA,CAAO,CAE/C,CAGT,mBAAmBA,EAAmF,CAC7F,OAAA,KAAK,YAAY,mBAAmBA,CAAO,CAAA,CAGpD,MAAM,2BAA2BA,EAAyF,CAGjH,OAFU,MAAM,KAAK,YAAY,2BAA2BA,CAAO,CAEnE,CAGT,MAAM,QAAwB,CACxB,GAAA,CACI,MAAA,KAAK,YAAY,OAAO,EAC9B,KAAK,eAAe,aAAa,EACjC,MAAM,KAAK,mBAAmB,QACvBhB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,oBAClD,cAAeA,CACjB,EACA,KAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,CAAA,CAEzD,KAAA,kBAAkB,eAAe,MAAS,EAC/C,KAAK,eAAe,OAAOjB,EAAc,QAAS,CAAA,CAAE,CAAA,CAGtD,uBAAuB3C,EAA6C,CAC7D,KAAA,YAAY,uBAAuBA,CAAO,CAAA,CAGjD,0BAA0BA,EAA6C,CAChE,KAAA,YAAY,0BAA0BA,CAAO,CAAA,CAGpD,MAAMhB,EAAgB,CAIpB,GAHA,KAAK,eAAe,aAAa,EAC5B,KAAA,kBAAkB,eAAe,MAAS,EAC/C,KAAK,eAAe,OAAO2D,EAAc,QAAS,CAAA,CAAE,EAChD3D,EAAO,CACJ,KAAA,MAAQ,IAAI,MAAMA,CAAK,EAC5B,MAAM4E,EAA6B,CACjC,QAAS5E,EACT,KAAM,aACR,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD,KAAK,KAAA,CACb,CAGF,MAAM,cAAuD,CAC3D,GAAI,CAAC,KAAK,kBAAkB,mBAAmB,cACvC,MAAA,IAAI,MAAM,wBAAwB,EAGtC,GAAA,CAGK,OAFU,MAAM,KAAK,YAAY,aAAa,QAG9C5E,EAAO,CACd,MAAIA,aAAiBD,GAGd,KAAA,eAAe,OAAO4D,EAAc,MAAO,CAC9C,QAAS,0BACT,cAAe3D,CAAA,CAChB,EACKA,CACR,CACF,CAGF,uBAAuBgB,EAAkF,CAChG,OAAA,KAAK,YAAY,uBAAuBA,CAAO,CAAA,CAGxD,MAAM,cAAciB,EAAqB7C,EAA2D,CAG3F,OAFU,MAAM,KAAK,YAAY,cAAc6C,EAAa7C,CAAM,CAElE,CAIT,MAAM,gBAAuC,CACvC,GAAA,CACK,OAAA,MAAM,KAAK,OAAO,eAAe,QACjCY,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,6BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,gBAA+C,CAC/C,GAAA,CACK,OAAA,MAAM,KAAK,WAAW,eAAe,QACrCA,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,6BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,2BAAqE,CACrE,GAAA,CACK,OAAA,MAAM,KAAK,WAAW,0BAA0B,QAChDA,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,yCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,oBAAuD,CACvD,GAAA,CACK,OAAA,MAAM,KAAK,WAAW,mBAAmB,QACzCA,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,iCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAIF,MAAM,gBAAgBgB,EAAsF,CAGnG,OAFU,MAAM,KAAK,YAAY,gBAAgBA,CAAO,CAExD,CAGT,MAAM,oBAAoBA,EAA0F,CAG3G,OAFU,MAAM,KAAK,YAAY,oBAAoBA,CAAO,CAE5D,CAIT,UAAU4E,EAA0B,CAC7B,KAAA,eAAe,WAAWA,CAAU,EACpC,KAAA,kBAAkB,eAAeA,CAAU,EAC3C,KAAA,eAAe,OAAOjC,EAAc,OAAQ,CAC/C,OAAQiC,EACR,aAAc,KAAK,kBAAkB,oBAAoB,CAAA,CAC1D,CAAA,CAIH,MAAM,UAAUI,EAAY,GAAoC,CAC9D,OAAO,MAAM,KAAK,YAAY,UAAUA,CAAS,CAAA,CAInD,SAASzH,EAA0C,CAC1C,OAAA,KAAK,eAAe,SAASA,CAAS,CAAA,CAI/C,MAAM,iBAAkB,CAClB,GAAA,CACK,OAAA,MAAM,KAAK,YAAY,gBAAgB,QACvCyB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,8BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,kBAAkB0C,EAAcC,EAAqD,CACrF,GAAA,CACF,OAAO,MAAM,KAAK,YAAY,kBAAkBD,EAAMC,CAAS,QACxD3C,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,gCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,kBAAkB2C,EAAqD,CACvE,GAAA,CACF,OAAO,MAAM,KAAK,YAAY,kBAAkBA,CAAS,QAClD3C,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,gCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,eAAeuB,EAIH,CACZ,GAAA,CACF,OAAO,MAAM,KAAK,YAAY,eAAeA,CAAO,QAC7CvB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,6BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAUF,MAAM,eAAe5B,EAAegB,EAA2D,CACzF,GAAA,CACF,MAAM2B,EAAW,MAAM,KAAK,OAAO,eAAe3C,EAAOgB,CAAM,EACtD,OAAA2B,EAAA,OAAS3B,GAAU,KAAK,OAC5B,KAAA,eAAe,WAAW2B,CAAQ,EAClC,KAAA,kBAAkB,eAAeA,CAAQ,EACvCA,QACAf,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,4BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CASF,MAAM,aAAa0C,EAAchB,EAAyD,CACpF,GAAA,CACF,MAAMX,EAAW,MAAM,KAAK,OAAO,aAAa2B,CAAI,EACpD,OAAIhB,GACF,MAAM,KAAK,aAAa,EAEnBX,QACAf,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,0BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAIF,MAAM,kBAAkBgB,EAAgE,CAClF,GAAA,CAEE,OAAAA,EAAQ,gBAAkB,SAC5BA,EAAQ,cAAgB,IAEnB,MAAM,KAAK,kBAAkB,kBAAkBA,CAAO,QACtDhB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,gCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAQF,MAAM,eAAeuB,EAKiB,CAChC,GAAA,CACF,OAAO,MAAM,KAAK,kBAAkB,eAAeA,CAAO,QACnDvB,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,4BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,iBAAiB5B,EAAiD,CAClE,GAAA,CACF,OAAO,MAAM,KAAK,kBAAkB,iBAAiBA,CAAK,QACnD4B,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,8BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,iBAAiB5B,EAAiD,CAClE,GAAA,CACF,OAAO,MAAM,KAAK,kBAAkB,iBAAiBA,CAAK,QACnD4B,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,8BAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAGF,MAAM,kBAAkB0D,EAAmD,CACrE,GAAA,CACF,OAAO,MAAM,KAAK,kBAAkB,kBAAkBA,CAAY,QAC3D1D,EAAO,CACd,MAAM4E,EAA6B,CACjC,QAAS5E,aAAiB,MAAQA,EAAM,QAAU,gCAClD,cAAeA,CACjB,EACA,WAAK,eAAe,OAAO2D,EAAc,MAAOiB,CAAY,EACtD5E,CAAA,CACR,CAIF,gBACEuB,EAKI,GACI,CACD,OAAA,KAAK,YAAY,gBAAgBA,CAAO,CAAA,CAGjD,aACEA,EAKI,GACE,CACD,KAAA,YAAY,aAAaA,CAAO,CAAA,CAEzC"}