@rqdhw3n/react-auth-flow 1.0.3 → 1.0.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/context/AuthContext.ts","../src/utils/normalizeError.ts","../src/services/createAuthClient.ts","../src/context/AuthProvider.tsx","../src/hooks/useAuth.ts","../src/components/LoginForm.tsx","../src/components/RegisterForm.tsx","../src/components/ForgotPasswordForm.tsx","../src/components/ResetPasswordForm.tsx","../src/components/VerifyEmailForm.tsx","../src/components/ProtectedRoute.tsx"],"sourcesContent":["import { createContext } from \"react\";\r\nimport { AuthContextValue } from \"../types\";\r\n\r\n/**\r\n * Auth Context\r\n * Provides authentication state and methods to the application\r\n */\r\nexport const AuthContext = createContext<AuthContextValue | undefined>(\r\n undefined\r\n);\r\n\r\nAuthContext.displayName = \"AuthContext\";\r\n","import { AuthError } from \"../types\";\r\n\r\n/**\r\n * Normalizes various error types into a consistent AuthError format\r\n */\r\nexport function normalizeError(error: unknown): AuthError {\r\n // Handle AuthError objects\r\n if (isAuthError(error)) {\r\n return error;\r\n }\r\n\r\n // Handle standard Error objects\r\n if (error instanceof Error) {\r\n return {\r\n code: \"ERROR\",\r\n message: error.message,\r\n statusCode: undefined,\r\n };\r\n }\r\n\r\n // Handle fetch errors with response\r\n if (\r\n typeof error === \"object\" &&\r\n error !== null &&\r\n \"status\" in error &&\r\n \"statusText\" in error\r\n ) {\r\n const fetchError = error as { status: number; statusText: string };\r\n return {\r\n code: `HTTP_${fetchError.status}`,\r\n message: fetchError.statusText || \"Request failed\",\r\n statusCode: fetchError.status,\r\n };\r\n }\r\n\r\n // Handle JSON API error response\r\n if (\r\n typeof error === \"object\" &&\r\n error !== null &&\r\n \"error\" in error &&\r\n typeof error.error === \"object\"\r\n ) {\r\n const apiError = error.error as Record<string, unknown>;\r\n return {\r\n code: (apiError.code as string) || \"API_ERROR\",\r\n message: (apiError.message as string) || \"An error occurred\",\r\n statusCode: (apiError.statusCode as number) || undefined,\r\n details: apiError.details as Record<string, unknown>,\r\n };\r\n }\r\n\r\n // Handle plain objects with message property\r\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\r\n const objError = error as { message: unknown; code?: unknown };\r\n return {\r\n code: (objError.code as string) || \"ERROR\",\r\n message:\r\n typeof objError.message === \"string\"\r\n ? objError.message\r\n : \"An unknown error occurred\",\r\n };\r\n }\r\n\r\n // Handle strings\r\n if (typeof error === \"string\") {\r\n return {\r\n code: \"ERROR\",\r\n message: error,\r\n };\r\n }\r\n\r\n // Fallback\r\n return {\r\n code: \"UNKNOWN_ERROR\",\r\n message: \"An unknown error occurred\",\r\n };\r\n}\r\n\r\n/**\r\n * Type guard to check if an object is an AuthError\r\n */\r\nfunction isAuthError(error: unknown): error is AuthError {\r\n return (\r\n typeof error === \"object\" &&\r\n error !== null &&\r\n \"code\" in error &&\r\n \"message\" in error &&\r\n typeof (error as AuthError).code === \"string\" &&\r\n typeof (error as AuthError).message === \"string\"\r\n );\r\n}\r\n","import {\r\n AuthClientConfig,\r\n AuthEndpoints,\r\n RequestAdapter,\r\n AuthResponse,\r\n} from \"../types\";\r\nimport { normalizeError } from \"../utils/normalizeError\";\r\n\r\n/**\r\n * Default endpoints\r\n */\r\nconst DEFAULT_ENDPOINTS: AuthEndpoints = {\r\n login: \"/auth/login\",\r\n register: \"/auth/register\",\r\n logout: \"/auth/logout\",\r\n me: \"/auth/me\",\r\n refresh: \"/auth/refresh\",\r\n forgotPassword: \"/auth/forgot-password\",\r\n resetPassword: \"/auth/reset-password\",\r\n verifyEmail: \"/auth/verify-email\",\r\n};\r\n\r\n/**\r\n * Default request adapter using fetch\r\n */\r\nconst defaultAdapter: RequestAdapter = async (url, options) => {\r\n const response = await fetch(url, options);\r\n return response;\r\n};\r\n\r\n/**\r\n * Creates an authenticated API client\r\n */\r\nexport function createAuthClient(config: AuthClientConfig = {}) {\r\n const {\r\n baseURL = \"\",\r\n endpoints = {},\r\n headers = {},\r\n credentials = \"include\",\r\n adapter = defaultAdapter,\r\n } = config;\r\n\r\n const finalEndpoints = { ...DEFAULT_ENDPOINTS, ...endpoints };\r\n\r\n /**\r\n * Makes an authenticated request\r\n */\r\n async function request<T = unknown>(\r\n method: string,\r\n endpoint: string,\r\n data?: Record<string, unknown>\r\n ): Promise<T> {\r\n const url = `${baseURL}${endpoint}`;\r\n const options: RequestInit = {\r\n method,\r\n credentials,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...headers,\r\n },\r\n };\r\n\r\n if (data) {\r\n options.body = JSON.stringify(data);\r\n }\r\n\r\n try {\r\n const response = await adapter(url, options);\r\n\r\n if (!response.ok) {\r\n let errorData: unknown = null;\r\n try {\r\n errorData = await response.json();\r\n } catch {\r\n errorData = {\r\n error: {\r\n message: response.statusText,\r\n statusCode: response.status,\r\n },\r\n };\r\n }\r\n throw errorData;\r\n }\r\n\r\n const contentType = response.headers.get(\"content-type\");\r\n if (contentType && contentType.includes(\"application/json\")) {\r\n return await response.json();\r\n }\r\n\r\n return {} as T;\r\n } catch (error) {\r\n throw normalizeError(error);\r\n }\r\n }\r\n\r\n return {\r\n /**\r\n * Login with email and password\r\n */\r\n async login(email: string, password: string, rememberMe?: boolean) {\r\n const response = await request<AuthResponse>(\r\n \"POST\",\r\n finalEndpoints.login!,\r\n { email, password, rememberMe }\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Register a new account\r\n */\r\n async register(payload: Record<string, unknown>) {\r\n const response = await request<AuthResponse>(\r\n \"POST\",\r\n finalEndpoints.register!,\r\n payload\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Logout the user\r\n */\r\n async logout() {\r\n await request(\"POST\", finalEndpoints.logout!);\r\n },\r\n\r\n /**\r\n * Get current user\r\n */\r\n async me() {\r\n const response = await request<AuthResponse>(\r\n \"GET\",\r\n finalEndpoints.me!\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Refresh the authentication session\r\n */\r\n async refresh() {\r\n const response = await request<AuthResponse>(\r\n \"POST\",\r\n finalEndpoints.refresh!\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Request a password reset\r\n */\r\n async forgotPassword(email: string) {\r\n await request(\"POST\", finalEndpoints.forgotPassword!, { email });\r\n },\r\n\r\n /**\r\n * Reset password with token\r\n */\r\n async resetPassword(\r\n token: string,\r\n password: string,\r\n confirmPassword?: string\r\n ) {\r\n await request(\"POST\", finalEndpoints.resetPassword!, {\r\n token,\r\n password,\r\n confirmPassword,\r\n });\r\n },\r\n\r\n /**\r\n * Verify email with token\r\n */\r\n async verifyEmail(token: string, email?: string) {\r\n await request(\"POST\", finalEndpoints.verifyEmail!, { token, email });\r\n },\r\n\r\n /**\r\n * Set custom headers for subsequent requests\r\n */\r\n setHeaders(newHeaders: Record<string, string>) {\r\n Object.assign(headers, newHeaders);\r\n },\r\n\r\n /**\r\n * Get current endpoints configuration\r\n */\r\n getEndpoints() {\r\n return finalEndpoints;\r\n },\r\n };\r\n}\r\n\r\nexport type AuthClient = ReturnType<typeof createAuthClient>;\r\n","import React, { useEffect, useReducer, useCallback } from \"react\";\r\nimport {\r\n AuthProviderProps,\r\n AuthUser,\r\n AuthError,\r\n LoginPayload,\r\n RegisterPayload,\r\n ForgotPasswordPayload,\r\n ResetPasswordPayload,\r\n VerifyEmailPayload,\r\n} from \"../types\";\r\nimport { AuthContext } from \"./AuthContext\";\r\nimport { createAuthClient } from \"../services/createAuthClient\";\r\nimport { normalizeError } from \"../utils/normalizeError\";\r\n\r\n/**\r\n * Auth state\r\n */\r\ninterface AuthState {\r\n user: AuthUser | null;\r\n isAuthenticated: boolean;\r\n isLoading: boolean;\r\n error: AuthError | null;\r\n}\r\n\r\n/**\r\n * Auth state actions\r\n */\r\ntype AuthAction =\r\n | { type: \"SET_LOADING\"; payload: boolean }\r\n | { type: \"SET_ERROR\"; payload: AuthError | null }\r\n | { type: \"SET_USER\"; payload: AuthUser | null }\r\n | { type: \"LOGOUT\" };\r\n\r\n/**\r\n * Initial state\r\n */\r\nconst initialState: AuthState = {\r\n user: null,\r\n isAuthenticated: false,\r\n isLoading: false,\r\n error: null,\r\n};\r\n\r\n/**\r\n * Auth reducer\r\n */\r\nfunction authReducer(state: AuthState, action: AuthAction): AuthState {\r\n switch (action.type) {\r\n case \"SET_LOADING\":\r\n return { ...state, isLoading: action.payload };\r\n\r\n case \"SET_ERROR\":\r\n return { ...state, error: action.payload, isLoading: false };\r\n\r\n case \"SET_USER\":\r\n return {\r\n ...state,\r\n user: action.payload,\r\n isAuthenticated: action.payload !== null,\r\n error: null,\r\n isLoading: false,\r\n };\r\n\r\n case \"LOGOUT\":\r\n return initialState;\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n\r\n/**\r\n * AuthProvider component\r\n * Provides authentication state and methods to the entire application\r\n */\r\nexport const AuthProvider: React.FC<AuthProviderProps> = ({\r\n children,\r\n baseURL = \"\",\r\n endpoints = {},\r\n onAuthError,\r\n autoRefresh = true,\r\n refreshInterval = 5 * 60 * 1000, // 5 minutes\r\n}) => {\r\n const [state, dispatch] = useReducer(authReducer, initialState);\r\n const clientRef = React.useRef(\r\n createAuthClient({\r\n baseURL,\r\n endpoints,\r\n credentials: \"include\",\r\n })\r\n );\r\n\r\n const client = clientRef.current;\r\n\r\n /**\r\n * Handle auth error\r\n */\r\n const handleError = useCallback(\r\n (error: AuthError) => {\r\n dispatch({ type: \"SET_ERROR\", payload: error });\r\n onAuthError?.(error);\r\n },\r\n [onAuthError]\r\n );\r\n\r\n /**\r\n * Restore session on mount\r\n */\r\n const restoreSession = useCallback(async () => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n const response = await client.me();\r\n if (response.user) {\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n } else {\r\n dispatch({ type: \"LOGOUT\" });\r\n }\r\n } catch (_error) {\r\n // Session restore failure is not always an error state\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n }\r\n }, [client]);\r\n\r\n /**\r\n * Refresh session\r\n */\r\n const refreshSession = useCallback(async () => {\r\n try {\r\n const response = await client.refresh();\r\n if (response.user) {\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n }\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n }\r\n }, [client, handleError]);\r\n\r\n /**\r\n * Login\r\n */\r\n const login = useCallback(\r\n async (payload: LoginPayload): Promise<AuthUser> => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n const response = await client.login(payload.email, payload.password);\r\n if (!response.user) {\r\n throw new Error(\"No user data in response\");\r\n }\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n return response.user;\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Register\r\n */\r\n const register = useCallback(\r\n async (payload: RegisterPayload): Promise<AuthUser> => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n const response = await client.register(payload);\r\n if (!response.user) {\r\n throw new Error(\"No user data in response\");\r\n }\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n return response.user;\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Logout\r\n */\r\n const logout = useCallback(async () => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.logout();\r\n } catch (error) {\r\n // Log but don't throw on logout error\r\n console.error(\"Logout error:\", error);\r\n } finally {\r\n dispatch({ type: \"LOGOUT\" });\r\n }\r\n }, [client]);\r\n\r\n /**\r\n * Forgot password\r\n */\r\n const forgotPassword = useCallback(\r\n async (payload: ForgotPasswordPayload) => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.forgotPassword(payload.email);\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Reset password\r\n */\r\n const resetPassword = useCallback(\r\n async (payload: ResetPasswordPayload) => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.resetPassword(\r\n payload.token,\r\n payload.password,\r\n payload.confirmPassword\r\n );\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Verify email\r\n */\r\n const verifyEmail = useCallback(\r\n async (payload: VerifyEmailPayload) => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.verifyEmail(payload.token, payload.email);\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Set user\r\n */\r\n const setUser = useCallback((user: AuthUser | null) => {\r\n dispatch({ type: \"SET_USER\", payload: user });\r\n }, []);\r\n\r\n /**\r\n * Effect: Restore session on mount\r\n */\r\n useEffect(() => {\r\n restoreSession();\r\n }, [restoreSession]);\r\n\r\n /**\r\n * Effect: Auto-refresh session\r\n */\r\n useEffect(() => {\r\n if (!autoRefresh || !state.isAuthenticated) {\r\n return;\r\n }\r\n\r\n const interval = setInterval(() => {\r\n refreshSession();\r\n }, refreshInterval);\r\n\r\n return () => clearInterval(interval);\r\n }, [autoRefresh, state.isAuthenticated, refreshSession, refreshInterval]);\r\n\r\n const value = {\r\n ...state,\r\n login,\r\n register,\r\n logout,\r\n forgotPassword,\r\n resetPassword,\r\n verifyEmail,\r\n refreshSession,\r\n restoreSession,\r\n setUser,\r\n };\r\n\r\n return (\r\n <AuthContext.Provider value={value}>{children}</AuthContext.Provider>\r\n );\r\n};\r\n","import { useContext } from \"react\";\r\nimport { AuthContext } from \"../context/AuthContext\";\r\nimport { AuthContextValue } from \"../types\";\r\n\r\n/**\r\n * Hook to access auth context\r\n * Must be used within an AuthProvider\r\n */\r\nexport function useAuth(): AuthContextValue {\r\n const context = useContext(AuthContext);\r\n\r\n if (!context) {\r\n throw new Error(\"useAuth must be used within an AuthProvider\");\r\n }\r\n\r\n return context;\r\n}\r\n","import React, { useState } from \"react\";\r\nimport { LoginFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\n\r\n/**\r\n * LoginForm Component\r\n * A ready-to-use login form with customizable styling and callbacks\r\n */\r\nexport const LoginForm: React.FC<LoginFormProps> = ({\r\n className = \"\",\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Login\",\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const { login, isLoading: authLoading, error: authError } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [rememberMe, setRememberMe] = useState(false);\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n\r\n if (!email || !password) {\r\n setFormError(\"Email and password are required\");\r\n return;\r\n }\r\n\r\n try {\r\n const user = await login({ email, password, rememberMe });\r\n onSuccess?.(user);\r\n } catch (err) {\r\n const errorMsg = err instanceof Error ? err.message : \"Login failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"LOGIN_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className={className}>\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"email\" className=\"auth-form-label\">\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"password\" className=\"auth-form-label\">\r\n {labels.password || \"Password\"}\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder={placeholders.password || \"••••••••\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"auth-form-group auth-form-checkbox\">\r\n <input\r\n id=\"rememberMe\"\r\n type=\"checkbox\"\r\n checked={rememberMe}\r\n onChange={(e) => setRememberMe(e.target.checked)}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n />\r\n <label htmlFor=\"rememberMe\" className=\"auth-form-label\">\r\n {labels.rememberMe || \"Remember me\"}\r\n </label>\r\n </div>\r\n\r\n {error && <div className=\"auth-form-error\">{error}</div>}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className=\"auth-form-button auth-form-button-primary\"\r\n >\r\n {isLoading ? \"Loading...\" : submitButtonText}\r\n </button>\r\n </form>\r\n );\r\n};\r\n\r\nLoginForm.displayName = \"LoginForm\";\r\n","import React, { useState } from \"react\";\r\nimport { RegisterFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\n\r\n/**\r\n * RegisterForm Component\r\n * A ready-to-use registration form with customizable styling and callbacks\r\n */\r\nexport const RegisterForm: React.FC<RegisterFormProps> = ({\r\n className = \"\",\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Register\",\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const { register, isLoading: authLoading, error: authError } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [name, setName] = useState(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [confirmPassword, setConfirmPassword] = useState(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n\r\n if (!name || !email || !password || !confirmPassword) {\r\n setFormError(\"All fields are required\");\r\n return;\r\n }\r\n\r\n if (password !== confirmPassword) {\r\n setFormError(\"Passwords do not match\");\r\n return;\r\n }\r\n\r\n if (password.length < 8) {\r\n setFormError(\"Password must be at least 8 characters\");\r\n return;\r\n }\r\n\r\n try {\r\n const user = await register({\r\n name,\r\n email,\r\n password,\r\n confirmPassword,\r\n });\r\n onSuccess?.(user);\r\n } catch (err) {\r\n const errorMsg = err instanceof Error ? err.message : \"Registration failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"REGISTER_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className={className}>\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"name\" className=\"auth-form-label\">\r\n {labels.name || \"Full Name\"}\r\n </label>\r\n <input\r\n id=\"name\"\r\n type=\"text\"\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder={placeholders.name || \"John Doe\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"email\" className=\"auth-form-label\">\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"password\" className=\"auth-form-label\">\r\n {labels.password || \"Password\"}\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder={placeholders.password || \"••••••••\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"confirmPassword\" className=\"auth-form-label\">\r\n {labels.confirmPassword || \"Confirm Password\"}\r\n </label>\r\n <input\r\n id=\"confirmPassword\"\r\n type=\"password\"\r\n value={confirmPassword}\r\n onChange={(e) => setConfirmPassword(e.target.value)}\r\n placeholder={placeholders.confirmPassword || \"••••••••\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n {error && <div className=\"auth-form-error\">{error}</div>}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className=\"auth-form-button auth-form-button-primary\"\r\n >\r\n {isLoading ? \"Loading...\" : submitButtonText}\r\n </button>\r\n </form>\r\n );\r\n};\r\n\r\nRegisterForm.displayName = \"RegisterForm\";\r\n","import React, { useState } from \"react\";\r\nimport { ForgotPasswordFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\n\r\n/**\r\n * ForgotPasswordForm Component\r\n * A ready-to-use forgot password form with customizable styling and callbacks\r\n */\r\nexport const ForgotPasswordForm: React.FC<ForgotPasswordFormProps> = ({\r\n className = \"\",\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Send Reset Link\",\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const {\r\n forgotPassword,\r\n isLoading: authLoading,\r\n error: authError,\r\n } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [successMessage, setSuccessMessage] = useState<string>(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n setSuccessMessage(\"\");\r\n\r\n if (!email) {\r\n setFormError(\"Email is required\");\r\n return;\r\n }\r\n\r\n try {\r\n await forgotPassword({ email });\r\n setSuccessMessage(\"Password reset link has been sent to your email\");\r\n setEmail(\"\");\r\n onSuccess?.();\r\n } catch (err) {\r\n const errorMsg =\r\n err instanceof Error ? err.message : \"Request failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"FORGOT_PASSWORD_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n if (successMessage) {\r\n return (\r\n <div className={`auth-form-success ${className}`}>\r\n <p className=\"auth-form-success-message\">{successMessage}</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className={className}>\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"email\" className=\"auth-form-label\">\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n {error && <div className=\"auth-form-error\">{error}</div>}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className=\"auth-form-button auth-form-button-primary\"\r\n >\r\n {isLoading ? \"Loading...\" : submitButtonText}\r\n </button>\r\n </form>\r\n );\r\n};\r\n\r\nForgotPasswordForm.displayName = \"ForgotPasswordForm\";\r\n","import React, { useState } from \"react\";\r\nimport { ResetPasswordFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\n\r\n/**\r\n * ResetPasswordForm Component\r\n * A ready-to-use password reset form with customizable styling and callbacks\r\n */\r\nexport const ResetPasswordForm: React.FC<ResetPasswordFormProps> = ({\r\n token,\r\n className = \"\",\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Reset Password\",\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const {\r\n resetPassword,\r\n isLoading: authLoading,\r\n error: authError,\r\n } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [confirmPassword, setConfirmPassword] = useState(\"\");\r\n const [successMessage, setSuccessMessage] = useState<string>(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n setSuccessMessage(\"\");\r\n\r\n if (!password || !confirmPassword) {\r\n setFormError(\"Both password fields are required\");\r\n return;\r\n }\r\n\r\n if (password !== confirmPassword) {\r\n setFormError(\"Passwords do not match\");\r\n return;\r\n }\r\n\r\n if (password.length < 8) {\r\n setFormError(\"Password must be at least 8 characters\");\r\n return;\r\n }\r\n\r\n try {\r\n await resetPassword({ token, password, confirmPassword });\r\n setSuccessMessage(\"Password has been reset successfully\");\r\n setPassword(\"\");\r\n setConfirmPassword(\"\");\r\n onSuccess?.();\r\n } catch (err) {\r\n const errorMsg =\r\n err instanceof Error ? err.message : \"Reset failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"RESET_PASSWORD_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n if (successMessage) {\r\n return (\r\n <div className={`auth-form-success ${className}`}>\r\n <p className=\"auth-form-success-message\">{successMessage}</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className={className}>\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"password\" className=\"auth-form-label\">\r\n {labels.password || \"New Password\"}\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder={placeholders.password || \"••••••••\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"confirmPassword\" className=\"auth-form-label\">\r\n {labels.confirmPassword || \"Confirm Password\"}\r\n </label>\r\n <input\r\n id=\"confirmPassword\"\r\n type=\"password\"\r\n value={confirmPassword}\r\n onChange={(e) => setConfirmPassword(e.target.value)}\r\n placeholder={placeholders.confirmPassword || \"••••••••\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n {error && <div className=\"auth-form-error\">{error}</div>}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className=\"auth-form-button auth-form-button-primary\"\r\n >\r\n {isLoading ? \"Loading...\" : submitButtonText}\r\n </button>\r\n </form>\r\n );\r\n};\r\n\r\nResetPasswordForm.displayName = \"ResetPasswordForm\";\r\n","import React, { useState, useEffect } from \"react\";\r\nimport { VerifyEmailFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\n\r\n/**\r\n * VerifyEmailForm Component\r\n * A ready-to-use email verification form with customizable styling and callbacks\r\n */\r\nexport const VerifyEmailForm: React.FC<VerifyEmailFormProps> = ({\r\n token: initialToken,\r\n email: initialEmail,\r\n className = \"\",\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Verify Email\",\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const {\r\n verifyEmail,\r\n isLoading: authLoading,\r\n error: authError,\r\n } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [email, setEmail] = useState(initialEmail || \"\");\r\n const [token, setToken] = useState(initialToken || \"\");\r\n const [successMessage, setSuccessMessage] = useState<string>(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n // Auto-submit if both token and email are provided\r\n useEffect(() => {\r\n if (token && email && !successMessage && !error) {\r\n handleSubmit({ preventDefault: () => {} } as React.FormEvent);\r\n }\r\n }, [token, email]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n setSuccessMessage(\"\");\r\n\r\n if (!token) {\r\n setFormError(\"Verification token is required\");\r\n return;\r\n }\r\n\r\n if (!email) {\r\n setFormError(\"Email is required\");\r\n return;\r\n }\r\n\r\n try {\r\n await verifyEmail({ token, email });\r\n setSuccessMessage(\"Email has been verified successfully\");\r\n onSuccess?.();\r\n } catch (err) {\r\n const errorMsg =\r\n err instanceof Error ? err.message : \"Verification failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"VERIFY_EMAIL_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n if (successMessage) {\r\n return (\r\n <div className={`auth-form-success ${className}`}>\r\n <p className=\"auth-form-success-message\">{successMessage}</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className={className}>\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"email\" className=\"auth-form-label\">\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"auth-form-group\">\r\n <label htmlFor=\"token\" className=\"auth-form-label\">\r\n {labels.token || \"Verification Code\"}\r\n </label>\r\n <input\r\n id=\"token\"\r\n type=\"text\"\r\n value={token}\r\n onChange={(e) => setToken(e.target.value)}\r\n placeholder={placeholders.token || \"Enter verification code\"}\r\n disabled={isLoading}\r\n className=\"auth-form-input\"\r\n required\r\n />\r\n </div>\r\n\r\n {error && <div className=\"auth-form-error\">{error}</div>}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className=\"auth-form-button auth-form-button-primary\"\r\n >\r\n {isLoading ? \"Loading...\" : submitButtonText}\r\n </button>\r\n </form>\r\n );\r\n};\r\n\r\nVerifyEmailForm.displayName = \"VerifyEmailForm\";\r\n","import React from \"react\";\r\nimport { Navigate } from \"react-router-dom\";\r\nimport { ProtectedRouteProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\n\r\n/**\r\n * ProtectedRoute Component\r\n * Protects routes based on authentication status and optional role/permission checks\r\n * Compatible with React Router v6\r\n */\r\nexport const ProtectedRoute: React.FC<ProtectedRouteProps> = ({\r\n children,\r\n redirectTo = \"/login\",\r\n fallback,\r\n roles,\r\n permissions,\r\n}) => {\r\n const { isAuthenticated, isLoading, user } = useAuth();\r\n\r\n // Show fallback while loading\r\n if (isLoading) {\r\n return fallback || <div className=\"auth-loading\">Loading...</div>;\r\n }\r\n\r\n // Redirect to login if not authenticated\r\n if (!isAuthenticated) {\r\n return <Navigate to={redirectTo} replace />;\r\n }\r\n\r\n // Check roles\r\n if (roles && roles.length > 0) {\r\n const hasRole = user?.roles?.some((role) => roles.includes(role));\r\n if (!hasRole) {\r\n return (\r\n <div className=\"auth-forbidden\">\r\n <p>You do not have permission to access this page.</p>\r\n </div>\r\n );\r\n }\r\n }\r\n\r\n // Check permissions\r\n if (permissions && permissions.length > 0) {\r\n const hasPermission = user?.permissions?.some((permission) =>\r\n permissions.includes(permission)\r\n );\r\n if (!hasPermission) {\r\n return (\r\n <div className=\"auth-forbidden\">\r\n <p>You do not have permission to access this page.</p>\r\n </div>\r\n );\r\n }\r\n }\r\n\r\n return <>{children}</>;\r\n};\r\n\r\nProtectedRoute.displayName = \"ProtectedRoute\";\r\n"],"names":["createContext","useReducer","useCallback","useEffect","jsx","useContext","useState","jsxs","Navigate"],"mappings":";;;;;AAOO,MAAM,cAAcA,MAAAA;AAAAA,EACzB;AACF;AAEA,YAAY,cAAc;ACNnB,SAAS,eAAe,OAA2B;AAExD,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO;AAAA,EACT;AAGA,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,MAAM;AAAA,MACf,YAAY;AAAA,IAAA;AAAA,EAEhB;AAGA,MACE,OAAO,UAAU,YACjB,UAAU,QACV,YAAY,SACZ,gBAAgB,OAChB;AACA,UAAM,aAAa;AACnB,WAAO;AAAA,MACL,MAAM,QAAQ,WAAW,MAAM;AAAA,MAC/B,SAAS,WAAW,cAAc;AAAA,MAClC,YAAY,WAAW;AAAA,IAAA;AAAA,EAE3B;AAGA,MACE,OAAO,UAAU,YACjB,UAAU,QACV,WAAW,SACX,OAAO,MAAM,UAAU,UACvB;AACA,UAAM,WAAW,MAAM;AACvB,WAAO;AAAA,MACL,MAAO,SAAS,QAAmB;AAAA,MACnC,SAAU,SAAS,WAAsB;AAAA,MACzC,YAAa,SAAS,cAAyB;AAAA,MAC/C,SAAS,SAAS;AAAA,IAAA;AAAA,EAEtB;AAGA,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,OAAO;AACrE,UAAM,WAAW;AACjB,WAAO;AAAA,MACL,MAAO,SAAS,QAAmB;AAAA,MACnC,SACE,OAAO,SAAS,YAAY,WACxB,SAAS,UACT;AAAA,IAAA;AAAA,EAEV;AAGA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,EAEb;AAGA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAEb;AAKA,SAAS,YAAY,OAAoC;AACvD,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,aAAa,SACb,OAAQ,MAAoB,SAAS,YACrC,OAAQ,MAAoB,YAAY;AAE5C;AC/EA,MAAM,oBAAmC;AAAA,EACvC,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,aAAa;AACf;AAKA,MAAM,iBAAiC,OAAO,KAAK,YAAY;AAC7D,QAAM,WAAW,MAAM,MAAM,KAAK,OAAO;AACzC,SAAO;AACT;AAKO,SAAS,iBAAiB,SAA2B,IAAI;AAC9D,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,YAAY,CAAA;AAAA,IACZ,UAAU,CAAA;AAAA,IACV,cAAc;AAAA,IACd,UAAU;AAAA,EAAA,IACR;AAEJ,QAAM,iBAAiB,EAAE,GAAG,mBAAmB,GAAG,UAAA;AAKlD,iBAAe,QACb,QACA,UACA,MACY;AACZ,UAAM,MAAM,GAAG,OAAO,GAAG,QAAQ;AACjC,UAAM,UAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MAAA;AAAA,IACL;AAGF,QAAI,MAAM;AACR,cAAQ,OAAO,KAAK,UAAU,IAAI;AAAA,IACpC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,QAAQ,KAAK,OAAO;AAE3C,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,YAAqB;AACzB,YAAI;AACF,sBAAY,MAAM,SAAS,KAAA;AAAA,QAC7B,QAAQ;AACN,sBAAY;AAAA,YACV,OAAO;AAAA,cACL,SAAS,SAAS;AAAA,cAClB,YAAY,SAAS;AAAA,YAAA;AAAA,UACvB;AAAA,QAEJ;AACA,cAAM;AAAA,MACR;AAEA,YAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AACvD,UAAI,eAAe,YAAY,SAAS,kBAAkB,GAAG;AAC3D,eAAO,MAAM,SAAS,KAAA;AAAA,MACxB;AAEA,aAAO,CAAA;AAAA,IACT,SAAS,OAAO;AACd,YAAM,eAAe,KAAK;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,MAAM,MAAM,OAAe,UAAkB,YAAsB;AACjE,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,QACf,EAAE,OAAO,UAAU,WAAA;AAAA,MAAW;AAEhC,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,SAAS,SAAkC;AAC/C,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,QACf;AAAA,MAAA;AAEF,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,SAAS;AACb,YAAM,QAAQ,QAAQ,eAAe,MAAO;AAAA,IAC9C;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,KAAK;AACT,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,MAAA;AAEjB,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,UAAU;AACd,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,MAAA;AAEjB,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,eAAe,OAAe;AAClC,YAAM,QAAQ,QAAQ,eAAe,gBAAiB,EAAE,OAAO;AAAA,IACjE;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,cACJ,OACA,UACA,iBACA;AACA,YAAM,QAAQ,QAAQ,eAAe,eAAgB;AAAA,QACnD;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,YAAY,OAAe,OAAgB;AAC/C,YAAM,QAAQ,QAAQ,eAAe,aAAc,EAAE,OAAO,OAAO;AAAA,IACrE;AAAA;AAAA;AAAA;AAAA,IAKA,WAAW,YAAoC;AAC7C,aAAO,OAAO,SAAS,UAAU;AAAA,IACnC;AAAA;AAAA;AAAA;AAAA,IAKA,eAAe;AACb,aAAO;AAAA,IACT;AAAA,EAAA;AAEJ;AC3JA,MAAM,eAA0B;AAAA,EAC9B,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,OAAO;AACT;AAKA,SAAS,YAAY,OAAkB,QAA+B;AACpE,UAAQ,OAAO,MAAA;AAAA,IACb,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,WAAW,OAAO,QAAA;AAAA,IAEvC,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,OAAO,OAAO,SAAS,WAAW,MAAA;AAAA,IAEvD,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,MAAM,OAAO;AAAA,QACb,iBAAiB,OAAO,YAAY;AAAA,QACpC,OAAO;AAAA,QACP,WAAW;AAAA,MAAA;AAAA,IAGf,KAAK;AACH,aAAO;AAAA,IAET;AACE,aAAO;AAAA,EAAA;AAEb;AAMO,MAAM,eAA4C,CAAC;AAAA,EACxD;AAAA,EACA,UAAU;AAAA,EACV,YAAY,CAAA;AAAA,EACZ;AAAA,EACA,cAAc;AAAA,EACd,kBAAkB,IAAI,KAAK;AAAA;AAC7B,MAAM;AACJ,QAAM,CAAC,OAAO,QAAQ,IAAIC,MAAAA,WAAW,aAAa,YAAY;AAC9D,QAAM,YAAY,MAAM;AAAA,IACtB,iBAAiB;AAAA,MACf;AAAA,MACA;AAAA,MACA,aAAa;AAAA,IAAA,CACd;AAAA,EAAA;AAGH,QAAM,SAAS,UAAU;AAKzB,QAAM,cAAcC,MAAAA;AAAAA,IAClB,CAAC,UAAqB;AACpB,eAAS,EAAE,MAAM,aAAa,SAAS,OAAO;AAC9C,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,WAAW;AAAA,EAAA;AAMd,QAAM,iBAAiBA,MAAAA,YAAY,YAAY;AAC7C,aAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,GAAA;AAC9B,UAAI,SAAS,MAAM;AACjB,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AAAA,MACvD,OAAO;AACL,iBAAS,EAAE,MAAM,UAAU;AAAA,MAC7B;AAAA,IACF,SAAS,QAAQ;AAEf,eAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,IAClD;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAKX,QAAM,iBAAiBA,MAAAA,YAAY,YAAY;AAC7C,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,QAAA;AAC9B,UAAI,SAAS,MAAM;AACjB,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AAAA,MACvD;AAAA,IACF,SAAS,OAAO;AACd,YAAM,YAAY,eAAe,KAAK;AACtC,kBAAY,SAAS;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,QAAQ,WAAW,CAAC;AAKxB,QAAM,QAAQA,MAAAA;AAAAA,IACZ,OAAO,YAA6C;AAClD,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,WAAW,MAAM,OAAO,MAAM,QAAQ,OAAO,QAAQ,QAAQ;AACnE,YAAI,CAAC,SAAS,MAAM;AAClB,gBAAM,IAAI,MAAM,0BAA0B;AAAA,QAC5C;AACA,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AACrD,eAAO,SAAS;AAAA,MAClB,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,WAAWA,MAAAA;AAAAA,IACf,OAAO,YAAgD;AACrD,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,WAAW,MAAM,OAAO,SAAS,OAAO;AAC9C,YAAI,CAAC,SAAS,MAAM;AAClB,gBAAM,IAAI,MAAM,0BAA0B;AAAA,QAC5C;AACA,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AACrD,eAAO,SAAS;AAAA,MAClB,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,SAASA,MAAAA,YAAY,YAAY;AACrC,aAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,QAAI;AACF,YAAM,OAAO,OAAA;AAAA,IACf,SAAS,OAAO;AAEd,cAAQ,MAAM,iBAAiB,KAAK;AAAA,IACtC,UAAA;AACE,eAAS,EAAE,MAAM,UAAU;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAKX,QAAM,iBAAiBA,MAAAA;AAAAA,IACrB,OAAO,YAAmC;AACxC,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,OAAO,eAAe,QAAQ,KAAK;AACzC,iBAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,MAClD,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,gBAAgBA,MAAAA;AAAAA,IACpB,OAAO,YAAkC;AACvC,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,OAAO;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,QAAA;AAEV,iBAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,MAClD,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,cAAcA,MAAAA;AAAAA,IAClB,OAAO,YAAgC;AACrC,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,OAAO,YAAY,QAAQ,OAAO,QAAQ,KAAK;AACrD,iBAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,MAClD,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,UAAUA,kBAAY,CAAC,SAA0B;AACrD,aAAS,EAAE,MAAM,YAAY,SAAS,MAAM;AAAA,EAC9C,GAAG,CAAA,CAAE;AAKLC,QAAAA,UAAU,MAAM;AACd,mBAAA;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAKnBA,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,eAAe,CAAC,MAAM,iBAAiB;AAC1C;AAAA,IACF;AAEA,UAAM,WAAW,YAAY,MAAM;AACjC,qBAAA;AAAA,IACF,GAAG,eAAe;AAElB,WAAO,MAAM,cAAc,QAAQ;AAAA,EACrC,GAAG,CAAC,aAAa,MAAM,iBAAiB,gBAAgB,eAAe,CAAC;AAExE,QAAM,QAAQ;AAAA,IACZ,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,SACEC,2BAAAA,IAAC,YAAY,UAAZ,EAAqB,OAAe,SAAA,CAAS;AAElD;ACrSO,SAAS,UAA4B;AAC1C,QAAM,UAAUC,MAAAA,WAAW,WAAW;AAEtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AAEA,SAAO;AACT;ACRO,MAAM,YAAsC,CAAC;AAAA,EAClD,YAAY;AAAA,EACZ,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,OAAO,WAAW,aAAa,OAAO,UAAA,IAAc,QAAA;AAC5D,QAAM,CAAC,WAAW,YAAY,IAAIC,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,EAAE;AAC3C,QAAM,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAS,KAAK;AAElD,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AAEf,QAAI,CAAC,SAAS,CAAC,UAAU;AACvB,mBAAa,iCAAiC;AAC9C;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,MAAM,EAAE,OAAO,UAAU,YAAY;AACxD,kBAAY,IAAI;AAAA,IAClB,SAAS,KAAK;AACZ,YAAM,WAAW,eAAe,QAAQ,IAAI,UAAU;AACtD,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,SACEC,2BAAAA,KAAC,QAAA,EAAK,UAAU,cAAc,WAC5B,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,SAAQ,WAAU,mBAC9B,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,UACxC,aAAa,aAAa,SAAS;AAAA,UACnC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEAG,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,YAAW,WAAU,mBACjC,UAAA,OAAO,YAAY,WAAA,CACtB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,UAC3C,aAAa,aAAa,YAAY;AAAA,UACtC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEAG,2BAAAA,KAAC,OAAA,EAAI,WAAU,sCACb,UAAA;AAAA,MAAAH,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,SAAS;AAAA,UACT,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,OAAO;AAAA,UAC/C,UAAU;AAAA,UACV,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZA,2BAAAA,IAAC,WAAM,SAAQ,cAAa,WAAU,mBACnC,UAAA,OAAO,cAAc,cAAA,CACxB;AAAA,IAAA,GACF;AAAA,IAEC,SAASA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,OAAM;AAAA,IAElDA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,WAAU;AAAA,QAET,sBAAY,eAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9B,GACF;AAEJ;AAEA,UAAU,cAAc;ACpGjB,MAAM,eAA4C,CAAC;AAAA,EACxD,YAAY;AAAA,EACZ,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,UAAU,WAAW,aAAa,OAAO,UAAA,IAAc,QAAA;AAC/D,QAAM,CAAC,WAAW,YAAY,IAAIE,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,MAAM,OAAO,IAAIA,MAAAA,SAAS,EAAE;AACnC,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,EAAE;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,MAAAA,SAAS,EAAE;AAEzD,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AAEf,QAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,iBAAiB;AACpD,mBAAa,yBAAyB;AACtC;AAAA,IACF;AAEA,QAAI,aAAa,iBAAiB;AAChC,mBAAa,wBAAwB;AACrC;AAAA,IACF;AAEA,QAAI,SAAS,SAAS,GAAG;AACvB,mBAAa,wCAAwC;AACrD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,SAAS;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AACD,kBAAY,IAAI;AAAA,IAClB,SAAS,KAAK;AACZ,YAAM,WAAW,eAAe,QAAQ,IAAI,UAAU;AACtD,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,SACEC,2BAAAA,KAAC,QAAA,EAAK,UAAU,cAAc,WAC5B,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,QAAO,WAAU,mBAC7B,UAAA,OAAO,QAAQ,YAAA,CAClB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,QAAQ,EAAE,OAAO,KAAK;AAAA,UACvC,aAAa,aAAa,QAAQ;AAAA,UAClC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEAG,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,SAAQ,WAAU,mBAC9B,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,UACxC,aAAa,aAAa,SAAS;AAAA,UACnC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEAG,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,YAAW,WAAU,mBACjC,UAAA,OAAO,YAAY,WAAA,CACtB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,UAC3C,aAAa,aAAa,YAAY;AAAA,UACtC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEAG,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,mBAAkB,WAAU,mBACxC,UAAA,OAAO,mBAAmB,mBAAA,CAC7B;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,mBAAmB,EAAE,OAAO,KAAK;AAAA,UAClD,aAAa,aAAa,mBAAmB;AAAA,UAC7C,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEC,SAASA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,OAAM;AAAA,IAElDA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,WAAU;AAAA,QAET,sBAAY,eAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9B,GACF;AAEJ;AAEA,aAAa,cAAc;ACtIpB,MAAM,qBAAwD,CAAC;AAAA,EACpE,YAAY;AAAA,EACZ,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,MAAM;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,EAAA,IACL,QAAA;AACJ,QAAM,CAAC,WAAW,YAAY,IAAIE,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,EAAE;AACrC,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,MAAAA,SAAiB,EAAE;AAE/D,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AACf,sBAAkB,EAAE;AAEpB,QAAI,CAAC,OAAO;AACV,mBAAa,mBAAmB;AAChC;AAAA,IACF;AAEA,QAAI;AACF,YAAM,eAAe,EAAE,OAAO;AAC9B,wBAAkB,iDAAiD;AACnE,eAAS,EAAE;AACX,kBAAA;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,WACJ,eAAe,QAAQ,IAAI,UAAU;AACvC,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,WACEF,2BAAAA,IAAC,OAAA,EAAI,WAAW,qBAAqB,SAAS,IAC5C,UAAAA,2BAAAA,IAAC,KAAA,EAAE,WAAU,6BAA6B,UAAA,eAAA,CAAe,GAC3D;AAAA,EAEJ;AAEA,SACEG,2BAAAA,KAAC,QAAA,EAAK,UAAU,cAAc,WAC5B,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,SAAQ,WAAU,mBAC9B,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,UACxC,aAAa,aAAa,SAAS;AAAA,UACnC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEC,SAASA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,OAAM;AAAA,IAElDA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,WAAU;AAAA,QAET,sBAAY,eAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9B,GACF;AAEJ;AAEA,mBAAmB,cAAc;ACrF1B,MAAM,oBAAsD,CAAC;AAAA,EAClE;AAAA,EACA,YAAY;AAAA,EACZ,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,MAAM;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,EAAA,IACL,QAAA;AACJ,QAAM,CAAC,WAAW,YAAY,IAAIE,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,EAAE;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,MAAAA,SAAS,EAAE;AACzD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,MAAAA,SAAiB,EAAE;AAE/D,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AACf,sBAAkB,EAAE;AAEpB,QAAI,CAAC,YAAY,CAAC,iBAAiB;AACjC,mBAAa,mCAAmC;AAChD;AAAA,IACF;AAEA,QAAI,aAAa,iBAAiB;AAChC,mBAAa,wBAAwB;AACrC;AAAA,IACF;AAEA,QAAI,SAAS,SAAS,GAAG;AACvB,mBAAa,wCAAwC;AACrD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,cAAc,EAAE,OAAO,UAAU,iBAAiB;AACxD,wBAAkB,sCAAsC;AACxD,kBAAY,EAAE;AACd,yBAAmB,EAAE;AACrB,kBAAA;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,WACJ,eAAe,QAAQ,IAAI,UAAU;AACvC,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,WACEF,2BAAAA,IAAC,OAAA,EAAI,WAAW,qBAAqB,SAAS,IAC5C,UAAAA,2BAAAA,IAAC,KAAA,EAAE,WAAU,6BAA6B,UAAA,eAAA,CAAe,GAC3D;AAAA,EAEJ;AAEA,SACEG,2BAAAA,KAAC,QAAA,EAAK,UAAU,cAAc,WAC5B,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,YAAW,WAAU,mBACjC,UAAA,OAAO,YAAY,eAAA,CACtB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,UAC3C,aAAa,aAAa,YAAY;AAAA,UACtC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEAG,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,mBAAkB,WAAU,mBACxC,UAAA,OAAO,mBAAmB,mBAAA,CAC7B;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,mBAAmB,EAAE,OAAO,KAAK;AAAA,UAClD,aAAa,aAAa,mBAAmB;AAAA,UAC7C,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEC,SAASA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,OAAM;AAAA,IAElDA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,WAAU;AAAA,QAET,sBAAY,eAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9B,GACF;AAEJ;AAEA,kBAAkB,cAAc;AClHzB,MAAM,kBAAkD,CAAC;AAAA,EAC9D,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,MAAM;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,EAAA,IACL,QAAA;AACJ,QAAM,CAAC,WAAW,YAAY,IAAIE,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,gBAAgB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,gBAAgB,EAAE;AACrD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,MAAAA,SAAiB,EAAE;AAE/D,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAGtCH,QAAAA,UAAU,MAAM;AACd,QAAI,SAAS,SAAS,CAAC,kBAAkB,CAAC,OAAO;AAC/C,mBAAa,EAAE,gBAAgB,MAAM;AAAA,MAAC,GAAsB;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,OAAO,KAAK,CAAC;AAEjB,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AACf,sBAAkB,EAAE;AAEpB,QAAI,CAAC,OAAO;AACV,mBAAa,gCAAgC;AAC7C;AAAA,IACF;AAEA,QAAI,CAAC,OAAO;AACV,mBAAa,mBAAmB;AAChC;AAAA,IACF;AAEA,QAAI;AACF,YAAM,YAAY,EAAE,OAAO,OAAO;AAClC,wBAAkB,sCAAsC;AACxD,kBAAA;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,WACJ,eAAe,QAAQ,IAAI,UAAU;AACvC,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,WACEC,2BAAAA,IAAC,OAAA,EAAI,WAAW,qBAAqB,SAAS,IAC5C,UAAAA,2BAAAA,IAAC,KAAA,EAAE,WAAU,6BAA6B,UAAA,eAAA,CAAe,GAC3D;AAAA,EAEJ;AAEA,SACEG,2BAAAA,KAAC,QAAA,EAAK,UAAU,cAAc,WAC5B,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,SAAQ,WAAU,mBAC9B,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,UACxC,aAAa,aAAa,SAAS;AAAA,UACnC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEAG,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAAH,2BAAAA,IAAC,WAAM,SAAQ,SAAQ,WAAU,mBAC9B,UAAA,OAAO,SAAS,oBAAA,CACnB;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,UACxC,aAAa,aAAa,SAAS;AAAA,UACnC,UAAU;AAAA,UACV,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACV,GACF;AAAA,IAEC,SAASA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,OAAM;AAAA,IAElDA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,WAAU;AAAA,QAET,sBAAY,eAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9B,GACF;AAEJ;AAEA,gBAAgB,cAAc;ACjHvB,MAAM,iBAAgD,CAAC;AAAA,EAC5D;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,iBAAiB,WAAW,KAAA,IAAS,QAAA;AAG7C,MAAI,WAAW;AACb,WAAO,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAU,gBAAe,UAAA,cAAU;AAAA,EAC7D;AAGA,MAAI,CAAC,iBAAiB;AACpB,WAAOA,2BAAAA,IAACI,eAAAA,UAAA,EAAS,IAAI,YAAY,SAAO,MAAC;AAAA,EAC3C;AAGA,MAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,UAAM,UAAU,MAAM,OAAO,KAAK,CAAC,SAAS,MAAM,SAAS,IAAI,CAAC;AAChE,QAAI,CAAC,SAAS;AACZ,4CACG,OAAA,EAAI,WAAU,kBACb,UAAAJ,2BAAAA,IAAC,KAAA,EAAE,6DAA+C,EAAA,CACpD;AAAA,IAEJ;AAAA,EACF;AAGA,MAAI,eAAe,YAAY,SAAS,GAAG;AACzC,UAAM,gBAAgB,MAAM,aAAa;AAAA,MAAK,CAAC,eAC7C,YAAY,SAAS,UAAU;AAAA,IAAA;AAEjC,QAAI,CAAC,eAAe;AAClB,4CACG,OAAA,EAAI,WAAU,kBACb,UAAAA,2BAAAA,IAAC,KAAA,EAAE,6DAA+C,EAAA,CACpD;AAAA,IAEJ;AAAA,EACF;AAEA,+DAAU,UAAS;AACrB;AAEA,eAAe,cAAc;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/context/AuthContext.ts","../src/utils/normalizeError.ts","../src/services/createAuthClient.ts","../src/context/AuthProvider.tsx","../src/hooks/useAuth.ts","../src/utils/cn.ts","../src/components/LoginForm.tsx","../src/components/RegisterForm.tsx","../src/components/ForgotPasswordForm.tsx","../src/components/ResetPasswordForm.tsx","../src/components/VerifyEmailForm.tsx","../src/components/ProtectedRoute.tsx"],"sourcesContent":["import { createContext } from \"react\";\r\nimport { AuthContextValue } from \"../types\";\r\n\r\n/**\r\n * Auth Context\r\n * Provides authentication state and methods to the application\r\n */\r\nexport const AuthContext = createContext<AuthContextValue | undefined>(\r\n undefined\r\n);\r\n\r\nAuthContext.displayName = \"AuthContext\";\r\n","import { AuthError } from \"../types\";\r\n\r\n/**\r\n * Normalizes various error types into a consistent AuthError format\r\n */\r\nexport function normalizeError(error: unknown): AuthError {\r\n // Handle AuthError objects\r\n if (isAuthError(error)) {\r\n return error;\r\n }\r\n\r\n // Handle standard Error objects\r\n if (error instanceof Error) {\r\n return {\r\n code: \"ERROR\",\r\n message: error.message,\r\n statusCode: undefined,\r\n };\r\n }\r\n\r\n // Handle fetch errors with response\r\n if (\r\n typeof error === \"object\" &&\r\n error !== null &&\r\n \"status\" in error &&\r\n \"statusText\" in error\r\n ) {\r\n const fetchError = error as { status: number; statusText: string };\r\n return {\r\n code: `HTTP_${fetchError.status}`,\r\n message: fetchError.statusText || \"Request failed\",\r\n statusCode: fetchError.status,\r\n };\r\n }\r\n\r\n // Handle JSON API error response\r\n if (\r\n typeof error === \"object\" &&\r\n error !== null &&\r\n \"error\" in error &&\r\n typeof error.error === \"object\"\r\n ) {\r\n const apiError = error.error as Record<string, unknown>;\r\n return {\r\n code: (apiError.code as string) || \"API_ERROR\",\r\n message: (apiError.message as string) || \"An error occurred\",\r\n statusCode: (apiError.statusCode as number) || undefined,\r\n details: apiError.details as Record<string, unknown>,\r\n };\r\n }\r\n\r\n // Handle plain objects with message property\r\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\r\n const objError = error as { message: unknown; code?: unknown };\r\n return {\r\n code: (objError.code as string) || \"ERROR\",\r\n message:\r\n typeof objError.message === \"string\"\r\n ? objError.message\r\n : \"An unknown error occurred\",\r\n };\r\n }\r\n\r\n // Handle strings\r\n if (typeof error === \"string\") {\r\n return {\r\n code: \"ERROR\",\r\n message: error,\r\n };\r\n }\r\n\r\n // Fallback\r\n return {\r\n code: \"UNKNOWN_ERROR\",\r\n message: \"An unknown error occurred\",\r\n };\r\n}\r\n\r\n/**\r\n * Type guard to check if an object is an AuthError\r\n */\r\nfunction isAuthError(error: unknown): error is AuthError {\r\n return (\r\n typeof error === \"object\" &&\r\n error !== null &&\r\n \"code\" in error &&\r\n \"message\" in error &&\r\n typeof (error as AuthError).code === \"string\" &&\r\n typeof (error as AuthError).message === \"string\"\r\n );\r\n}\r\n","import {\r\n AuthClientConfig,\r\n AuthEndpoints,\r\n RequestAdapter,\r\n AuthResponse,\r\n} from \"../types\";\r\nimport { normalizeError } from \"../utils/normalizeError\";\r\n\r\n/**\r\n * Default endpoints\r\n */\r\nconst DEFAULT_ENDPOINTS: AuthEndpoints = {\r\n login: \"/auth/login\",\r\n register: \"/auth/register\",\r\n logout: \"/auth/logout\",\r\n me: \"/auth/me\",\r\n refresh: \"/auth/refresh\",\r\n forgotPassword: \"/auth/forgot-password\",\r\n resetPassword: \"/auth/reset-password\",\r\n verifyEmail: \"/auth/verify-email\",\r\n};\r\n\r\n/**\r\n * Default request adapter using fetch\r\n */\r\nconst defaultAdapter: RequestAdapter = async (url, options) => {\r\n const response = await fetch(url, options);\r\n return response;\r\n};\r\n\r\n/**\r\n * Creates an authenticated API client\r\n */\r\nexport function createAuthClient(config: AuthClientConfig = {}) {\r\n const {\r\n baseURL = \"\",\r\n endpoints = {},\r\n headers = {},\r\n credentials = \"include\",\r\n adapter = defaultAdapter,\r\n } = config;\r\n\r\n const finalEndpoints = { ...DEFAULT_ENDPOINTS, ...endpoints };\r\n\r\n /**\r\n * Makes an authenticated request\r\n */\r\n async function request<T = unknown>(\r\n method: string,\r\n endpoint: string,\r\n data?: Record<string, unknown>\r\n ): Promise<T> {\r\n const url = `${baseURL}${endpoint}`;\r\n const options: RequestInit = {\r\n method,\r\n credentials,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...headers,\r\n },\r\n };\r\n\r\n if (data) {\r\n options.body = JSON.stringify(data);\r\n }\r\n\r\n try {\r\n const response = await adapter(url, options);\r\n\r\n if (!response.ok) {\r\n let errorData: unknown = null;\r\n try {\r\n errorData = await response.json();\r\n } catch {\r\n errorData = {\r\n error: {\r\n message: response.statusText,\r\n statusCode: response.status,\r\n },\r\n };\r\n }\r\n throw errorData;\r\n }\r\n\r\n const contentType = response.headers.get(\"content-type\");\r\n if (contentType && contentType.includes(\"application/json\")) {\r\n return await response.json();\r\n }\r\n\r\n return {} as T;\r\n } catch (error) {\r\n throw normalizeError(error);\r\n }\r\n }\r\n\r\n return {\r\n /**\r\n * Login with email and password\r\n */\r\n async login(email: string, password: string, rememberMe?: boolean) {\r\n const response = await request<AuthResponse>(\r\n \"POST\",\r\n finalEndpoints.login!,\r\n { email, password, rememberMe }\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Register a new account\r\n */\r\n async register(payload: Record<string, unknown>) {\r\n const response = await request<AuthResponse>(\r\n \"POST\",\r\n finalEndpoints.register!,\r\n payload\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Logout the user\r\n */\r\n async logout() {\r\n await request(\"POST\", finalEndpoints.logout!);\r\n },\r\n\r\n /**\r\n * Get current user\r\n */\r\n async me() {\r\n const response = await request<AuthResponse>(\r\n \"GET\",\r\n finalEndpoints.me!\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Refresh the authentication session\r\n */\r\n async refresh() {\r\n const response = await request<AuthResponse>(\r\n \"POST\",\r\n finalEndpoints.refresh!\r\n );\r\n return response;\r\n },\r\n\r\n /**\r\n * Request a password reset\r\n */\r\n async forgotPassword(email: string) {\r\n await request(\"POST\", finalEndpoints.forgotPassword!, { email });\r\n },\r\n\r\n /**\r\n * Reset password with token\r\n */\r\n async resetPassword(\r\n token: string,\r\n password: string,\r\n confirmPassword?: string\r\n ) {\r\n await request(\"POST\", finalEndpoints.resetPassword!, {\r\n token,\r\n password,\r\n confirmPassword,\r\n });\r\n },\r\n\r\n /**\r\n * Verify email with token\r\n */\r\n async verifyEmail(token: string, email?: string) {\r\n await request(\"POST\", finalEndpoints.verifyEmail!, { token, email });\r\n },\r\n\r\n /**\r\n * Set custom headers for subsequent requests\r\n */\r\n setHeaders(newHeaders: Record<string, string>) {\r\n Object.assign(headers, newHeaders);\r\n },\r\n\r\n /**\r\n * Get current endpoints configuration\r\n */\r\n getEndpoints() {\r\n return finalEndpoints;\r\n },\r\n };\r\n}\r\n\r\nexport type AuthClient = ReturnType<typeof createAuthClient>;\r\n","import React, { useEffect, useReducer, useCallback } from \"react\";\r\nimport {\r\n AuthProviderProps,\r\n AuthUser,\r\n AuthError,\r\n LoginPayload,\r\n RegisterPayload,\r\n ForgotPasswordPayload,\r\n ResetPasswordPayload,\r\n VerifyEmailPayload,\r\n} from \"../types\";\r\nimport { AuthContext } from \"./AuthContext\";\r\nimport { createAuthClient } from \"../services/createAuthClient\";\r\nimport { normalizeError } from \"../utils/normalizeError\";\r\n\r\n/**\r\n * Auth state\r\n */\r\ninterface AuthState {\r\n user: AuthUser | null;\r\n isAuthenticated: boolean;\r\n isLoading: boolean;\r\n error: AuthError | null;\r\n}\r\n\r\n/**\r\n * Auth state actions\r\n */\r\ntype AuthAction =\r\n | { type: \"SET_LOADING\"; payload: boolean }\r\n | { type: \"SET_ERROR\"; payload: AuthError | null }\r\n | { type: \"SET_USER\"; payload: AuthUser | null }\r\n | { type: \"LOGOUT\" };\r\n\r\n/**\r\n * Initial state\r\n */\r\nconst initialState: AuthState = {\r\n user: null,\r\n isAuthenticated: false,\r\n isLoading: false,\r\n error: null,\r\n};\r\n\r\n/**\r\n * Auth reducer\r\n */\r\nfunction authReducer(state: AuthState, action: AuthAction): AuthState {\r\n switch (action.type) {\r\n case \"SET_LOADING\":\r\n return { ...state, isLoading: action.payload };\r\n\r\n case \"SET_ERROR\":\r\n return { ...state, error: action.payload, isLoading: false };\r\n\r\n case \"SET_USER\":\r\n return {\r\n ...state,\r\n user: action.payload,\r\n isAuthenticated: action.payload !== null,\r\n error: null,\r\n isLoading: false,\r\n };\r\n\r\n case \"LOGOUT\":\r\n return initialState;\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n\r\n/**\r\n * AuthProvider component\r\n * Provides authentication state and methods to the entire application\r\n */\r\nexport const AuthProvider: React.FC<AuthProviderProps> = ({\r\n children,\r\n baseURL = \"\",\r\n endpoints = {},\r\n onAuthError,\r\n autoRefresh = true,\r\n refreshInterval = 5 * 60 * 1000, // 5 minutes\r\n}) => {\r\n const [state, dispatch] = useReducer(authReducer, initialState);\r\n const clientRef = React.useRef(\r\n createAuthClient({\r\n baseURL,\r\n endpoints,\r\n credentials: \"include\",\r\n })\r\n );\r\n\r\n const client = clientRef.current;\r\n\r\n /**\r\n * Handle auth error\r\n */\r\n const handleError = useCallback(\r\n (error: AuthError) => {\r\n dispatch({ type: \"SET_ERROR\", payload: error });\r\n onAuthError?.(error);\r\n },\r\n [onAuthError]\r\n );\r\n\r\n /**\r\n * Restore session on mount\r\n */\r\n const restoreSession = useCallback(async () => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n const response = await client.me();\r\n if (response.user) {\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n } else {\r\n dispatch({ type: \"LOGOUT\" });\r\n }\r\n } catch (_error) {\r\n // Session restore failure is not always an error state\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n }\r\n }, [client]);\r\n\r\n /**\r\n * Refresh session\r\n */\r\n const refreshSession = useCallback(async () => {\r\n try {\r\n const response = await client.refresh();\r\n if (response.user) {\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n }\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n }\r\n }, [client, handleError]);\r\n\r\n /**\r\n * Login\r\n */\r\n const login = useCallback(\r\n async (payload: LoginPayload): Promise<AuthUser> => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n const response = await client.login(payload.email, payload.password);\r\n if (!response.user) {\r\n throw new Error(\"No user data in response\");\r\n }\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n return response.user;\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Register\r\n */\r\n const register = useCallback(\r\n async (payload: RegisterPayload): Promise<AuthUser> => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n const response = await client.register(payload);\r\n if (!response.user) {\r\n throw new Error(\"No user data in response\");\r\n }\r\n dispatch({ type: \"SET_USER\", payload: response.user });\r\n return response.user;\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Logout\r\n */\r\n const logout = useCallback(async () => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.logout();\r\n } catch (error) {\r\n // Log but don't throw on logout error\r\n console.error(\"Logout error:\", error);\r\n } finally {\r\n dispatch({ type: \"LOGOUT\" });\r\n }\r\n }, [client]);\r\n\r\n /**\r\n * Forgot password\r\n */\r\n const forgotPassword = useCallback(\r\n async (payload: ForgotPasswordPayload) => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.forgotPassword(payload.email);\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Reset password\r\n */\r\n const resetPassword = useCallback(\r\n async (payload: ResetPasswordPayload) => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.resetPassword(\r\n payload.token,\r\n payload.password,\r\n payload.confirmPassword\r\n );\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Verify email\r\n */\r\n const verifyEmail = useCallback(\r\n async (payload: VerifyEmailPayload) => {\r\n dispatch({ type: \"SET_LOADING\", payload: true });\r\n try {\r\n await client.verifyEmail(payload.token, payload.email);\r\n dispatch({ type: \"SET_LOADING\", payload: false });\r\n } catch (error) {\r\n const authError = normalizeError(error);\r\n handleError(authError);\r\n throw authError;\r\n }\r\n },\r\n [client, handleError]\r\n );\r\n\r\n /**\r\n * Set user\r\n */\r\n const setUser = useCallback((user: AuthUser | null) => {\r\n dispatch({ type: \"SET_USER\", payload: user });\r\n }, []);\r\n\r\n /**\r\n * Effect: Restore session on mount\r\n */\r\n useEffect(() => {\r\n restoreSession();\r\n }, [restoreSession]);\r\n\r\n /**\r\n * Effect: Auto-refresh session\r\n */\r\n useEffect(() => {\r\n if (!autoRefresh || !state.isAuthenticated) {\r\n return;\r\n }\r\n\r\n const interval = setInterval(() => {\r\n refreshSession();\r\n }, refreshInterval);\r\n\r\n return () => clearInterval(interval);\r\n }, [autoRefresh, state.isAuthenticated, refreshSession, refreshInterval]);\r\n\r\n const value = {\r\n ...state,\r\n login,\r\n register,\r\n logout,\r\n forgotPassword,\r\n resetPassword,\r\n verifyEmail,\r\n refreshSession,\r\n restoreSession,\r\n setUser,\r\n };\r\n\r\n return (\r\n <AuthContext.Provider value={value}>{children}</AuthContext.Provider>\r\n );\r\n};\r\n","import { useContext } from \"react\";\r\nimport { AuthContext } from \"../context/AuthContext\";\r\nimport { AuthContextValue } from \"../types\";\r\n\r\n/**\r\n * Hook to access auth context\r\n * Must be used within an AuthProvider\r\n */\r\nexport function useAuth(): AuthContextValue {\r\n const context = useContext(AuthContext);\r\n\r\n if (!context) {\r\n throw new Error(\"useAuth must be used within an AuthProvider\");\r\n }\r\n\r\n return context;\r\n}\r\n","/**\r\n * Utility to safely merge class names\r\n * Filters out falsy values and joins with space\r\n */\r\nexport function cn(...classes: Array<string | undefined | false | null>): string {\r\n return classes.filter(Boolean).join(\" \");\r\n}\r\n","import React, { useState } from \"react\";\r\nimport { LoginFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\nimport { cn } from \"../utils/cn\";\r\n\r\nconst DEFAULT_CLASSES = {\r\n form: \"space-y-5\",\r\n field: \"space-y-2\",\r\n label: \"block text-sm font-medium text-slate-700\",\r\n input:\r\n \"w-full rounded-xl border border-slate-300 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition placeholder:text-slate-400 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 disabled:cursor-not-allowed disabled:bg-slate-100\",\r\n button:\r\n \"w-full rounded-xl bg-blue-600 px-4 py-3 text-sm font-semibold text-white transition hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60\",\r\n error:\r\n \"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600\",\r\n title: \"text-2xl font-bold text-slate-900\",\r\n subtitle: \"mt-1 text-sm text-slate-500\",\r\n};\r\n\r\n/**\r\n * LoginForm Component\r\n * A ready-to-use login form with customizable Tailwind styling\r\n */\r\nexport const LoginForm: React.FC<LoginFormProps> = ({\r\n className,\r\n formClassName,\r\n fieldClassName,\r\n labelClassName,\r\n inputClassName,\r\n buttonClassName,\r\n errorClassName,\r\n titleClassName,\r\n subtitleClassName,\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Login\",\r\n loadingText = \"Signing in...\",\r\n title,\r\n subtitle,\r\n showTitle = !!title,\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const { login, isLoading: authLoading, error: authError } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [rememberMe, setRememberMe] = useState(false);\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n\r\n if (!email || !password) {\r\n setFormError(\"Email and password are required\");\r\n return;\r\n }\r\n\r\n try {\r\n const user = await login({ email, password, rememberMe });\r\n onSuccess?.(user);\r\n } catch (err) {\r\n const errorMsg = err instanceof Error ? err.message : \"Login failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"LOGIN_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className={cn(DEFAULT_CLASSES.form, formClassName)}>\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"email\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"password\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.password || \"Password\"}\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder={placeholders.password || \"••••••••\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"flex items-center\">\r\n <input\r\n id=\"rememberMe\"\r\n type=\"checkbox\"\r\n checked={rememberMe}\r\n onChange={(e) => setRememberMe(e.target.checked)}\r\n disabled={isLoading}\r\n className=\"h-4 w-4 rounded border-slate-300\"\r\n />\r\n <label\r\n htmlFor=\"rememberMe\"\r\n className=\"ml-2 text-sm text-slate-700\"\r\n >\r\n {labels.rememberMe || \"Remember me\"}\r\n </label>\r\n </div>\r\n\r\n {error && (\r\n <div className={cn(DEFAULT_CLASSES.error, errorClassName)}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.button, buttonClassName)}\r\n >\r\n {isLoading ? loadingText : submitButtonText}\r\n </button>\r\n </form>\r\n </div>\r\n );\r\n};\r\n\r\nLoginForm.displayName = \"LoginForm\";\r\n\r\n","import React, { useState } from \"react\";\r\nimport { RegisterFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\nimport { cn } from \"../utils/cn\";\r\n\r\nconst DEFAULT_CLASSES = {\r\n form: \"space-y-5\",\r\n field: \"space-y-2\",\r\n label: \"block text-sm font-medium text-slate-700\",\r\n input:\r\n \"w-full rounded-xl border border-slate-300 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition placeholder:text-slate-400 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 disabled:cursor-not-allowed disabled:bg-slate-100\",\r\n button:\r\n \"w-full rounded-xl bg-blue-600 px-4 py-3 text-sm font-semibold text-white transition hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60\",\r\n error:\r\n \"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600\",\r\n title: \"text-2xl font-bold text-slate-900\",\r\n subtitle: \"mt-1 text-sm text-slate-500\",\r\n};\r\n\r\n/**\r\n * RegisterForm Component\r\n * A ready-to-use registration form with customizable Tailwind styling\r\n */\r\nexport const RegisterForm: React.FC<RegisterFormProps> = ({\r\n className,\r\n formClassName,\r\n fieldClassName,\r\n labelClassName,\r\n inputClassName,\r\n buttonClassName,\r\n errorClassName,\r\n titleClassName,\r\n subtitleClassName,\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Register\",\r\n loadingText = \"Creating account...\",\r\n title,\r\n subtitle,\r\n showTitle = !!title,\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const { register, isLoading: authLoading, error: authError } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [name, setName] = useState(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [confirmPassword, setConfirmPassword] = useState(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n\r\n if (!name || !email || !password || !confirmPassword) {\r\n setFormError(\"All fields are required\");\r\n return;\r\n }\r\n\r\n if (password !== confirmPassword) {\r\n setFormError(\"Passwords do not match\");\r\n return;\r\n }\r\n\r\n if (password.length < 8) {\r\n setFormError(\"Password must be at least 8 characters\");\r\n return;\r\n }\r\n\r\n try {\r\n const user = await register({\r\n name,\r\n email,\r\n password,\r\n confirmPassword,\r\n });\r\n onSuccess?.(user);\r\n } catch (err) {\r\n const errorMsg = err instanceof Error ? err.message : \"Registration failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"REGISTER_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className={cn(DEFAULT_CLASSES.form, formClassName)}>\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"name\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.name || \"Full Name\"}\r\n </label>\r\n <input\r\n id=\"name\"\r\n type=\"text\"\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder={placeholders.name || \"John Doe\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"email\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"password\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.password || \"Password\"}\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder={placeholders.password || \"••••••••\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"confirmPassword\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.confirmPassword || \"Confirm Password\"}\r\n </label>\r\n <input\r\n id=\"confirmPassword\"\r\n type=\"password\"\r\n value={confirmPassword}\r\n onChange={(e) => setConfirmPassword(e.target.value)}\r\n placeholder={placeholders.confirmPassword || \"••••••••\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n {error && (\r\n <div className={cn(DEFAULT_CLASSES.error, errorClassName)}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.button, buttonClassName)}\r\n >\r\n {isLoading ? loadingText : submitButtonText}\r\n </button>\r\n </form>\r\n </div>\r\n );\r\n};\r\n\r\nRegisterForm.displayName = \"RegisterForm\";\r\n","import React, { useState } from \"react\";\r\nimport { ForgotPasswordFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\nimport { cn } from \"../utils/cn\";\r\n\r\nconst DEFAULT_CLASSES = {\r\n form: \"space-y-5\",\r\n field: \"space-y-2\",\r\n label: \"block text-sm font-medium text-slate-700\",\r\n input:\r\n \"w-full rounded-xl border border-slate-300 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition placeholder:text-slate-400 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 disabled:cursor-not-allowed disabled:bg-slate-100\",\r\n button:\r\n \"w-full rounded-xl bg-blue-600 px-4 py-3 text-sm font-semibold text-white transition hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60\",\r\n error:\r\n \"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600\",\r\n success:\r\n \"rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700\",\r\n title: \"text-2xl font-bold text-slate-900\",\r\n subtitle: \"mt-1 text-sm text-slate-500\",\r\n};\r\n\r\n/**\r\n * ForgotPasswordForm Component\r\n * A ready-to-use forgot password form with customizable Tailwind styling\r\n */\r\nexport const ForgotPasswordForm: React.FC<ForgotPasswordFormProps> = ({\r\n className,\r\n formClassName,\r\n fieldClassName,\r\n labelClassName,\r\n inputClassName,\r\n buttonClassName,\r\n errorClassName,\r\n successClassName,\r\n titleClassName,\r\n subtitleClassName,\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Send Reset Link\",\r\n loadingText = \"Sending...\",\r\n title,\r\n subtitle,\r\n showTitle = !!title,\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const {\r\n forgotPassword,\r\n isLoading: authLoading,\r\n error: authError,\r\n } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [successMessage, setSuccessMessage] = useState<string>(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n setSuccessMessage(\"\");\r\n\r\n if (!email) {\r\n setFormError(\"Email is required\");\r\n return;\r\n }\r\n\r\n try {\r\n await forgotPassword({ email });\r\n setSuccessMessage(\"Password reset link has been sent to your email\");\r\n setEmail(\"\");\r\n onSuccess?.();\r\n } catch (err) {\r\n const errorMsg =\r\n err instanceof Error ? err.message : \"Request failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"FORGOT_PASSWORD_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n if (successMessage) {\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n <div className={cn(DEFAULT_CLASSES.success, successClassName)}>\r\n <p>{successMessage}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className={cn(DEFAULT_CLASSES.form, formClassName)}>\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"email\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n {error && (\r\n <div className={cn(DEFAULT_CLASSES.error, errorClassName)}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.button, buttonClassName)}\r\n >\r\n {isLoading ? loadingText : submitButtonText}\r\n </button>\r\n </form>\r\n </div>\r\n );\r\n};\r\n\r\nForgotPasswordForm.displayName = \"ForgotPasswordForm\";\r\n","import React, { useState } from \"react\";\r\nimport { ResetPasswordFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\nimport { cn } from \"../utils/cn\";\r\n\r\nconst DEFAULT_CLASSES = {\r\n form: \"space-y-5\",\r\n field: \"space-y-2\",\r\n label: \"block text-sm font-medium text-slate-700\",\r\n input:\r\n \"w-full rounded-xl border border-slate-300 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition placeholder:text-slate-400 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 disabled:cursor-not-allowed disabled:bg-slate-100\",\r\n button:\r\n \"w-full rounded-xl bg-blue-600 px-4 py-3 text-sm font-semibold text-white transition hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60\",\r\n error:\r\n \"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600\",\r\n success:\r\n \"rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700\",\r\n title: \"text-2xl font-bold text-slate-900\",\r\n subtitle: \"mt-1 text-sm text-slate-500\",\r\n};\r\n\r\n/**\r\n * ResetPasswordForm Component\r\n * A ready-to-use password reset form with customizable Tailwind styling\r\n */\r\nexport const ResetPasswordForm: React.FC<ResetPasswordFormProps> = ({\r\n token,\r\n className,\r\n formClassName,\r\n fieldClassName,\r\n labelClassName,\r\n inputClassName,\r\n buttonClassName,\r\n errorClassName,\r\n successClassName,\r\n titleClassName,\r\n subtitleClassName,\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Reset Password\",\r\n loadingText = \"Updating...\",\r\n title,\r\n subtitle,\r\n showTitle = !!title,\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const {\r\n resetPassword,\r\n isLoading: authLoading,\r\n error: authError,\r\n } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [confirmPassword, setConfirmPassword] = useState(\"\");\r\n const [successMessage, setSuccessMessage] = useState<string>(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n setSuccessMessage(\"\");\r\n\r\n if (!password || !confirmPassword) {\r\n setFormError(\"Both password fields are required\");\r\n return;\r\n }\r\n\r\n if (password !== confirmPassword) {\r\n setFormError(\"Passwords do not match\");\r\n return;\r\n }\r\n\r\n if (password.length < 8) {\r\n setFormError(\"Password must be at least 8 characters\");\r\n return;\r\n }\r\n\r\n try {\r\n await resetPassword({ token, password, confirmPassword });\r\n setSuccessMessage(\"Password has been reset successfully\");\r\n setPassword(\"\");\r\n setConfirmPassword(\"\");\r\n onSuccess?.();\r\n } catch (err) {\r\n const errorMsg =\r\n err instanceof Error ? err.message : \"Reset failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"RESET_PASSWORD_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n if (successMessage) {\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n <div className={cn(DEFAULT_CLASSES.success, successClassName)}>\r\n <p>{successMessage}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className={cn(DEFAULT_CLASSES.form, formClassName)}>\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"password\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.password || \"New Password\"}\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder={placeholders.password || \"••••••••\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"confirmPassword\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.confirmPassword || \"Confirm Password\"}\r\n </label>\r\n <input\r\n id=\"confirmPassword\"\r\n type=\"password\"\r\n value={confirmPassword}\r\n onChange={(e) => setConfirmPassword(e.target.value)}\r\n placeholder={placeholders.confirmPassword || \"••••••••\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n {error && (\r\n <div className={cn(DEFAULT_CLASSES.error, errorClassName)}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.button, buttonClassName)}\r\n >\r\n {isLoading ? loadingText : submitButtonText}\r\n </button>\r\n </form>\r\n </div>\r\n );\r\n};\r\n\r\nResetPasswordForm.displayName = \"ResetPasswordForm\";\r\n","import React, { useState, useEffect } from \"react\";\r\nimport { VerifyEmailFormProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\nimport { cn } from \"../utils/cn\";\r\n\r\nconst DEFAULT_CLASSES = {\r\n form: \"space-y-5\",\r\n field: \"space-y-2\",\r\n label: \"block text-sm font-medium text-slate-700\",\r\n input:\r\n \"w-full rounded-xl border border-slate-300 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition placeholder:text-slate-400 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 disabled:cursor-not-allowed disabled:bg-slate-100\",\r\n button:\r\n \"w-full rounded-xl bg-blue-600 px-4 py-3 text-sm font-semibold text-white transition hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60\",\r\n error:\r\n \"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600\",\r\n success:\r\n \"rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700\",\r\n title: \"text-2xl font-bold text-slate-900\",\r\n subtitle: \"mt-1 text-sm text-slate-500\",\r\n};\r\n\r\n/**\r\n * VerifyEmailForm Component\r\n * A ready-to-use email verification form with customizable Tailwind styling\r\n */\r\nexport const VerifyEmailForm: React.FC<VerifyEmailFormProps> = ({\r\n token: initialToken,\r\n email: initialEmail,\r\n className,\r\n formClassName,\r\n fieldClassName,\r\n labelClassName,\r\n inputClassName,\r\n buttonClassName,\r\n errorClassName,\r\n successClassName,\r\n titleClassName,\r\n subtitleClassName,\r\n labels = {},\r\n placeholders = {},\r\n submitButtonText = \"Verify Email\",\r\n loadingText = \"Verifying...\",\r\n title,\r\n subtitle,\r\n showTitle = !!title,\r\n onSuccess,\r\n onError,\r\n}) => {\r\n const {\r\n verifyEmail,\r\n isLoading: authLoading,\r\n error: authError,\r\n } = useAuth();\r\n const [formError, setFormError] = useState<string>(\"\");\r\n const [email, setEmail] = useState(initialEmail || \"\");\r\n const [token, setToken] = useState(initialToken || \"\");\r\n const [successMessage, setSuccessMessage] = useState<string>(\"\");\r\n\r\n const isLoading = authLoading;\r\n const error = formError || authError?.message;\r\n\r\n // Auto-submit if both token and email are provided\r\n useEffect(() => {\r\n if (token && email && !successMessage && !error) {\r\n handleSubmit({ preventDefault: () => {} } as React.FormEvent);\r\n }\r\n }, [token, email]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setFormError(\"\");\r\n setSuccessMessage(\"\");\r\n\r\n if (!token) {\r\n setFormError(\"Verification token is required\");\r\n return;\r\n }\r\n\r\n if (!email) {\r\n setFormError(\"Email is required\");\r\n return;\r\n }\r\n\r\n try {\r\n await verifyEmail({ token, email });\r\n setSuccessMessage(\"Email has been verified successfully\");\r\n onSuccess?.();\r\n } catch (err) {\r\n const errorMsg =\r\n err instanceof Error ? err.message : \"Verification failed\";\r\n setFormError(errorMsg);\r\n onError?.({\r\n code: \"VERIFY_EMAIL_ERROR\",\r\n message: errorMsg,\r\n });\r\n }\r\n };\r\n\r\n if (successMessage) {\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n <div className={cn(DEFAULT_CLASSES.success, successClassName)}>\r\n <p>{successMessage}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className}>\r\n {showTitle && title && (\r\n <div className=\"mb-6\">\r\n <h1 className={cn(DEFAULT_CLASSES.title, titleClassName)}>\r\n {title}\r\n </h1>\r\n {subtitle && (\r\n <p className={cn(DEFAULT_CLASSES.subtitle, subtitleClassName)}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className={cn(DEFAULT_CLASSES.form, formClassName)}>\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"email\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.email || \"Email\"}\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder={placeholders.email || \"your@email.com\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n <div className={cn(DEFAULT_CLASSES.field, fieldClassName)}>\r\n <label htmlFor=\"token\" className={cn(DEFAULT_CLASSES.label, labelClassName)}>\r\n {labels.token || \"Verification Code\"}\r\n </label>\r\n <input\r\n id=\"token\"\r\n type=\"text\"\r\n value={token}\r\n onChange={(e) => setToken(e.target.value)}\r\n placeholder={placeholders.token || \"Enter verification code\"}\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.input, inputClassName)}\r\n required\r\n />\r\n </div>\r\n\r\n {error && (\r\n <div className={cn(DEFAULT_CLASSES.error, errorClassName)}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={isLoading}\r\n className={cn(DEFAULT_CLASSES.button, buttonClassName)}\r\n >\r\n {isLoading ? loadingText : submitButtonText}\r\n </button>\r\n </form>\r\n </div>\r\n );\r\n};\r\n\r\nVerifyEmailForm.displayName = \"VerifyEmailForm\";\r\n","import React from \"react\";\r\nimport { Navigate } from \"react-router-dom\";\r\nimport { ProtectedRouteProps } from \"../types\";\r\nimport { useAuth } from \"../hooks/useAuth\";\r\n\r\n/**\r\n * ProtectedRoute Component\r\n * Protects routes based on authentication status and optional role/permission checks\r\n * Compatible with React Router v6\r\n */\r\nexport const ProtectedRoute: React.FC<ProtectedRouteProps> = ({\r\n children,\r\n redirectTo = \"/login\",\r\n fallback,\r\n roles,\r\n permissions,\r\n}) => {\r\n const { isAuthenticated, isLoading, user } = useAuth();\r\n\r\n // Show fallback while loading\r\n if (isLoading) {\r\n return fallback || <div className=\"auth-loading\">Loading...</div>;\r\n }\r\n\r\n // Redirect to login if not authenticated\r\n if (!isAuthenticated) {\r\n return <Navigate to={redirectTo} replace />;\r\n }\r\n\r\n // Check roles\r\n if (roles && roles.length > 0) {\r\n const hasRole = user?.roles?.some((role) => roles.includes(role));\r\n if (!hasRole) {\r\n return (\r\n <div className=\"auth-forbidden\">\r\n <p>You do not have permission to access this page.</p>\r\n </div>\r\n );\r\n }\r\n }\r\n\r\n // Check permissions\r\n if (permissions && permissions.length > 0) {\r\n const hasPermission = user?.permissions?.some((permission) =>\r\n permissions.includes(permission)\r\n );\r\n if (!hasPermission) {\r\n return (\r\n <div className=\"auth-forbidden\">\r\n <p>You do not have permission to access this page.</p>\r\n </div>\r\n );\r\n }\r\n }\r\n\r\n return <>{children}</>;\r\n};\r\n\r\nProtectedRoute.displayName = \"ProtectedRoute\";\r\n"],"names":["createContext","useReducer","useCallback","useEffect","jsx","useContext","DEFAULT_CLASSES","useState","jsxs","Navigate"],"mappings":";;;;;AAOO,MAAM,cAAcA,MAAAA;AAAAA,EACzB;AACF;AAEA,YAAY,cAAc;ACNnB,SAAS,eAAe,OAA2B;AAExD,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO;AAAA,EACT;AAGA,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,MAAM;AAAA,MACf,YAAY;AAAA,IAAA;AAAA,EAEhB;AAGA,MACE,OAAO,UAAU,YACjB,UAAU,QACV,YAAY,SACZ,gBAAgB,OAChB;AACA,UAAM,aAAa;AACnB,WAAO;AAAA,MACL,MAAM,QAAQ,WAAW,MAAM;AAAA,MAC/B,SAAS,WAAW,cAAc;AAAA,MAClC,YAAY,WAAW;AAAA,IAAA;AAAA,EAE3B;AAGA,MACE,OAAO,UAAU,YACjB,UAAU,QACV,WAAW,SACX,OAAO,MAAM,UAAU,UACvB;AACA,UAAM,WAAW,MAAM;AACvB,WAAO;AAAA,MACL,MAAO,SAAS,QAAmB;AAAA,MACnC,SAAU,SAAS,WAAsB;AAAA,MACzC,YAAa,SAAS,cAAyB;AAAA,MAC/C,SAAS,SAAS;AAAA,IAAA;AAAA,EAEtB;AAGA,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,OAAO;AACrE,UAAM,WAAW;AACjB,WAAO;AAAA,MACL,MAAO,SAAS,QAAmB;AAAA,MACnC,SACE,OAAO,SAAS,YAAY,WACxB,SAAS,UACT;AAAA,IAAA;AAAA,EAEV;AAGA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,EAEb;AAGA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAEb;AAKA,SAAS,YAAY,OAAoC;AACvD,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,aAAa,SACb,OAAQ,MAAoB,SAAS,YACrC,OAAQ,MAAoB,YAAY;AAE5C;AC/EA,MAAM,oBAAmC;AAAA,EACvC,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,aAAa;AACf;AAKA,MAAM,iBAAiC,OAAO,KAAK,YAAY;AAC7D,QAAM,WAAW,MAAM,MAAM,KAAK,OAAO;AACzC,SAAO;AACT;AAKO,SAAS,iBAAiB,SAA2B,IAAI;AAC9D,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,YAAY,CAAA;AAAA,IACZ,UAAU,CAAA;AAAA,IACV,cAAc;AAAA,IACd,UAAU;AAAA,EAAA,IACR;AAEJ,QAAM,iBAAiB,EAAE,GAAG,mBAAmB,GAAG,UAAA;AAKlD,iBAAe,QACb,QACA,UACA,MACY;AACZ,UAAM,MAAM,GAAG,OAAO,GAAG,QAAQ;AACjC,UAAM,UAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MAAA;AAAA,IACL;AAGF,QAAI,MAAM;AACR,cAAQ,OAAO,KAAK,UAAU,IAAI;AAAA,IACpC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,QAAQ,KAAK,OAAO;AAE3C,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,YAAqB;AACzB,YAAI;AACF,sBAAY,MAAM,SAAS,KAAA;AAAA,QAC7B,QAAQ;AACN,sBAAY;AAAA,YACV,OAAO;AAAA,cACL,SAAS,SAAS;AAAA,cAClB,YAAY,SAAS;AAAA,YAAA;AAAA,UACvB;AAAA,QAEJ;AACA,cAAM;AAAA,MACR;AAEA,YAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AACvD,UAAI,eAAe,YAAY,SAAS,kBAAkB,GAAG;AAC3D,eAAO,MAAM,SAAS,KAAA;AAAA,MACxB;AAEA,aAAO,CAAA;AAAA,IACT,SAAS,OAAO;AACd,YAAM,eAAe,KAAK;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,MAAM,MAAM,OAAe,UAAkB,YAAsB;AACjE,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,QACf,EAAE,OAAO,UAAU,WAAA;AAAA,MAAW;AAEhC,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,SAAS,SAAkC;AAC/C,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,QACf;AAAA,MAAA;AAEF,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,SAAS;AACb,YAAM,QAAQ,QAAQ,eAAe,MAAO;AAAA,IAC9C;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,KAAK;AACT,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,MAAA;AAEjB,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,UAAU;AACd,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,eAAe;AAAA,MAAA;AAEjB,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,eAAe,OAAe;AAClC,YAAM,QAAQ,QAAQ,eAAe,gBAAiB,EAAE,OAAO;AAAA,IACjE;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,cACJ,OACA,UACA,iBACA;AACA,YAAM,QAAQ,QAAQ,eAAe,eAAgB;AAAA,QACnD;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,YAAY,OAAe,OAAgB;AAC/C,YAAM,QAAQ,QAAQ,eAAe,aAAc,EAAE,OAAO,OAAO;AAAA,IACrE;AAAA;AAAA;AAAA;AAAA,IAKA,WAAW,YAAoC;AAC7C,aAAO,OAAO,SAAS,UAAU;AAAA,IACnC;AAAA;AAAA;AAAA;AAAA,IAKA,eAAe;AACb,aAAO;AAAA,IACT;AAAA,EAAA;AAEJ;AC3JA,MAAM,eAA0B;AAAA,EAC9B,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,OAAO;AACT;AAKA,SAAS,YAAY,OAAkB,QAA+B;AACpE,UAAQ,OAAO,MAAA;AAAA,IACb,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,WAAW,OAAO,QAAA;AAAA,IAEvC,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,OAAO,OAAO,SAAS,WAAW,MAAA;AAAA,IAEvD,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,MAAM,OAAO;AAAA,QACb,iBAAiB,OAAO,YAAY;AAAA,QACpC,OAAO;AAAA,QACP,WAAW;AAAA,MAAA;AAAA,IAGf,KAAK;AACH,aAAO;AAAA,IAET;AACE,aAAO;AAAA,EAAA;AAEb;AAMO,MAAM,eAA4C,CAAC;AAAA,EACxD;AAAA,EACA,UAAU;AAAA,EACV,YAAY,CAAA;AAAA,EACZ;AAAA,EACA,cAAc;AAAA,EACd,kBAAkB,IAAI,KAAK;AAAA;AAC7B,MAAM;AACJ,QAAM,CAAC,OAAO,QAAQ,IAAIC,MAAAA,WAAW,aAAa,YAAY;AAC9D,QAAM,YAAY,MAAM;AAAA,IACtB,iBAAiB;AAAA,MACf;AAAA,MACA;AAAA,MACA,aAAa;AAAA,IAAA,CACd;AAAA,EAAA;AAGH,QAAM,SAAS,UAAU;AAKzB,QAAM,cAAcC,MAAAA;AAAAA,IAClB,CAAC,UAAqB;AACpB,eAAS,EAAE,MAAM,aAAa,SAAS,OAAO;AAC9C,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,WAAW;AAAA,EAAA;AAMd,QAAM,iBAAiBA,MAAAA,YAAY,YAAY;AAC7C,aAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,GAAA;AAC9B,UAAI,SAAS,MAAM;AACjB,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AAAA,MACvD,OAAO;AACL,iBAAS,EAAE,MAAM,UAAU;AAAA,MAC7B;AAAA,IACF,SAAS,QAAQ;AAEf,eAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,IAClD;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAKX,QAAM,iBAAiBA,MAAAA,YAAY,YAAY;AAC7C,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,QAAA;AAC9B,UAAI,SAAS,MAAM;AACjB,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AAAA,MACvD;AAAA,IACF,SAAS,OAAO;AACd,YAAM,YAAY,eAAe,KAAK;AACtC,kBAAY,SAAS;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,QAAQ,WAAW,CAAC;AAKxB,QAAM,QAAQA,MAAAA;AAAAA,IACZ,OAAO,YAA6C;AAClD,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,WAAW,MAAM,OAAO,MAAM,QAAQ,OAAO,QAAQ,QAAQ;AACnE,YAAI,CAAC,SAAS,MAAM;AAClB,gBAAM,IAAI,MAAM,0BAA0B;AAAA,QAC5C;AACA,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AACrD,eAAO,SAAS;AAAA,MAClB,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,WAAWA,MAAAA;AAAAA,IACf,OAAO,YAAgD;AACrD,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,WAAW,MAAM,OAAO,SAAS,OAAO;AAC9C,YAAI,CAAC,SAAS,MAAM;AAClB,gBAAM,IAAI,MAAM,0BAA0B;AAAA,QAC5C;AACA,iBAAS,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM;AACrD,eAAO,SAAS;AAAA,MAClB,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,SAASA,MAAAA,YAAY,YAAY;AACrC,aAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,QAAI;AACF,YAAM,OAAO,OAAA;AAAA,IACf,SAAS,OAAO;AAEd,cAAQ,MAAM,iBAAiB,KAAK;AAAA,IACtC,UAAA;AACE,eAAS,EAAE,MAAM,UAAU;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAKX,QAAM,iBAAiBA,MAAAA;AAAAA,IACrB,OAAO,YAAmC;AACxC,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,OAAO,eAAe,QAAQ,KAAK;AACzC,iBAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,MAClD,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,gBAAgBA,MAAAA;AAAAA,IACpB,OAAO,YAAkC;AACvC,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,OAAO;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,QAAA;AAEV,iBAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,MAClD,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,cAAcA,MAAAA;AAAAA,IAClB,OAAO,YAAgC;AACrC,eAAS,EAAE,MAAM,eAAe,SAAS,MAAM;AAC/C,UAAI;AACF,cAAM,OAAO,YAAY,QAAQ,OAAO,QAAQ,KAAK;AACrD,iBAAS,EAAE,MAAM,eAAe,SAAS,OAAO;AAAA,MAClD,SAAS,OAAO;AACd,cAAM,YAAY,eAAe,KAAK;AACtC,oBAAY,SAAS;AACrB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EAAA;AAMtB,QAAM,UAAUA,kBAAY,CAAC,SAA0B;AACrD,aAAS,EAAE,MAAM,YAAY,SAAS,MAAM;AAAA,EAC9C,GAAG,CAAA,CAAE;AAKLC,QAAAA,UAAU,MAAM;AACd,mBAAA;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAKnBA,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,eAAe,CAAC,MAAM,iBAAiB;AAC1C;AAAA,IACF;AAEA,UAAM,WAAW,YAAY,MAAM;AACjC,qBAAA;AAAA,IACF,GAAG,eAAe;AAElB,WAAO,MAAM,cAAc,QAAQ;AAAA,EACrC,GAAG,CAAC,aAAa,MAAM,iBAAiB,gBAAgB,eAAe,CAAC;AAExE,QAAM,QAAQ;AAAA,IACZ,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,SACEC,2BAAAA,IAAC,YAAY,UAAZ,EAAqB,OAAe,SAAA,CAAS;AAElD;ACrSO,SAAS,UAA4B;AAC1C,QAAM,UAAUC,MAAAA,WAAW,WAAW;AAEtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AAEA,SAAO;AACT;ACZO,SAAS,MAAM,SAA2D;AAC/E,SAAO,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AACzC;ACDA,MAAMC,oBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OACE;AAAA,EACF,QACE;AAAA,EACF,OACE;AAAA,EACF,OAAO;AAAA,EACP,UAAU;AACZ;AAMO,MAAM,YAAsC,CAAC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,YAAY,CAAC,CAAC;AAAA,EACd;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,OAAO,WAAW,aAAa,OAAO,UAAA,IAAc,QAAA;AAC5D,QAAM,CAAC,WAAW,YAAY,IAAIC,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,EAAE;AAC3C,QAAM,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAS,KAAK;AAElD,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AAEf,QAAI,CAAC,SAAS,CAAC,UAAU;AACvB,mBAAa,iCAAiC;AAC9C;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,MAAM,EAAE,OAAO,UAAU,YAAY;AACxD,kBAAY,IAAI;AAAA,IAClB,SAAS,KAAK;AACZ,YAAM,WAAW,eAAe,QAAQ,IAAI,UAAU;AACtD,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,SACEC,gCAAC,SAAI,WACF,UAAA;AAAA,IAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,MACC,2CACE,KAAA,EAAE,WAAW,GAAGA,kBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IAGFE,2BAAAA,KAAC,UAAK,UAAU,cAAc,WAAW,GAAGF,kBAAgB,MAAM,aAAa,GAC7E,UAAA;AAAA,MAAAE,gCAAC,SAAI,WAAW,GAAGF,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,SAAQ,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACvE,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YACxC,aAAa,aAAa,SAAS;AAAA,YACnC,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,sCAEC,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,YAAW,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GAC1E,UAAA,OAAO,YAAY,WAAA,CACtB;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,YAC3C,aAAa,aAAa,YAAY;AAAA,YACtC,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,MAEAE,2BAAAA,KAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,QAAAJ,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,SAAS;AAAA,YACT,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,OAAO;AAAA,YAC/C,UAAU;AAAA,YACV,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,WAAU;AAAA,YAET,iBAAO,cAAc;AAAA,UAAA;AAAA,QAAA;AAAA,MACxB,GACF;AAAA,MAEC,wCACE,OAAA,EAAI,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACrD,UAAA,MAAA,CACH;AAAA,MAGFF,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,WAAW,GAAGE,kBAAgB,QAAQ,eAAe;AAAA,UAEpD,sBAAY,cAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAC7B,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,UAAU,cAAc;ACxJxB,MAAMA,oBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OACE;AAAA,EACF,QACE;AAAA,EACF,OACE;AAAA,EACF,OAAO;AAAA,EACP,UAAU;AACZ;AAMO,MAAM,eAA4C,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,YAAY,CAAC,CAAC;AAAA,EACd;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,UAAU,WAAW,aAAa,OAAO,UAAA,IAAc,QAAA;AAC/D,QAAM,CAAC,WAAW,YAAY,IAAIC,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,MAAM,OAAO,IAAIA,MAAAA,SAAS,EAAE;AACnC,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,EAAE;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,MAAAA,SAAS,EAAE;AAEzD,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AAEf,QAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,iBAAiB;AACpD,mBAAa,yBAAyB;AACtC;AAAA,IACF;AAEA,QAAI,aAAa,iBAAiB;AAChC,mBAAa,wBAAwB;AACrC;AAAA,IACF;AAEA,QAAI,SAAS,SAAS,GAAG;AACvB,mBAAa,wCAAwC;AACrD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,SAAS;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AACD,kBAAY,IAAI;AAAA,IAClB,SAAS,KAAK;AACZ,YAAM,WAAW,eAAe,QAAQ,IAAI,UAAU;AACtD,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,SACEC,gCAAC,SAAI,WACF,UAAA;AAAA,IAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,MACC,2CACE,KAAA,EAAE,WAAW,GAAGA,kBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IAGFE,2BAAAA,KAAC,UAAK,UAAU,cAAc,WAAW,GAAGF,kBAAgB,MAAM,aAAa,GAC7E,UAAA;AAAA,MAAAE,gCAAC,SAAI,WAAW,GAAGF,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,QAAO,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACtE,UAAA,OAAO,QAAQ,YAAA,CAClB;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,QAAQ,EAAE,OAAO,KAAK;AAAA,YACvC,aAAa,aAAa,QAAQ;AAAA,YAClC,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,sCAEC,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,SAAQ,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACvE,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YACxC,aAAa,aAAa,SAAS;AAAA,YACnC,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,sCAEC,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,YAAW,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GAC1E,UAAA,OAAO,YAAY,WAAA,CACtB;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,YAC3C,aAAa,aAAa,YAAY;AAAA,YACtC,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,sCAEC,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,mBAAkB,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACjF,UAAA,OAAO,mBAAmB,mBAAA,CAC7B;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,mBAAmB,EAAE,OAAO,KAAK;AAAA,YAClD,aAAa,aAAa,mBAAmB;AAAA,YAC7C,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,MAEC,wCACE,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACrD,UAAA,MAAA,CACH;AAAA,MAGFF,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,WAAW,GAAGE,kBAAgB,QAAQ,eAAe;AAAA,UAEpD,sBAAY,cAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAC7B,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,aAAa,cAAc;ACvL3B,MAAMA,oBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OACE;AAAA,EACF,QACE;AAAA,EACF,OACE;AAAA,EACF,SACE;AAAA,EACF,OAAO;AAAA,EACP,UAAU;AACZ;AAMO,MAAM,qBAAwD,CAAC;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,YAAY,CAAC,CAAC;AAAA,EACd;AAAA,EACA;AACF,MAAM;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,EAAA,IACL,QAAA;AACJ,QAAM,CAAC,WAAW,YAAY,IAAIC,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,EAAE;AACrC,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,MAAAA,SAAiB,EAAE;AAE/D,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AACf,sBAAkB,EAAE;AAEpB,QAAI,CAAC,OAAO;AACV,mBAAa,mBAAmB;AAChC;AAAA,IACF;AAEA,QAAI;AACF,YAAM,eAAe,EAAE,OAAO;AAC9B,wBAAkB,iDAAiD;AACnE,eAAS,EAAE;AACX,kBAAA;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,WACJ,eAAe,QAAQ,IAAI,UAAU;AACvC,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,WACEC,gCAAC,SAAI,WACF,UAAA;AAAA,MAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,QAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,QACC,2CACE,KAAA,EAAE,WAAW,GAAGA,kBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,MAAA,GAEJ;AAAA,MAEFF,2BAAAA,IAAC,OAAA,EAAI,WAAW,GAAGE,kBAAgB,SAAS,gBAAgB,GAC1D,UAAAF,2BAAAA,IAAC,KAAA,EAAG,UAAA,eAAA,CAAe,EAAA,CACrB;AAAA,IAAA,GACF;AAAA,EAEJ;AAEA,SACEI,gCAAC,SAAI,WACF,UAAA;AAAA,IAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,MACC,2CACE,KAAA,EAAE,WAAW,GAAGA,kBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IAGFE,2BAAAA,KAAC,UAAK,UAAU,cAAc,WAAW,GAAGF,kBAAgB,MAAM,aAAa,GAC7E,UAAA;AAAA,MAAAE,gCAAC,SAAI,WAAW,GAAGF,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,SAAQ,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACvE,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YACxC,aAAa,aAAa,SAAS;AAAA,YACnC,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,MAEC,wCACE,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACrD,UAAA,MAAA,CACH;AAAA,MAGFF,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,WAAW,GAAGE,kBAAgB,QAAQ,eAAe;AAAA,UAEpD,sBAAY,cAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAC7B,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,mBAAmB,cAAc;ACvJjC,MAAMA,oBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OACE;AAAA,EACF,QACE;AAAA,EACF,OACE;AAAA,EACF,SACE;AAAA,EACF,OAAO;AAAA,EACP,UAAU;AACZ;AAMO,MAAM,oBAAsD,CAAC;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,YAAY,CAAC,CAAC;AAAA,EACd;AAAA,EACA;AACF,MAAM;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,EAAA,IACL,QAAA;AACJ,QAAM,CAAC,WAAW,YAAY,IAAIC,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,EAAE;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,MAAAA,SAAS,EAAE;AACzD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,MAAAA,SAAiB,EAAE;AAE/D,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAEtC,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AACf,sBAAkB,EAAE;AAEpB,QAAI,CAAC,YAAY,CAAC,iBAAiB;AACjC,mBAAa,mCAAmC;AAChD;AAAA,IACF;AAEA,QAAI,aAAa,iBAAiB;AAChC,mBAAa,wBAAwB;AACrC;AAAA,IACF;AAEA,QAAI,SAAS,SAAS,GAAG;AACvB,mBAAa,wCAAwC;AACrD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,cAAc,EAAE,OAAO,UAAU,iBAAiB;AACxD,wBAAkB,sCAAsC;AACxD,kBAAY,EAAE;AACd,yBAAmB,EAAE;AACrB,kBAAA;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,WACJ,eAAe,QAAQ,IAAI,UAAU;AACvC,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,WACEC,gCAAC,SAAI,WACF,UAAA;AAAA,MAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,QAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,QACC,2CACE,KAAA,EAAE,WAAW,GAAGA,kBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,MAAA,GAEJ;AAAA,MAEFF,2BAAAA,IAAC,OAAA,EAAI,WAAW,GAAGE,kBAAgB,SAAS,gBAAgB,GAC1D,UAAAF,2BAAAA,IAAC,KAAA,EAAG,UAAA,eAAA,CAAe,EAAA,CACrB;AAAA,IAAA,GACF;AAAA,EAEJ;AAEA,SACEI,gCAAC,SAAI,WACF,UAAA;AAAA,IAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,MACC,2CACE,KAAA,EAAE,WAAW,GAAGA,kBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IAGFE,2BAAAA,KAAC,UAAK,UAAU,cAAc,WAAW,GAAGF,kBAAgB,MAAM,aAAa,GAC7E,UAAA;AAAA,MAAAE,gCAAC,SAAI,WAAW,GAAGF,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,YAAW,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GAC1E,UAAA,OAAO,YAAY,eAAA,CACtB;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,YAC3C,aAAa,aAAa,YAAY;AAAA,YACtC,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,sCAEC,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAF,2BAAAA,IAAC,SAAA,EAAM,SAAQ,mBAAkB,WAAW,GAAGE,kBAAgB,OAAO,cAAc,GACjF,UAAA,OAAO,mBAAmB,mBAAA,CAC7B;AAAA,QACAF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,mBAAmB,EAAE,OAAO,KAAK;AAAA,YAClD,aAAa,aAAa,mBAAmB;AAAA,YAC7C,UAAU;AAAA,YACV,WAAW,GAAGE,kBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,MAEC,wCACE,OAAA,EAAI,WAAW,GAAGA,kBAAgB,OAAO,cAAc,GACrD,UAAA,MAAA,CACH;AAAA,MAGFF,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,WAAW,GAAGE,kBAAgB,QAAQ,eAAe;AAAA,UAEpD,sBAAY,cAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAC7B,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,kBAAkB,cAAc;ACpLhC,MAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OACE;AAAA,EACF,QACE;AAAA,EACF,OACE;AAAA,EACF,SACE;AAAA,EACF,OAAO;AAAA,EACP,UAAU;AACZ;AAMO,MAAM,kBAAkD,CAAC;AAAA,EAC9D,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,CAAA;AAAA,EACT,eAAe,CAAA;AAAA,EACf,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,YAAY,CAAC,CAAC;AAAA,EACd;AAAA,EACA;AACF,MAAM;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,EAAA,IACL,QAAA;AACJ,QAAM,CAAC,WAAW,YAAY,IAAIC,MAAAA,SAAiB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,gBAAgB,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,gBAAgB,EAAE;AACrD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,MAAAA,SAAiB,EAAE;AAE/D,QAAM,YAAY;AAClB,QAAM,QAAQ,aAAa,WAAW;AAGtCJ,QAAAA,UAAU,MAAM;AACd,QAAI,SAAS,SAAS,CAAC,kBAAkB,CAAC,OAAO;AAC/C,mBAAa,EAAE,gBAAgB,MAAM;AAAA,MAAC,GAAsB;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,OAAO,KAAK,CAAC;AAEjB,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAA;AACF,iBAAa,EAAE;AACf,sBAAkB,EAAE;AAEpB,QAAI,CAAC,OAAO;AACV,mBAAa,gCAAgC;AAC7C;AAAA,IACF;AAEA,QAAI,CAAC,OAAO;AACV,mBAAa,mBAAmB;AAChC;AAAA,IACF;AAEA,QAAI;AACF,YAAM,YAAY,EAAE,OAAO,OAAO;AAClC,wBAAkB,sCAAsC;AACxD,kBAAA;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,WACJ,eAAe,QAAQ,IAAI,UAAU;AACvC,mBAAa,QAAQ;AACrB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,WACEK,gCAAC,SAAI,WACF,UAAA;AAAA,MAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,QAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAG,gBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,QACC,2CACE,KAAA,EAAE,WAAW,GAAG,gBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,MAAA,GAEJ;AAAA,MAEFA,2BAAAA,IAAC,OAAA,EAAI,WAAW,GAAG,gBAAgB,SAAS,gBAAgB,GAC1D,UAAAA,2BAAAA,IAAC,KAAA,EAAG,UAAA,eAAA,CAAe,EAAA,CACrB;AAAA,IAAA,GACF;AAAA,EAEJ;AAEA,SACEI,gCAAC,SAAI,WACF,UAAA;AAAA,IAAA,aAAa,SACZA,gCAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAAJ,2BAAAA,IAAC,QAAG,WAAW,GAAG,gBAAgB,OAAO,cAAc,GACpD,UAAA,OACH;AAAA,MACC,2CACE,KAAA,EAAE,WAAW,GAAG,gBAAgB,UAAU,iBAAiB,GACzD,UAAA,SAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IAGFI,2BAAAA,KAAC,UAAK,UAAU,cAAc,WAAW,GAAG,gBAAgB,MAAM,aAAa,GAC7E,UAAA;AAAA,MAAAA,gCAAC,SAAI,WAAW,GAAG,gBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAJ,2BAAAA,IAAC,SAAA,EAAM,SAAQ,SAAQ,WAAW,GAAG,gBAAgB,OAAO,cAAc,GACvE,UAAA,OAAO,SAAS,QAAA,CACnB;AAAA,QACAA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YACxC,aAAa,aAAa,SAAS;AAAA,YACnC,UAAU;AAAA,YACV,WAAW,GAAG,gBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,sCAEC,OAAA,EAAI,WAAW,GAAG,gBAAgB,OAAO,cAAc,GACtD,UAAA;AAAA,QAAAA,2BAAAA,IAAC,SAAA,EAAM,SAAQ,SAAQ,WAAW,GAAG,gBAAgB,OAAO,cAAc,GACvE,UAAA,OAAO,SAAS,oBAAA,CACnB;AAAA,QACAA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YACxC,aAAa,aAAa,SAAS;AAAA,YACnC,UAAU;AAAA,YACV,WAAW,GAAG,gBAAgB,OAAO,cAAc;AAAA,YACnD,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,MAEC,wCACE,OAAA,EAAI,WAAW,GAAG,gBAAgB,OAAO,cAAc,GACrD,UAAA,MAAA,CACH;AAAA,MAGFA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,WAAW,GAAG,gBAAgB,QAAQ,eAAe;AAAA,UAEpD,sBAAY,cAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAC7B,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,gBAAgB,cAAc;AChLvB,MAAM,iBAAgD,CAAC;AAAA,EAC5D;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,iBAAiB,WAAW,KAAA,IAAS,QAAA;AAG7C,MAAI,WAAW;AACb,WAAO,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAU,gBAAe,UAAA,cAAU;AAAA,EAC7D;AAGA,MAAI,CAAC,iBAAiB;AACpB,WAAOA,2BAAAA,IAACK,eAAAA,UAAA,EAAS,IAAI,YAAY,SAAO,MAAC;AAAA,EAC3C;AAGA,MAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,UAAM,UAAU,MAAM,OAAO,KAAK,CAAC,SAAS,MAAM,SAAS,IAAI,CAAC;AAChE,QAAI,CAAC,SAAS;AACZ,4CACG,OAAA,EAAI,WAAU,kBACb,UAAAL,2BAAAA,IAAC,KAAA,EAAE,6DAA+C,EAAA,CACpD;AAAA,IAEJ;AAAA,EACF;AAGA,MAAI,eAAe,YAAY,SAAS,GAAG;AACzC,UAAM,gBAAgB,MAAM,aAAa;AAAA,MAAK,CAAC,eAC7C,YAAY,SAAS,UAAU;AAAA,IAAA;AAEjC,QAAI,CAAC,eAAe;AAClB,4CACG,OAAA,EAAI,WAAU,kBACb,UAAAA,2BAAAA,IAAC,KAAA,EAAE,6DAA+C,EAAA,CACpD;AAAA,IAEJ;AAAA,EACF;AAEA,+DAAU,UAAS;AACrB;AAEA,eAAe,cAAc;;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -57,6 +57,22 @@ export declare interface AuthError {
57
57
  details?: Record<string, unknown>;
58
58
  }
59
59
 
60
+ /**
61
+ * Auth Form Class Names - Tailwind-friendly styling
62
+ */
63
+ export declare interface AuthFormClassNames {
64
+ className?: string;
65
+ formClassName?: string;
66
+ fieldClassName?: string;
67
+ labelClassName?: string;
68
+ inputClassName?: string;
69
+ buttonClassName?: string;
70
+ errorClassName?: string;
71
+ successClassName?: string;
72
+ titleClassName?: string;
73
+ subtitleClassName?: string;
74
+ }
75
+
60
76
  /**
61
77
  * AuthProvider component
62
78
  * Provides authentication state and methods to the entire application
@@ -97,6 +113,12 @@ export declare interface AuthUser {
97
113
  [key: string]: unknown;
98
114
  }
99
115
 
116
+ /**
117
+ * Utility to safely merge class names
118
+ * Filters out falsy values and joins with space
119
+ */
120
+ export declare function cn(...classes: Array<string | undefined | false | null>): string;
121
+
100
122
  /**
101
123
  * Creates an authenticated API client
102
124
  */
@@ -154,7 +176,7 @@ export declare function createAuthClient(config?: AuthClientConfig): {
154
176
 
155
177
  /**
156
178
  * ForgotPasswordForm Component
157
- * A ready-to-use forgot password form with customizable styling and callbacks
179
+ * A ready-to-use forgot password form with customizable Tailwind styling
158
180
  */
159
181
  export declare const ForgotPasswordForm: default_2.FC<ForgotPasswordFormProps>;
160
182
 
@@ -170,11 +192,14 @@ export declare interface ForgotPasswordPayload {
170
192
  /**
171
193
  * Form Component Props
172
194
  */
173
- export declare interface FormComponentProps {
174
- className?: string;
195
+ export declare interface FormComponentProps extends AuthFormClassNames {
175
196
  labels?: Record<string, string>;
176
197
  placeholders?: Record<string, string>;
177
198
  submitButtonText?: string;
199
+ loadingText?: string;
200
+ title?: string;
201
+ subtitle?: string;
202
+ showTitle?: boolean;
178
203
  isLoading?: boolean;
179
204
  error?: string;
180
205
  onSuccess?: (user?: AuthUser) => void;
@@ -183,7 +208,7 @@ export declare interface FormComponentProps {
183
208
 
184
209
  /**
185
210
  * LoginForm Component
186
- * A ready-to-use login form with customizable styling and callbacks
211
+ * A ready-to-use login form with customizable Tailwind styling
187
212
  */
188
213
  export declare const LoginForm: default_2.FC<LoginFormProps>;
189
214
 
@@ -226,7 +251,7 @@ export declare interface ProtectedRouteProps {
226
251
 
227
252
  /**
228
253
  * RegisterForm Component
229
- * A ready-to-use registration form with customizable styling and callbacks
254
+ * A ready-to-use registration form with customizable Tailwind styling
230
255
  */
231
256
  export declare const RegisterForm: default_2.FC<RegisterFormProps>;
232
257
 
@@ -250,7 +275,7 @@ export declare type RequestAdapter = (url: string, options: RequestInit) => Prom
250
275
 
251
276
  /**
252
277
  * ResetPasswordForm Component
253
- * A ready-to-use password reset form with customizable styling and callbacks
278
+ * A ready-to-use password reset form with customizable Tailwind styling
254
279
  */
255
280
  export declare const ResetPasswordForm: default_2.FC<ResetPasswordFormProps>;
256
281
 
@@ -274,7 +299,7 @@ export declare function useAuth(): AuthContextValue;
274
299
 
275
300
  /**
276
301
  * VerifyEmailForm Component
277
- * A ready-to-use email verification form with customizable styling and callbacks
302
+ * A ready-to-use email verification form with customizable Tailwind styling
278
303
  */
279
304
  export declare const VerifyEmailForm: default_2.FC<VerifyEmailFormProps>;
280
305