@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 35.7 kB
Source Map (JSON)
{"version":3,"file":"use-organization.cjs","sources":["../../../src/hooks/use-organization.ts"],"sourcesContent":["/**\n * @frank-auth/react - useOrganization Hook\n *\n * Organization management hook that provides access to organization operations,\n * member management, invitations, and organization-specific settings.\n */\n\nimport {useCallback, useEffect, useMemo, useState} from \"react\";\n\nimport type {\n AcceptInvitationRequest, CreateMembershipRequest,\n CreateOrganizationRequest,\n DeclineInvitationRequest,\n Organization,\n OrganizationSettings,\n UpdateOrganizationRequest,\n} from \"@frank-auth/client\";\n\nimport {useAuth} from \"./use-auth\";\nimport {useAuth as useAuthProvider} from \"../provider/auth-provider\";\nimport {useConfig} from \"../provider/config-provider\";\n\nimport type {\n AuthError,\n CreateOrganizationParams,\n InviteMemberParams,\n OrganizationInvitation,\n OrganizationMembership,\n UpdateOrganizationParams,\n} from \"../provider/types\";\n\n// ============================================================================\n// Organization Hook Interface\n// ============================================================================\n\nexport interface UseOrganizationReturn {\n // Organization state\n organization: Organization | null;\n organizations: Organization[];\n activeOrganization: Organization | null;\n memberships: OrganizationMembership[];\n invitations: OrganizationInvitation[];\n isLoaded: boolean;\n isLoading: boolean;\n error: AuthError | null;\n\n // Organization management\n createOrganization: (\n params: CreateOrganizationParams,\n ) => Promise<Organization>;\n updateOrganization: (\n organizationId: string,\n params: UpdateOrganizationParams,\n ) => Promise<Organization>;\n deleteOrganization: (organizationId: string) => Promise<void>;\n switchOrganization: (organizationId: string) => Promise<void>;\n\n // Member management\n inviteMember: (params: InviteMemberParams) => Promise<void>;\n removeMember: (memberId: string) => Promise<void>;\n updateMemberRole: (memberId: string, role: string) => Promise<void>;\n getMembers: () => Promise<OrganizationMember[]>;\n\n // Invitation management\n acceptInvitation: (invitationId: string) => Promise<void>;\n declineInvitation: (invitationId: string) => Promise<void>;\n cancelInvitation: (invitationId: string) => Promise<void>;\n resendInvitation: (invitationId: string) => Promise<void>;\n\n // Settings management\n updateSettings: (\n settings: Partial<OrganizationSettings>,\n ) => Promise<OrganizationSettings>;\n\n // Convenience properties\n organizationId: string | null;\n organizationName: string | null;\n organizationSlug: string | null;\n isOwner: boolean;\n isAdmin: boolean;\n isMember: boolean;\n memberCount: number;\n pendingInvitations: number;\n\n // Multi-tenant helpers\n hasOrganizations: boolean;\n canCreateOrganization: boolean;\n canSwitchOrganization: boolean;\n}\n\nexport interface OrganizationMember {\n id: string;\n userId: string;\n organizationId: string;\n role: string;\n status: \"active\" | \"invited\" | \"suspended\";\n joinedAt: Date;\n invitedBy?: string;\n user: {\n id: string;\n firstName?: string;\n lastName?: string;\n email: string;\n profileImageUrl?: string;\n };\n}\n\n// ============================================================================\n// Main useOrganization Hook\n// ============================================================================\n\n/**\n * Organization management hook providing access to all organization functionality\n *\n * @example Basic organization management\n * ```tsx\n * import { useOrganization } from '@frank-auth/react';\n *\n * function OrganizationManager() {\n * const {\n * organization,\n * organizations,\n * switchOrganization,\n * createOrganization,\n * isOwner,\n * memberCount\n * } = useOrganization();\n *\n * return (\n * <div>\n * <h2>{organization?.name}</h2>\n * <p>Members: {memberCount}</p>\n *\n * {organizations.length > 1 && (\n * <select onChange={(e) => switchOrganization(e.target.value)}>\n * {organizations.map((org) => (\n * <option key={org.id} value={org.id}>\n * {org.name}\n * </option>\n * ))}\n * </select>\n * )}\n *\n * {isOwner && (\n * <button onClick={() => createOrganization({\n * name: 'New Organization',\n * slug: 'new-org'\n * })}>\n * Create Organization\n * </button>\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @example Member management\n * ```tsx\n * function MemberManager() {\n * const {\n * getMembers,\n * inviteMember,\n * removeMember,\n * isAdmin\n * } = useOrganization();\n * const [members, setMembers] = useState([]);\n *\n * useEffect(() => {\n * getMembers().then(setMembers);\n * }, [getMembers]);\n *\n * if (!isAdmin) return <div>Access denied</div>;\n *\n * return (\n * <div>\n * <h3>Members</h3>\n * {members.map((member) => (\n * <div key={member.id}>\n * <span>{member.user.email} ({member.role})</span>\n * <button onClick={() => removeMember(member.id)}>\n * Remove\n * </button>\n * </div>\n * ))}\n * <button onClick={() => inviteMember({\n * emailAddress: 'new@example.com',\n * role: 'member'\n * })}>\n * Invite Member\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useOrganization(): UseOrganizationReturn {\n const {\n organization,\n organizationMemberships,\n activeOrganization,\n switchOrganization: authSwitchOrganization,\n session,\n reload,\n } = useAuth();\n const {sdk} = useAuthProvider();\n\n const {apiUrl, publishableKey, userType} = useConfig();\n\n const [organizations, setOrganizations] = useState<Organization[]>([]);\n const [invitations, setInvitations] = useState<OrganizationInvitation[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n // Error handler\n const handleError = useCallback((err: any) => {\n const authError: AuthError = {\n code: err.code || \"UNKNOWN_ERROR\",\n message: err.message || \"An unknown error occurred\",\n details: err.details,\n field: err.field,\n };\n setError(authError);\n throw authError;\n }, []);\n\n // Load organizations and invitations\n const loadOrganizations = useCallback(async () => {\n try {\n setIsLoading(true);\n setError(null);\n\n // Load organizations user belongs to\n const orgsData = await sdk.organization.listOrganizations({\n fields: [],\n });\n setOrganizations((orgsData.data ?? []) as any);\n\n // Load pending invitations\n // const invitationsData = await sdk.organization.listInvitations();\n // setInvitations(invitationsData?.data ?? []);\n } catch (err) {\n console.error(\"Failed to load organizations:\", err);\n setError({\n code: \"ORGANIZATIONS_LOAD_FAILED\",\n message: \"Failed to load organizations\",\n });\n } finally {\n setIsLoading(false);\n }\n }, [sdk.organization]);\n\n useEffect(() => {\n loadOrganizations();\n }, [loadOrganizations]);\n\n // Organization management methods\n const createOrganization = useCallback(\n async (params: CreateOrganizationParams): Promise<Organization> => {\n if (!sdk.organization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n const createRequest: CreateOrganizationRequest = {\n name: params.name,\n slug: params.slug,\n // description: params.description,\n logoUrl: params.logoUrl,\n websiteUrl: params.websiteUrl,\n settings: params.settings,\n plan: params.planId ?? 'free',\n\n // createTrialPeriod: true,\n // enableAuthService: true,\n // endUserLimit: 10000000,\n // externalUserLimit: 0,\n // orgType: \"platform\",\n // plan: \"\",\n };\n\n const newOrganization =\n await sdk.organization.createOrganization(createRequest);\n\n // Refresh organizations list\n await loadOrganizations();\n await reload(); // Refresh auth state\n\n return newOrganization;\n } catch (err) {\n return handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, loadOrganizations, reload, handleError],\n );\n\n const updateOrganization = useCallback(\n async (\n organizationId: string,\n params: UpdateOrganizationParams,\n ): Promise<Organization> => {\n if (!sdk.organization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n const updateRequest: UpdateOrganizationRequest = {\n name: params.name,\n slug: params.slug,\n description: params.description,\n logoUrl: params.logoUrl,\n websiteUrl: params.websiteUrl,\n settings: params.settings,\n };\n\n const updatedOrganization = await sdk.organization.updateOrganization(\n organizationId,\n updateRequest,\n );\n\n // Refresh organizations list and auth state\n await loadOrganizations();\n await reload();\n\n return updatedOrganization;\n } catch (err) {\n return handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, loadOrganizations, reload, handleError],\n );\n\n const deleteOrganization = useCallback(\n async (organizationId: string): Promise<void> => {\n if (!sdk.organization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n await sdk.organization.deleteOrganization(organizationId, {\n notifyMembers: true,\n confirm: true,\n dataRetention: 0,\n });\n\n // Refresh organizations list and auth state\n await loadOrganizations();\n await reload();\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, loadOrganizations, reload, handleError],\n );\n\n const switchOrganization = useCallback(\n async (organizationId: string): Promise<void> => {\n await authSwitchOrganization(organizationId);\n await loadOrganizations(); // Refresh data for new organization\n },\n [authSwitchOrganization, loadOrganizations],\n );\n\n // Member management methods\n const inviteMember = useCallback(\n async (params: InviteMemberParams): Promise<void> => {\n if (!sdk.organization || !activeOrganization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n const inviteRequest: CreateMembershipRequest = {\n emailAddress: params.emailAddress,\n role: params.role,\n redirectUrl: params.redirectUrl,\n publicMetadata: params.publicMetadata,\n privateMetadata: params.privateMetadata,\n isBillingContact: false,\n isPrimaryContact: false,\n roleId: params.role,\n sendInvitationEmail: false\n };\n\n await sdk.organization.addMember(activeOrganization.id, inviteRequest);\n\n // Refresh invitations\n await loadOrganizations();\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, activeOrganization, loadOrganizations, handleError],\n );\n\n const removeMember = useCallback(\n async (memberId: string): Promise<void> => {\n if (!sdk.organization || !activeOrganization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n await sdk.organization.removeMember(activeOrganization.id, memberId, {\n notifyUser: true,\n });\n\n // Refresh organizations data\n await loadOrganizations();\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, activeOrganization, loadOrganizations, handleError],\n );\n\n const updateMemberRole = useCallback(\n async (memberId: string, role: string): Promise<void> => {\n if (!sdk.organization || !activeOrganization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n await sdk.organization.updateMemberRole(\n activeOrganization.id,\n memberId,\n {\n roleId: role,\n },\n );\n\n // Refresh organizations data\n await loadOrganizations();\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, activeOrganization, loadOrganizations, handleError],\n );\n\n const getMembers = useCallback(async (): Promise<OrganizationMember[]> => {\n if (!sdk.organization || !activeOrganization)\n throw new Error(\"Organization service not available\");\n\n try {\n const res = await sdk.organization.listMembers(activeOrganization.id);\n return (res.data ?? []).map(\n (item) =>\n ({\n id: item.userId,\n userId: item.userId,\n organizationId: item.organizationId,\n role: item.role,\n status: item.status,\n joinedAt: item.joinedAt,\n invitedBy: item.invitedBy,\n }) as OrganizationMember,\n );\n } catch (err) {\n handleError(err);\n return [];\n }\n }, [sdk.organization, activeOrganization, handleError]);\n\n // Invitation management methods\n const acceptInvitation = useCallback(\n async (\n token: string,\n opts?: {\n firstName?: string;\n lastName?: string;\n password?: string;\n },\n ): Promise<void> => {\n if (!sdk.organization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n const acceptRequest: AcceptInvitationRequest = {\n ...(opts ?? {}),\n token,\n acceptTerms: true,\n };\n await sdk.organization.acceptInvitation(acceptRequest);\n\n // Refresh organizations and invitations\n await loadOrganizations();\n await reload(); // User now belongs to new organization\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, loadOrganizations, reload, handleError],\n );\n\n const declineInvitation = useCallback(\n async (token: string): Promise<void> => {\n if (!sdk.organization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n const declineRequest: DeclineInvitationRequest = {\n token: token,\n };\n await sdk.organization.declineInvitation(declineRequest);\n\n // Refresh invitations\n await loadOrganizations();\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, loadOrganizations, handleError],\n );\n\n const cancelInvitation = useCallback(\n async (invitationId: string): Promise<void> => {\n if (!sdk.organization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n await sdk.organization.cancelInvitation(invitationId);\n\n // Refresh invitations\n await loadOrganizations();\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, loadOrganizations, handleError],\n );\n\n const resendInvitation = useCallback(\n async (invitationId: string): Promise<void> => {\n if (!sdk.organization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n await sdk.organization.resendInvitation(invitationId);\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [sdk.organization, handleError],\n );\n\n // Settings management\n const updateSettings = useCallback(\n async (\n settings: Partial<OrganizationSettings>,\n ): Promise<OrganizationSettings> => {\n if (!sdk.organization || !activeOrganization)\n throw new Error(\"Organization service not available\");\n\n try {\n setIsLoading(true);\n setError(null);\n\n const updatedSettings =\n await sdk.organization.updateOrganizationSettings(\n activeOrganization.id,\n settings,\n );\n\n // Refresh organization data\n await loadOrganizations();\n await reload();\n\n return updatedSettings;\n } catch (err) {\n return handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [\n sdk.organization,\n activeOrganization,\n loadOrganizations,\n reload,\n handleError,\n ],\n );\n\n // Convenience properties\n const organizationId = useMemo(\n () => activeOrganization?.id || null,\n [activeOrganization],\n );\n const organizationName = useMemo(\n () => activeOrganization?.name || null,\n [activeOrganization],\n );\n const organizationSlug = useMemo(\n () => activeOrganization?.slug || null,\n [activeOrganization],\n );\n\n // Role-based properties\n const currentMembership = useMemo(() => {\n if (!activeOrganization) return null;\n return organizationMemberships.find(\n (m) => m.organization.id === activeOrganization.id,\n );\n }, [activeOrganization, organizationMemberships]);\n\n const isOwner = useMemo(\n () => currentMembership?.role === \"owner\",\n [currentMembership],\n );\n const isAdmin = useMemo(\n () => [\"owner\", \"admin\"].includes(currentMembership?.role || \"\"),\n [currentMembership],\n );\n const isMember = useMemo(() => !!currentMembership, [currentMembership]);\n\n // Organization statistics\n const memberCount = useMemo(\n () => activeOrganization?.memberCount || 0,\n [activeOrganization],\n );\n const pendingInvitations = useMemo(\n () => invitations.filter((inv) => inv.status === \"pending\").length,\n [invitations],\n );\n\n // Multi-tenant helpers\n const hasOrganizations = useMemo(\n () => organizations.length > 0,\n [organizations],\n );\n const canCreateOrganization = useMemo(() => {\n // Internal users can always create organizations\n if (userType === \"internal\") return true;\n // External users can create organizations if they're owners of at least one\n if (userType === \"external\") {\n return organizationMemberships.some((m) => m.role === \"owner\");\n }\n // End users cannot create organizations\n return false;\n }, [userType, organizationMemberships]);\n\n const canSwitchOrganization = useMemo(\n () => organizations.length > 1,\n [organizations],\n );\n\n return {\n // Organization state\n organization,\n organizations,\n activeOrganization,\n memberships: organizationMemberships,\n invitations,\n isLoaded: !!sdk.organization,\n isLoading,\n error,\n\n // Organization management\n createOrganization,\n updateOrganization,\n deleteOrganization,\n switchOrganization,\n\n // Member management\n inviteMember,\n removeMember,\n updateMemberRole,\n getMembers,\n\n // Invitation management\n acceptInvitation,\n declineInvitation,\n cancelInvitation,\n resendInvitation,\n\n // Settings management\n updateSettings,\n\n // Convenience properties\n organizationId,\n organizationName,\n organizationSlug,\n isOwner,\n isAdmin,\n isMember,\n memberCount,\n pendingInvitations,\n\n // Multi-tenant helpers\n hasOrganizations,\n canCreateOrganization,\n canSwitchOrganization,\n };\n}\n\n// ============================================================================\n// Specialized Organization Hooks\n// ============================================================================\n\n/**\n * Hook for organization membership and role information\n */\nexport function useOrganizationMembership() {\n const {\n activeOrganization,\n memberships,\n isOwner,\n isAdmin,\n isMember,\n memberCount,\n } = useOrganization();\n\n const currentMembership = useMemo(() => {\n if (!activeOrganization) return null;\n return memberships.find((m) => m.organization.id === activeOrganization.id);\n }, [activeOrganization, memberships]);\n\n return {\n organization: activeOrganization,\n membership: currentMembership,\n role: currentMembership?.role || null,\n isOwner,\n isAdmin,\n isMember,\n memberCount,\n joinedAt: currentMembership?.joinedAt || null,\n status: currentMembership?.status || null,\n };\n}\n\n/**\n * Hook for organization invitations management\n */\nexport function useOrganizationInvitations() {\n const {\n invitations,\n acceptInvitation,\n declineInvitation,\n cancelInvitation,\n resendInvitation,\n inviteMember,\n isAdmin,\n isLoading,\n error,\n } = useOrganization();\n\n const pendingInvitations = useMemo(\n () => invitations.filter((inv) => inv.status === \"pending\"),\n [invitations],\n );\n\n const expiredInvitations = useMemo(\n () => invitations.filter((inv) => inv.status === \"expired\"),\n [invitations],\n );\n\n return {\n invitations,\n pendingInvitations,\n expiredInvitations,\n acceptInvitation,\n declineInvitation,\n cancelInvitation: isAdmin ? cancelInvitation : undefined,\n resendInvitation: isAdmin ? resendInvitation : undefined,\n inviteMember: isAdmin ? inviteMember : undefined,\n canManageInvitations: isAdmin,\n isLoading,\n error,\n };\n}\n\n/**\n * Hook for organization switching\n */\nexport function useOrganizationSwitcher() {\n const {\n organizations,\n activeOrganization,\n switchOrganization,\n canSwitchOrganization,\n isLoading,\n } = useOrganization();\n\n return {\n organizations,\n activeOrganization,\n switchOrganization,\n canSwitchOrganization,\n isLoading,\n hasMultipleOrganizations: organizations.length > 1,\n };\n}\n"],"names":["useOrganization","organization","organizationMemberships","activeOrganization","authSwitchOrganization","session","reload","useAuth","sdk","useAuthProvider","apiUrl","publishableKey","userType","useConfig","organizations","setOrganizations","useState","invitations","setInvitations","isLoading","setIsLoading","error","setError","handleError","useCallback","err","authError","loadOrganizations","orgsData","useEffect","createOrganization","params","createRequest","newOrganization","updateOrganization","organizationId","updateRequest","updatedOrganization","deleteOrganization","switchOrganization","inviteMember","inviteRequest","removeMember","memberId","updateMemberRole","role","getMembers","item","acceptInvitation","token","opts","acceptRequest","declineInvitation","declineRequest","cancelInvitation","invitationId","resendInvitation","updateSettings","settings","updatedSettings","useMemo","organizationName","organizationSlug","currentMembership","m","isOwner","isAdmin","isMember","memberCount","pendingInvitations","inv","hasOrganizations","canCreateOrganization","canSwitchOrganization","useOrganizationMembership","memberships","useOrganizationInvitations","expiredInvitations","useOrganizationSwitcher"],"mappings":"6NAmMO,SAASA,GAAyC,CAC/C,KAAA,CACF,aAAAC,EACA,wBAAAC,EACA,mBAAAC,EACA,mBAAoBC,EACpB,QAAAC,EACA,OAAAC,GACAC,UAAQ,EACN,CAAC,IAAAC,CAAG,EAAIC,UAAgB,EAExB,CAAC,OAAAC,EAAQ,eAAAC,EAAgB,SAAAC,CAAA,EAAYC,EAAAA,UAAU,EAE/C,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAAyB,CAAA,CAAE,EAC/D,CAACC,EAAaC,EAAc,EAAIF,EAAAA,SAAmC,CAAA,CAAE,EACrE,CAACG,EAAWC,CAAY,EAAIJ,EAAAA,SAAS,EAAK,EAC1C,CAACK,EAAOC,CAAQ,EAAIN,EAAAA,SAA2B,IAAI,EAGnDO,EAAcC,cAAaC,GAAa,CAC1C,MAAMC,EAAuB,CACzB,KAAMD,EAAI,MAAQ,gBAClB,QAASA,EAAI,SAAW,4BACxB,QAASA,EAAI,QACb,MAAOA,EAAI,KACf,EACA,MAAAH,EAASI,CAAS,EACZA,CACV,EAAG,EAAE,EAGCC,EAAoBH,EAAAA,YAAY,SAAY,CAC1C,GAAA,CACAJ,EAAa,EAAI,EACjBE,EAAS,IAAI,EAGb,MAAMM,EAAW,MAAMpB,EAAI,aAAa,kBAAkB,CACtD,OAAQ,CAAA,CAAC,CACZ,EACiBO,EAAAa,EAAS,MAAQ,EAAU,QAKxCH,EAAK,CACF,QAAA,MAAM,gCAAiCA,CAAG,EACzCH,EAAA,CACL,KAAM,4BACN,QAAS,8BAAA,CACZ,CAAA,QACH,CACEF,EAAa,EAAK,CAAA,CACtB,EACD,CAACZ,EAAI,YAAY,CAAC,EAErBqB,EAAAA,UAAU,IAAM,CACMF,EAAA,CAAA,EACnB,CAACA,CAAiB,CAAC,EAGtB,MAAMG,EAAqBN,EAAA,YACvB,MAAOO,GAA4D,CAC/D,GAAI,CAACvB,EAAI,aACC,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAY,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,MAAMU,EAA2C,CAC7C,KAAMD,EAAO,KACb,KAAMA,EAAO,KAEb,QAASA,EAAO,QAChB,WAAYA,EAAO,WACnB,SAAUA,EAAO,SACjB,KAAMA,EAAO,QAAU,MAQ3B,EAEME,EACF,MAAMzB,EAAI,aAAa,mBAAmBwB,CAAa,EAG3D,aAAML,EAAkB,EACxB,MAAMrB,EAAO,EAEN2B,QACFR,EAAK,CACV,OAAOF,EAAYE,CAAG,CAAA,QACxB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcmB,EAAmBrB,EAAQiB,CAAW,CAC7D,EAEMW,EAAqBV,EAAA,YACvB,MACIW,EACAJ,IACwB,CACxB,GAAI,CAACvB,EAAI,aACC,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAY,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,MAAMc,EAA2C,CAC7C,KAAML,EAAO,KACb,KAAMA,EAAO,KACb,YAAaA,EAAO,YACpB,QAASA,EAAO,QAChB,WAAYA,EAAO,WACnB,SAAUA,EAAO,QACrB,EAEMM,EAAsB,MAAM7B,EAAI,aAAa,mBAC/C2B,EACAC,CACJ,EAGA,aAAMT,EAAkB,EACxB,MAAMrB,EAAO,EAEN+B,QACFZ,EAAK,CACV,OAAOF,EAAYE,CAAG,CAAA,QACxB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcmB,EAAmBrB,EAAQiB,CAAW,CAC7D,EAEMe,EAAqBd,EAAA,YACvB,MAAOW,GAA0C,CAC7C,GAAI,CAAC3B,EAAI,aACC,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAY,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEP,MAAAd,EAAI,aAAa,mBAAmB2B,EAAgB,CACtD,cAAe,GACf,QAAS,GACT,cAAe,CAAA,CAClB,EAGD,MAAMR,EAAkB,EACxB,MAAMrB,EAAO,QACRmB,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcmB,EAAmBrB,EAAQiB,CAAW,CAC7D,EAEMgB,EAAqBf,EAAA,YACvB,MAAOW,GAA0C,CAC7C,MAAM/B,EAAuB+B,CAAc,EAC3C,MAAMR,EAAkB,CAC5B,EACA,CAACvB,EAAwBuB,CAAiB,CAC9C,EAGMa,EAAehB,EAAA,YACjB,MAAOO,GAA8C,CAC7C,GAAA,CAACvB,EAAI,cAAgB,CAACL,EAChB,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAiB,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,MAAMmB,EAAyC,CAC3C,aAAcV,EAAO,aACrB,KAAMA,EAAO,KACb,YAAaA,EAAO,YACpB,eAAgBA,EAAO,eACvB,gBAAiBA,EAAO,gBACxB,iBAAkB,GAClB,iBAAkB,GAClB,OAAQA,EAAO,KACf,oBAAqB,EACzB,EAEA,MAAMvB,EAAI,aAAa,UAAUL,EAAmB,GAAIsC,CAAa,EAGrE,MAAMd,EAAkB,QACnBF,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcL,EAAoBwB,EAAmBJ,CAAW,CACzE,EAEMmB,EAAelB,EAAA,YACjB,MAAOmB,GAAoC,CACnC,GAAA,CAACnC,EAAI,cAAgB,CAACL,EAChB,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAiB,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,MAAMd,EAAI,aAAa,aAAaL,EAAmB,GAAIwC,EAAU,CACjE,WAAY,EAAA,CACf,EAGD,MAAMhB,EAAkB,QACnBF,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcL,EAAoBwB,EAAmBJ,CAAW,CACzE,EAEMqB,EAAmBpB,EAAA,YACrB,MAAOmB,EAAkBE,IAAgC,CACjD,GAAA,CAACrC,EAAI,cAAgB,CAACL,EAChB,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAiB,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,MAAMd,EAAI,aAAa,iBACnBL,EAAmB,GACnBwC,EACA,CACI,OAAQE,CAAA,CAEhB,EAGA,MAAMlB,EAAkB,QACnBF,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcL,EAAoBwB,EAAmBJ,CAAW,CACzE,EAEMuB,EAAatB,EAAAA,YAAY,SAA2C,CAClE,GAAA,CAAChB,EAAI,cAAgB,CAACL,EAChB,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CAEQ,QADI,MAAMK,EAAI,aAAa,YAAYL,EAAmB,EAAE,GACxD,MAAQ,CAAA,GAAI,IACnB4C,IACI,CACG,GAAIA,EAAK,OACT,OAAQA,EAAK,OACb,eAAgBA,EAAK,eACrB,KAAMA,EAAK,KACX,OAAQA,EAAK,OACb,SAAUA,EAAK,SACf,UAAWA,EAAK,SACpB,EACR,QACKtB,EAAK,CACV,OAAAF,EAAYE,CAAG,EACR,CAAC,CAAA,GAEb,CAACjB,EAAI,aAAcL,EAAoBoB,CAAW,CAAC,EAGhDyB,EAAmBxB,EAAA,YACrB,MACIyB,EACAC,IAKgB,CAChB,GAAI,CAAC1C,EAAI,aACC,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAY,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,MAAM6B,EAAyC,CAC3C,GAAID,GAAQ,CAAC,EACb,MAAAD,EACA,YAAa,EACjB,EACM,MAAAzC,EAAI,aAAa,iBAAiB2C,CAAa,EAGrD,MAAMxB,EAAkB,EACxB,MAAMrB,EAAO,QACRmB,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcmB,EAAmBrB,EAAQiB,CAAW,CAC7D,EAEM6B,EAAoB5B,EAAA,YACtB,MAAOyB,GAAiC,CACpC,GAAI,CAACzC,EAAI,aACC,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAY,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,MAAM+B,EAA2C,CAC7C,MAAAJ,CACJ,EACM,MAAAzC,EAAI,aAAa,kBAAkB6C,CAAc,EAGvD,MAAM1B,EAAkB,QACnBF,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcmB,EAAmBJ,CAAW,CACrD,EAEM+B,EAAmB9B,EAAA,YACrB,MAAO+B,GAAwC,CAC3C,GAAI,CAAC/C,EAAI,aACC,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAY,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEP,MAAAd,EAAI,aAAa,iBAAiB+C,CAAY,EAGpD,MAAM5B,EAAkB,QACnBF,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAcmB,EAAmBJ,CAAW,CACrD,EAEMiC,EAAmBhC,EAAA,YACrB,MAAO+B,GAAwC,CAC3C,GAAI,CAAC/C,EAAI,aACC,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAY,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEP,MAAAd,EAAI,aAAa,iBAAiB+C,CAAY,QAC/C9B,EAAK,CACVF,EAAYE,CAAG,CAAA,QACjB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CAACZ,EAAI,aAAce,CAAW,CAClC,EAGMkC,EAAiBjC,EAAA,YACnB,MACIkC,GACgC,CAC5B,GAAA,CAAClD,EAAI,cAAgB,CAACL,EAChB,MAAA,IAAI,MAAM,oCAAoC,EAEpD,GAAA,CACAiB,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEP,MAAAqC,EACF,MAAMnD,EAAI,aAAa,2BACnBL,EAAmB,GACnBuD,CACJ,EAGJ,aAAM/B,EAAkB,EACxB,MAAMrB,EAAO,EAENqD,QACFlC,EAAK,CACV,OAAOF,EAAYE,CAAG,CAAA,QACxB,CACEL,EAAa,EAAK,CAAA,CAE1B,EACA,CACIZ,EAAI,aACJL,EACAwB,EACArB,EACAiB,CAAA,CAER,EAGMY,EAAiByB,EAAA,QACnB,IAAMzD,GAAoB,IAAM,KAChC,CAACA,CAAkB,CACvB,EACM0D,EAAmBD,EAAA,QACrB,IAAMzD,GAAoB,MAAQ,KAClC,CAACA,CAAkB,CACvB,EACM2D,EAAmBF,EAAA,QACrB,IAAMzD,GAAoB,MAAQ,KAClC,CAACA,CAAkB,CACvB,EAGM4D,EAAoBH,EAAAA,QAAQ,IACzBzD,EACED,EAAwB,KAC1B8D,GAAMA,EAAE,aAAa,KAAO7D,EAAmB,EACpD,EAHgC,KAIjC,CAACA,EAAoBD,CAAuB,CAAC,EAE1C+D,EAAUL,EAAA,QACZ,IAAMG,GAAmB,OAAS,QAClC,CAACA,CAAiB,CACtB,EACMG,EAAUN,EAAA,QACZ,IAAM,CAAC,QAAS,OAAO,EAAE,SAASG,GAAmB,MAAQ,EAAE,EAC/D,CAACA,CAAiB,CACtB,EACMI,EAAWP,EAAAA,QAAQ,IAAM,CAAC,CAACG,EAAmB,CAACA,CAAiB,CAAC,EAGjEK,EAAcR,EAAA,QAChB,IAAMzD,GAAoB,aAAe,EACzC,CAACA,CAAkB,CACvB,EACMkE,EAAqBT,EAAA,QACvB,IAAM3C,EAAY,OAAQqD,GAAQA,EAAI,SAAW,SAAS,EAAE,OAC5D,CAACrD,CAAW,CAChB,EAGMsD,EAAmBX,EAAA,QACrB,IAAM9C,EAAc,OAAS,EAC7B,CAACA,CAAa,CAClB,EACM0D,EAAwBZ,EAAAA,QAAQ,IAE9BhD,IAAa,WAAmB,GAEhCA,IAAa,WACNV,EAAwB,KAAM8D,GAAMA,EAAE,OAAS,OAAO,EAG1D,GACR,CAACpD,EAAUV,CAAuB,CAAC,EAEhCuE,EAAwBb,EAAA,QAC1B,IAAM9C,EAAc,OAAS,EAC7B,CAACA,CAAa,CAClB,EAEO,MAAA,CAEH,aAAAb,EACA,cAAAa,EACA,mBAAAX,EACA,YAAaD,EACb,YAAAe,EACA,SAAU,CAAC,CAACT,EAAI,aAChB,UAAAW,EACA,MAAAE,EAGA,mBAAAS,EACA,mBAAAI,EACA,mBAAAI,EACA,mBAAAC,EAGA,aAAAC,EACA,aAAAE,EACA,iBAAAE,EACA,WAAAE,EAGA,iBAAAE,EACA,kBAAAI,EACA,iBAAAE,EACA,iBAAAE,EAGA,eAAAC,EAGA,eAAAtB,EACA,iBAAA0B,EACA,iBAAAC,EACA,QAAAG,EACA,QAAAC,EACA,SAAAC,EACA,YAAAC,EACA,mBAAAC,EAGA,iBAAAE,EACA,sBAAAC,EACA,sBAAAC,CACJ,CACJ,CASO,SAASC,GAA4B,CAClC,KAAA,CACF,mBAAAvE,EACA,YAAAwE,EACA,QAAAV,EACA,QAAAC,EACA,SAAAC,EACA,YAAAC,GACApE,EAAgB,EAEd+D,EAAoBH,EAAAA,QAAQ,IACzBzD,EACEwE,EAAY,KAAMX,GAAMA,EAAE,aAAa,KAAO7D,EAAmB,EAAE,EAD1C,KAEjC,CAACA,EAAoBwE,CAAW,CAAC,EAE7B,MAAA,CACH,aAAcxE,EACd,WAAY4D,EACZ,KAAMA,GAAmB,MAAQ,KACjC,QAAAE,EACA,QAAAC,EACA,SAAAC,EACA,YAAAC,EACA,SAAUL,GAAmB,UAAY,KACzC,OAAQA,GAAmB,QAAU,IACzC,CACJ,CAKO,SAASa,IAA6B,CACnC,KAAA,CACF,YAAA3D,EACA,iBAAA+B,EACA,kBAAAI,EACA,iBAAAE,EACA,iBAAAE,EACA,aAAAhB,EACA,QAAA0B,EACA,UAAA/C,EACA,MAAAE,GACArB,EAAgB,EAEdqE,EAAqBT,EAAA,QACvB,IAAM3C,EAAY,OAAQqD,GAAQA,EAAI,SAAW,SAAS,EAC1D,CAACrD,CAAW,CAChB,EAEM4D,EAAqBjB,EAAA,QACvB,IAAM3C,EAAY,OAAQqD,GAAQA,EAAI,SAAW,SAAS,EAC1D,CAACrD,CAAW,CAChB,EAEO,MAAA,CACH,YAAAA,EACA,mBAAAoD,EACA,mBAAAQ,EACA,iBAAA7B,EACA,kBAAAI,EACA,iBAAkBc,EAAUZ,EAAmB,OAC/C,iBAAkBY,EAAUV,EAAmB,OAC/C,aAAcU,EAAU1B,EAAe,OACvC,qBAAsB0B,EACtB,UAAA/C,EACA,MAAAE,CACJ,CACJ,CAKO,SAASyD,IAA0B,CAChC,KAAA,CACF,cAAAhE,EACA,mBAAAX,EACA,mBAAAoC,EACA,sBAAAkC,EACA,UAAAtD,GACAnB,EAAgB,EAEb,MAAA,CACH,cAAAc,EACA,mBAAAX,EACA,mBAAAoC,EACA,sBAAAkC,EACA,UAAAtD,EACA,yBAA0BL,EAAc,OAAS,CACrD,CACJ"}