@secmia/openui-flow 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/AdaptiveFlow.tsx","../src/engine.ts"],"sourcesContent":["export {\r\n\tAdaptiveFlow,\r\n\ttype AdaptiveFlowAdapter,\r\n\ttype AdaptiveFlowClassNames,\r\n\ttype AdaptiveFlowPersistence,\r\n\ttype AdaptiveFlowProps,\r\n\ttype AdaptiveStepRegistry,\r\n\ttype AdaptiveStepRendererArgs,\r\n\ttype AdaptiveStepTransition,\r\n\ttype AdaptiveFlowStorageDriver,\r\n\ttype AdaptiveFlowStyleSlot,\r\n\ttype AdaptiveFlowStyles,\r\n\ttype AdaptiveFlowValidationContext,\r\n\ttype AdaptiveFlowValidators,\r\n\ttype AdaptiveStepRenderArgs,\r\n\ttype IdentityResolution,\r\n\ttype OAuthProvider,\r\n\ttype PersistedAdaptiveFlowState,\r\n} from \"./AdaptiveFlow\";\r\nexport {\r\n\tdefaultRequirements,\r\n\tcreateDefaultRequirementGraph,\r\n\tcreateRequirementGraph,\r\n\tdefaultRequirementResolvers,\r\n\tevaluateNextStep,\r\n\tgetMissingRequirements,\r\n\tinitialContext,\r\n\ttype RequirementGraph,\r\n\ttype RequirementGraphNode,\r\n\ttype MaybePromise,\r\n\tDefaultAdaptiveSteps,\r\n\tDefaultAppRequirements,\r\n\ttype AdaptiveContext,\r\n\ttype AdaptiveContextBase,\r\n\ttype AdaptiveStep,\r\n\ttype AppRequirement,\r\n\ttype DefaultAdaptiveStep,\r\n\ttype DefaultAppRequirement,\r\n\ttype RequirementResolver,\r\n} from \"./engine\";","\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport {\r\n createDefaultRequirementGraph,\r\n defaultRequirementResolvers,\r\n defaultRequirements,\r\n evaluateNextStep,\r\n getMissingRequirements,\r\n initialContext,\r\n type AdaptiveContext,\r\n type AdaptiveContextBase,\r\n type AdaptiveStep,\r\n type AppRequirement,\r\n type MaybePromise,\r\n type RequirementGraph,\r\n type RequirementResolver,\r\n} from \"./engine\";\r\n\r\nexport type OAuthProvider = \"google\" | \"apple\";\r\n\r\nexport type IdentityResolution = {\r\n accountExists: boolean;\r\n hasPassword?: boolean;\r\n isVerified?: boolean;\r\n agreedToTos?: boolean;\r\n profile?: Partial<AdaptiveContextBase[\"profile\"]>;\r\n};\r\n\r\nexport type AdaptiveFlowAdapter<TContext extends AdaptiveContextBase = AdaptiveContextBase> = {\r\n lookupByEmail?: (email: string) => Promise<IdentityResolution | null>;\r\n requestOtp?: (email: string) => Promise<void>;\r\n verifyOtp?: (email: string, code: string) => Promise<void>;\r\n signInWithPassword?: (email: string, password: string) => Promise<void>;\r\n createPassword?: (password: string) => Promise<void>;\r\n saveProfile?: (context: TContext) => Promise<void>;\r\n acceptTos?: (context: TContext) => Promise<void>;\r\n startOAuth?: (provider: OAuthProvider, context: TContext) => Promise<void>;\r\n completeOAuth?: (\r\n provider: OAuthProvider | null,\r\n context: TContext,\r\n ) => Promise<Partial<TContext> | void>;\r\n};\r\n\r\nexport type AdaptiveFlowStyleSlot =\r\n | \"shell\"\r\n | \"headerRow\"\r\n | \"eyebrow\"\r\n | \"title\"\r\n | \"badge\"\r\n | \"success\"\r\n | \"error\"\r\n | \"info\"\r\n | \"caption\"\r\n | \"formRow\"\r\n | \"formColumn\"\r\n | \"input\"\r\n | \"button\"\r\n | \"checkboxRow\"\r\n | \"complete\"\r\n | \"footer\"\r\n | \"oauthButton\";\r\n\r\nexport type AdaptiveFlowStyles = Partial<Record<AdaptiveFlowStyleSlot, React.CSSProperties>>;\r\nexport type AdaptiveFlowClassNames = Partial<Record<AdaptiveFlowStyleSlot, string>>;\r\n\r\nexport type AdaptiveFlowStorageDriver = Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\r\n\r\nexport type AdaptiveFlowPersistence<TContext extends AdaptiveContextBase = AdaptiveContextBase> = {\r\n key: string;\r\n storage?: \"session\" | \"local\" | AdaptiveFlowStorageDriver;\r\n serialize?: (state: PersistedAdaptiveFlowState<TContext>) => string;\r\n deserialize?: (value: string) => PersistedAdaptiveFlowState<TContext>;\r\n clearOnComplete?: boolean;\r\n};\r\n\r\nexport type PersistedAdaptiveFlowState<TContext extends AdaptiveContextBase = AdaptiveContextBase> = {\r\n context: TContext;\r\n oauthPendingProvider: OAuthProvider | null;\r\n};\r\n\r\nexport type AdaptiveFlowValidationContext<\r\n TContext extends AdaptiveContextBase = AdaptiveContextBase,\r\n> = {\r\n context: TContext;\r\n};\r\n\r\nexport type AdaptiveFlowValidators<TContext extends AdaptiveContextBase = AdaptiveContextBase> = {\r\n email?: (input: string, payload: AdaptiveFlowValidationContext<TContext>) => string | void | Promise<string | void>;\r\n otp?: (\r\n input: string,\r\n payload: AdaptiveFlowValidationContext<TContext> & { email: string },\r\n ) => string | void | Promise<string | void>;\r\n password?: (\r\n input: string,\r\n payload: AdaptiveFlowValidationContext<TContext> & { hasPassword: boolean },\r\n ) => string | void | Promise<string | void>;\r\n profile?: (\r\n input: AdaptiveContextBase[\"profile\"],\r\n payload: AdaptiveFlowValidationContext<TContext>,\r\n ) => string | void | Promise<string | void>;\r\n tos?: (\r\n accepted: boolean,\r\n payload: AdaptiveFlowValidationContext<TContext>,\r\n ) => string | void | Promise<string | void>;\r\n};\r\n\r\nexport type AdaptiveStepTransition<TStep extends string = AdaptiveStep> = {\r\n from: TStep | null;\r\n to: TStep;\r\n at: number;\r\n attempt: number;\r\n};\r\n\r\nexport type AdaptiveStepRendererArgs<\r\n TContext extends AdaptiveContextBase,\r\n TRequirement extends string,\r\n TStep extends string,\r\n> = {\r\n step: TStep;\r\n context: TContext;\r\n busy: boolean;\r\n message: string | null;\r\n errorMessage: string | null;\r\n missingRequirements: TRequirement[];\r\n requirements: readonly TRequirement[];\r\n setContextPatch: (patch: Partial<TContext>) => void;\r\n run: (job: () => Promise<void>) => Promise<void>;\r\n adapter?: AdaptiveFlowAdapter<TContext>;\r\n transitions: AdaptiveStepTransition<TStep>[];\r\n};\r\n\r\nexport type AdaptiveStepRegistry<\r\n TContext extends AdaptiveContextBase,\r\n TRequirement extends string,\r\n TStep extends string,\r\n> = Partial<\r\n Record<TStep, (args: AdaptiveStepRendererArgs<TContext, TRequirement, TStep>) => React.ReactNode>\r\n>;\r\n\r\nexport type AdaptiveStepRenderArgs<\r\n TContext extends AdaptiveContextBase = AdaptiveContextBase,\r\n TRequirement extends string = AppRequirement,\r\n TStep extends string = AdaptiveStep,\r\n> = {\r\n step: TStep;\r\n context: TContext;\r\n busy: boolean;\r\n message: string | null;\r\n errorMessage: string | null;\r\n missingRequirements: TRequirement[];\r\n requirements: readonly TRequirement[];\r\n defaultView: React.ReactNode;\r\n setContextPatch: (patch: Partial<TContext>) => void;\r\n run: (job: () => Promise<void>) => Promise<void>;\r\n adapter?: AdaptiveFlowAdapter<TContext>;\r\n transitions: AdaptiveStepTransition<TStep>[];\r\n};\r\n\r\nexport type AdaptiveFlowProps<\r\n TContext extends AdaptiveContextBase = AdaptiveContext,\r\n TRequirement extends string = AppRequirement,\r\n TStep extends string = AdaptiveStep,\r\n> = {\r\n adapter?: AdaptiveFlowAdapter<TContext>;\r\n requirements?: readonly TRequirement[];\r\n requirementGraph?: RequirementGraph<TContext, TRequirement, TStep>;\r\n requirementGraphConfig?: {\r\n priorities?: Partial<Record<TRequirement, number>>;\r\n conditions?: Partial<Record<TRequirement, (context: TContext) => MaybePromise<boolean>>>;\r\n dependencies?: Partial<Record<TRequirement, readonly TRequirement[]>>;\r\n };\r\n requirementResolvers?: Partial<Record<TRequirement, RequirementResolver<TContext, TStep>>>;\r\n completeStep?: TStep;\r\n stepTitles?: Partial<Record<TStep, string>>;\r\n renderStep?: (args: AdaptiveStepRenderArgs<TContext, TRequirement, TStep>) => React.ReactNode;\r\n stepRegistry?: AdaptiveStepRegistry<TContext, TRequirement, TStep>;\r\n initialValue?: Partial<TContext>;\r\n onComplete?: (context: TContext) => void;\r\n onError?: (error: Error) => void;\r\n onStepTransition?: (transition: AdaptiveStepTransition<TStep>, context: TContext) => void;\r\n className?: string;\r\n classNames?: AdaptiveFlowClassNames;\r\n styles?: AdaptiveFlowStyles;\r\n unstyled?: boolean;\r\n persistence?: AdaptiveFlowPersistence<TContext>;\r\n validators?: AdaptiveFlowValidators<TContext>;\r\n};\r\n\r\nconst defaultStepTitle: Record<string, string> = {\r\n COLLECT_EMAIL: \"Enter your email\",\r\n VERIFY_OTP: \"Verify your email\",\r\n COLLECT_PASSWORD: \"Set up your password\",\r\n COLLECT_PROFILE: \"Complete your profile\",\r\n COLLECT_TOS: \"Accept terms\",\r\n COMPLETE: \"Done\",\r\n};\r\n\r\nconst styleSlots: AdaptiveFlowStyleSlot[] = [\r\n \"shell\",\r\n \"headerRow\",\r\n \"eyebrow\",\r\n \"title\",\r\n \"badge\",\r\n \"success\",\r\n \"error\",\r\n \"info\",\r\n \"caption\",\r\n \"formRow\",\r\n \"formColumn\",\r\n \"input\",\r\n \"button\",\r\n \"checkboxRow\",\r\n \"complete\",\r\n \"footer\",\r\n \"oauthButton\",\r\n];\r\n\r\nfunction mergeContext<TContext extends AdaptiveContextBase>(\r\n current: TContext,\r\n patch: Partial<TContext>,\r\n): TContext {\r\n return {\r\n ...current,\r\n ...patch,\r\n profile: {\r\n ...current.profile,\r\n ...patch.profile,\r\n },\r\n } as TContext;\r\n}\r\n\r\nfunction withDefaults<TContext extends AdaptiveContextBase>(initialValue?: Partial<TContext>): TContext {\r\n if (!initialValue) {\r\n return initialContext as TContext;\r\n }\r\n\r\n return mergeContext(initialContext as TContext, initialValue);\r\n}\r\n\r\nfunction toError(error: unknown): Error {\r\n if (error instanceof Error) {\r\n return error;\r\n }\r\n return new Error(\"Unknown error while processing adaptive flow\");\r\n}\r\n\r\nfunction cx(...names: Array<string | undefined | false | null>): string | undefined {\r\n const value = names.filter(Boolean).join(\" \").trim();\r\n return value.length > 0 ? value : undefined;\r\n}\r\n\r\nfunction pickStorage(storage?: \"session\" | \"local\" | AdaptiveFlowStorageDriver): AdaptiveFlowStorageDriver | null {\r\n if (typeof window === \"undefined\") {\r\n return null;\r\n }\r\n\r\n if (!storage || storage === \"session\") {\r\n return window.sessionStorage;\r\n }\r\n\r\n if (storage === \"local\") {\r\n return window.localStorage;\r\n }\r\n\r\n return storage;\r\n}\r\n\r\nfunction readPersistedState<TContext extends AdaptiveContextBase>(\r\n persistence: AdaptiveFlowPersistence<TContext> | undefined,\r\n): PersistedAdaptiveFlowState<TContext> | null {\r\n if (!persistence) {\r\n return null;\r\n }\r\n\r\n const storage = pickStorage(persistence.storage);\r\n if (!storage) {\r\n return null;\r\n }\r\n\r\n const raw = storage.getItem(persistence.key);\r\n if (!raw) {\r\n return null;\r\n }\r\n\r\n const deserialize = persistence.deserialize ?? ((value: string) => JSON.parse(value));\r\n return deserialize(raw);\r\n}\r\n\r\nfunction writePersistedState<TContext extends AdaptiveContextBase>(\r\n persistence: AdaptiveFlowPersistence<TContext> | undefined,\r\n state: PersistedAdaptiveFlowState<TContext>,\r\n): void {\r\n if (!persistence) {\r\n return;\r\n }\r\n\r\n const storage = pickStorage(persistence.storage);\r\n if (!storage) {\r\n return;\r\n }\r\n\r\n const serialize = persistence.serialize ?? ((value: PersistedAdaptiveFlowState<TContext>) => JSON.stringify(value));\r\n storage.setItem(persistence.key, serialize(state));\r\n}\r\n\r\nfunction clearPersistedState<TContext extends AdaptiveContextBase>(\r\n persistence: AdaptiveFlowPersistence<TContext> | undefined,\r\n): void {\r\n if (!persistence) {\r\n return;\r\n }\r\n\r\n const storage = pickStorage(persistence.storage);\r\n if (!storage) {\r\n return;\r\n }\r\n\r\n storage.removeItem(persistence.key);\r\n}\r\n\r\nasync function assertValid(result: string | void | Promise<string | void>): Promise<void> {\r\n const message = await result;\r\n if (typeof message === \"string\" && message.trim().length > 0) {\r\n throw new Error(message);\r\n }\r\n}\r\n\r\nfunction resolveStyles(\r\n unstyled: boolean,\r\n styleOverrides?: AdaptiveFlowStyles,\r\n): Record<AdaptiveFlowStyleSlot, React.CSSProperties | undefined> {\r\n const resolved = {} as Record<AdaptiveFlowStyleSlot, React.CSSProperties | undefined>;\r\n\r\n for (const slot of styleSlots) {\r\n if (unstyled) {\r\n resolved[slot] = styleOverrides?.[slot];\r\n continue;\r\n }\r\n\r\n resolved[slot] = {\r\n ...defaultStyles[slot],\r\n ...(styleOverrides?.[slot] ?? {}),\r\n };\r\n }\r\n\r\n return resolved;\r\n}\r\n\r\nexport function AdaptiveFlow<\r\n TContext extends AdaptiveContextBase = AdaptiveContext,\r\n TRequirement extends string = AppRequirement,\r\n TStep extends string = AdaptiveStep,\r\n>({\r\n adapter,\r\n requirements,\r\n requirementGraph,\r\n requirementGraphConfig,\r\n requirementResolvers,\r\n completeStep,\r\n stepTitles,\r\n renderStep,\r\n stepRegistry,\r\n initialValue,\r\n onComplete,\r\n onError,\r\n onStepTransition,\r\n className,\r\n classNames,\r\n styles,\r\n unstyled = false,\r\n persistence,\r\n validators,\r\n}: AdaptiveFlowProps<TContext, TRequirement, TStep>) {\r\n const normalizedRequirements = React.useMemo(\r\n () => (requirements ?? (defaultRequirements as unknown as readonly TRequirement[])),\r\n [requirements],\r\n );\r\n const normalizedCompleteStep = React.useMemo(\r\n () => (completeStep ?? (\"COMPLETE\" as TStep)),\r\n [completeStep],\r\n );\r\n const resolvers = React.useMemo(\r\n () =>\r\n ({\r\n ...(defaultRequirementResolvers as unknown as Partial<\r\n Record<TRequirement, RequirementResolver<TContext, TStep>>\r\n >),\r\n ...(requirementResolvers ?? {}),\r\n }) as Partial<Record<TRequirement, RequirementResolver<TContext, TStep>>>,\r\n [requirementResolvers],\r\n );\r\n const graph = React.useMemo(\r\n () =>\r\n requirementGraph ??\r\n createDefaultRequirementGraph({\r\n requirements: normalizedRequirements,\r\n resolvers,\r\n priorities: requirementGraphConfig?.priorities,\r\n conditions: requirementGraphConfig?.conditions,\r\n dependencies: requirementGraphConfig?.dependencies,\r\n }),\r\n [\r\n requirementGraph,\r\n normalizedRequirements,\r\n resolvers,\r\n requirementGraphConfig?.priorities,\r\n requirementGraphConfig?.conditions,\r\n requirementGraphConfig?.dependencies,\r\n ],\r\n );\r\n\r\n const uiStyles = React.useMemo(() => resolveStyles(unstyled, styles), [unstyled, styles]);\r\n\r\n const [context, setContext] = React.useState<TContext>(() => withDefaults(initialValue));\r\n const [step, setStep] = React.useState<TStep>(normalizedCompleteStep);\r\n const [missingRequirements, setMissingRequirements] = React.useState<TRequirement[]>([]);\r\n const [transitions, setTransitions] = React.useState<AdaptiveStepTransition<TStep>[]>([]);\r\n const [busy, setBusy] = React.useState(false);\r\n const [message, setMessage] = React.useState<string | null>(null);\r\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null);\r\n const [oauthPendingProvider, setOauthPendingProvider] = React.useState<OAuthProvider | null>(null);\r\n const [persistenceHydrated, setPersistenceHydrated] = React.useState(!persistence);\r\n const attemptByStepRef = React.useRef<Record<string, number>>({});\r\n const previousStepRef = React.useRef<TStep | null>(null);\r\n const evaluationRef = React.useRef(0);\r\n const completed = React.useRef(false);\r\n\r\n React.useEffect(() => {\r\n if (!persistence) {\r\n return;\r\n }\r\n\r\n try {\r\n const persisted = readPersistedState(persistence);\r\n if (persisted?.context) {\r\n setContext(mergeContext(withDefaults(initialValue), persisted.context));\r\n }\r\n if (persisted?.oauthPendingProvider) {\r\n setOauthPendingProvider(persisted.oauthPendingProvider);\r\n }\r\n } catch {\r\n // Invalid persisted payload should not break rendering.\r\n } finally {\r\n setPersistenceHydrated(true);\r\n }\r\n }, [initialValue, persistence]);\r\n\r\n React.useEffect(() => {\r\n let isCancelled = false;\r\n const currentEvaluation = ++evaluationRef.current;\r\n\r\n void (async () => {\r\n const [missing, next] = await Promise.all([\r\n getMissingRequirements(context, graph as RequirementGraph<TContext, TRequirement, TStep>),\r\n evaluateNextStep(context, graph as RequirementGraph<TContext, TRequirement, TStep>, normalizedCompleteStep),\r\n ]);\r\n\r\n if (isCancelled || currentEvaluation !== evaluationRef.current) {\r\n return;\r\n }\r\n\r\n setMissingRequirements(missing);\r\n setStep(next);\r\n\r\n const from = previousStepRef.current;\r\n const attemptKey = String(next);\r\n const nextAttempt = from === next ? (attemptByStepRef.current[attemptKey] ?? 0) + 1 : 1;\r\n attemptByStepRef.current[attemptKey] = nextAttempt;\r\n\r\n const transition: AdaptiveStepTransition<TStep> = {\r\n from,\r\n to: next,\r\n at: Date.now(),\r\n attempt: nextAttempt,\r\n };\r\n\r\n setTransitions((previous) => [...previous, transition].slice(-100));\r\n previousStepRef.current = next;\r\n onStepTransition?.(transition, context);\r\n })().catch((error) => {\r\n if (isCancelled || currentEvaluation !== evaluationRef.current) {\r\n return;\r\n }\r\n\r\n const normalized = toError(error);\r\n setErrorMessage(normalized.message);\r\n onError?.(normalized);\r\n });\r\n\r\n return () => {\r\n isCancelled = true;\r\n };\r\n }, [context, graph, normalizedCompleteStep, onError, onStepTransition]);\r\n\r\n React.useEffect(() => {\r\n if (step === normalizedCompleteStep) {\r\n if (!completed.current) {\r\n completed.current = true;\r\n onComplete?.(context);\r\n\r\n const shouldClearPersistence = persistence?.clearOnComplete ?? true;\r\n if (shouldClearPersistence) {\r\n clearPersistedState(persistence);\r\n }\r\n }\r\n } else {\r\n completed.current = false;\r\n }\r\n }, [context, normalizedCompleteStep, onComplete, persistence, step]);\r\n\r\n React.useEffect(() => {\r\n if (!persistence || !persistenceHydrated) {\r\n return;\r\n }\r\n\r\n try {\r\n writePersistedState(persistence, { context, oauthPendingProvider });\r\n } catch {\r\n // Storage quota/privacy mode issues should not fail auth flow.\r\n }\r\n }, [context, oauthPendingProvider, persistence, persistenceHydrated]);\r\n\r\n const run = React.useCallback(\r\n async (job: () => Promise<void>) => {\r\n setBusy(true);\r\n setErrorMessage(null);\r\n try {\r\n await job();\r\n } catch (error) {\r\n const normalized = toError(error);\r\n setErrorMessage(normalized.message);\r\n onError?.(normalized);\r\n } finally {\r\n setBusy(false);\r\n }\r\n },\r\n [onError],\r\n );\r\n\r\n const patchContext = React.useCallback((patch: Partial<TContext>) => {\r\n setContext((prev) => mergeContext(prev, patch));\r\n }, []);\r\n\r\n const patchBaseContext = React.useCallback(\r\n (patch: Partial<AdaptiveContextBase>) => {\r\n patchContext(patch as Partial<TContext>);\r\n },\r\n [patchContext],\r\n );\r\n\r\n React.useEffect(() => {\r\n const completeOAuth = adapter?.completeOAuth;\r\n if (!oauthPendingProvider || !completeOAuth) {\r\n return;\r\n }\r\n\r\n void run(async () => {\r\n const patch = await completeOAuth(oauthPendingProvider, context);\r\n if (patch) {\r\n patchContext(patch);\r\n }\r\n setOauthPendingProvider(null);\r\n setMessage(\"OAuth sign-in completed.\");\r\n });\r\n }, [adapter, context, oauthPendingProvider, patchContext, run]);\r\n\r\n const handleEmail = (emailInput: string) => {\r\n const email = emailInput.trim().toLowerCase();\r\n if (!email) {\r\n return;\r\n }\r\n\r\n void run(async () => {\r\n if (validators?.email) {\r\n await assertValid(validators.email(email, { context }));\r\n }\r\n\r\n const identity = (await adapter?.lookupByEmail?.(email)) ?? null;\r\n\r\n patchBaseContext({\r\n email,\r\n hasPassword: Boolean(identity?.hasPassword),\r\n isVerified: Boolean(identity?.isVerified),\r\n agreedToTos: Boolean(identity?.agreedToTos),\r\n profile: {\r\n firstName: identity?.profile?.firstName ?? null,\r\n lastName: identity?.profile?.lastName ?? null,\r\n jobTitle: identity?.profile?.jobTitle ?? null,\r\n },\r\n });\r\n\r\n if (identity?.accountExists && identity.hasPassword) {\r\n setMessage(\"Welcome back. Enter your password to continue.\");\r\n return;\r\n }\r\n\r\n if (adapter?.requestOtp) {\r\n await adapter.requestOtp(email);\r\n setMessage(\"We sent a 6-digit code to your inbox.\");\r\n } else {\r\n patchBaseContext({ isVerified: true });\r\n setMessage(\"No OTP adapter configured. Email verification was skipped.\");\r\n }\r\n });\r\n };\r\n\r\n const handleOtp = (code: string) => {\r\n if (!context.email) {\r\n return;\r\n }\r\n\r\n void run(async () => {\r\n if (validators?.otp) {\r\n await assertValid(validators.otp(code, { context, email: context.email as string }));\r\n }\r\n\r\n if (adapter?.verifyOtp) {\r\n await adapter.verifyOtp(context.email as string, code);\r\n }\r\n patchBaseContext({ isVerified: true });\r\n setMessage(\"Email verified.\");\r\n });\r\n };\r\n\r\n const handlePassword = (password: string) => {\r\n if (!context.email) {\r\n return;\r\n }\r\n\r\n void run(async () => {\r\n if (validators?.password) {\r\n await assertValid(validators.password(password, { context, hasPassword: context.hasPassword }));\r\n }\r\n\r\n if (context.hasPassword) {\r\n if (adapter?.signInWithPassword) {\r\n await adapter.signInWithPassword(context.email as string, password);\r\n }\r\n } else {\r\n if (adapter?.createPassword) {\r\n await adapter.createPassword(password);\r\n }\r\n patchBaseContext({ hasPassword: true });\r\n }\r\n setMessage(\"Password step complete.\");\r\n });\r\n };\r\n\r\n const handleProfile = (profile: AdaptiveContextBase[\"profile\"]) => {\r\n void run(async () => {\r\n if (validators?.profile) {\r\n await assertValid(validators.profile(profile, { context }));\r\n }\r\n\r\n const next = mergeContext(context, {\r\n profile: {\r\n firstName: profile.firstName || null,\r\n lastName: profile.lastName || null,\r\n jobTitle: profile.jobTitle || null,\r\n },\r\n } as Partial<TContext>);\r\n\r\n if (adapter?.saveProfile) {\r\n await adapter.saveProfile(next);\r\n }\r\n\r\n patchContext({ profile: next.profile } as Partial<TContext>);\r\n setMessage(\"Profile saved.\");\r\n });\r\n };\r\n\r\n const handleTos = () => {\r\n void run(async () => {\r\n if (validators?.tos) {\r\n await assertValid(validators.tos(true, { context }));\r\n }\r\n\r\n const next = mergeContext(context, { agreedToTos: true } as Partial<TContext>);\r\n if (adapter?.acceptTos) {\r\n await adapter.acceptTos(next);\r\n }\r\n patchBaseContext({ agreedToTos: true });\r\n setMessage(\"Terms accepted.\");\r\n });\r\n };\r\n\r\n const handleOAuth = (provider: OAuthProvider) => {\r\n const startOAuth = adapter?.startOAuth;\r\n if (!startOAuth) {\r\n return;\r\n }\r\n\r\n void run(async () => {\r\n setOauthPendingProvider(provider);\r\n setMessage(`Starting ${provider} sign-in...`);\r\n await startOAuth(provider, context);\r\n });\r\n };\r\n\r\n const missing = missingRequirements;\r\n const needsJobTitle = normalizedRequirements.includes(\"has_job_title\" as TRequirement);\r\n const stepLabel = stepTitles?.[step] ?? defaultStepTitle[step] ?? step;\r\n\r\n const defaultView = (\r\n <>\r\n {step === \"COLLECT_EMAIL\" ? (\r\n <EmailBlock\r\n onSubmit={handleEmail}\r\n disabled={busy}\r\n styles={uiStyles}\r\n classNames={classNames}\r\n />\r\n ) : null}\r\n {step === \"VERIFY_OTP\" ? (\r\n <OtpBlock\r\n onSubmit={handleOtp}\r\n email={context.email ?? \"your email\"}\r\n disabled={busy}\r\n styles={uiStyles}\r\n classNames={classNames}\r\n />\r\n ) : null}\r\n {step === \"COLLECT_PASSWORD\" ? (\r\n <PasswordBlock\r\n onSubmit={handlePassword}\r\n disabled={busy}\r\n hasPassword={context.hasPassword}\r\n styles={uiStyles}\r\n classNames={classNames}\r\n />\r\n ) : null}\r\n {step === \"COLLECT_PROFILE\" ? (\r\n <ProfileBlock\r\n defaultValue={context.profile}\r\n requireJobTitle={needsJobTitle}\r\n onSubmit={handleProfile}\r\n disabled={busy}\r\n styles={uiStyles}\r\n classNames={classNames}\r\n />\r\n ) : null}\r\n {step === \"COLLECT_TOS\" ? (\r\n <TosBlock\r\n onSubmit={handleTos}\r\n disabled={busy}\r\n styles={uiStyles}\r\n classNames={classNames}\r\n />\r\n ) : null}\r\n {step === normalizedCompleteStep ? (\r\n <CompleteBlock styles={uiStyles} classNames={classNames} />\r\n ) : null}\r\n {step !== \"COLLECT_EMAIL\" &&\r\n step !== \"VERIFY_OTP\" &&\r\n step !== \"COLLECT_PASSWORD\" &&\r\n step !== \"COLLECT_PROFILE\" &&\r\n step !== \"COLLECT_TOS\" &&\r\n step !== normalizedCompleteStep ? (\r\n <div className={classNames?.info} style={uiStyles.info}>\r\n No default renderer for step \"{step}\". Provide renderStep to handle custom steps.\r\n </div>\r\n ) : null}\r\n </>\r\n );\r\n\r\n const customView = renderStep\r\n ? renderStep({\r\n step,\r\n context,\r\n busy,\r\n message,\r\n errorMessage,\r\n missingRequirements: missing,\r\n requirements: normalizedRequirements,\r\n defaultView,\r\n setContextPatch: patchContext,\r\n run,\r\n adapter,\r\n transitions,\r\n })\r\n : null;\r\n const registryView = stepRegistry?.[step]\r\n ? stepRegistry[step]?.({\r\n step,\r\n context,\r\n busy,\r\n message,\r\n errorMessage,\r\n missingRequirements: missing,\r\n requirements: normalizedRequirements,\r\n setContextPatch: patchContext,\r\n run,\r\n adapter,\r\n transitions,\r\n })\r\n : null;\r\n\r\n return (\r\n <div className={cx(className, classNames?.shell)} style={uiStyles.shell}>\r\n <div className={classNames?.headerRow} style={uiStyles.headerRow}>\r\n <div>\r\n <div className={classNames?.eyebrow} style={uiStyles.eyebrow}>\r\n Adaptive flow\r\n </div>\r\n <h2 className={classNames?.title} style={uiStyles.title}>\r\n {stepLabel}\r\n </h2>\r\n </div>\r\n <div className={classNames?.badge} style={uiStyles.badge}>\r\n {normalizedRequirements.length - missing.length}/{normalizedRequirements.length}\r\n </div>\r\n </div>\r\n\r\n {message ? (\r\n <div className={classNames?.success} style={uiStyles.success}>\r\n {message}\r\n </div>\r\n ) : null}\r\n {errorMessage ? (\r\n <div className={classNames?.error} style={uiStyles.error}>\r\n {errorMessage}\r\n </div>\r\n ) : null}\r\n\r\n {customView ?? registryView ?? defaultView}\r\n\r\n <div className={classNames?.footer} style={uiStyles.footer}>\r\n <button\r\n type=\"button\"\r\n className={classNames?.oauthButton}\r\n style={uiStyles.oauthButton}\r\n disabled={busy || !adapter?.startOAuth}\r\n onClick={() => {\r\n handleOAuth(\"google\");\r\n }}\r\n >\r\n Continue with Google\r\n </button>\r\n <button\r\n type=\"button\"\r\n className={classNames?.oauthButton}\r\n style={uiStyles.oauthButton}\r\n disabled={busy || !adapter?.startOAuth}\r\n onClick={() => {\r\n handleOAuth(\"apple\");\r\n }}\r\n >\r\n Continue with Apple\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ntype BlockBaseProps = {\r\n disabled?: boolean;\r\n styles: Record<AdaptiveFlowStyleSlot, React.CSSProperties | undefined>;\r\n classNames?: AdaptiveFlowClassNames;\r\n};\r\n\r\nfunction EmailBlock({ onSubmit, disabled, styles, classNames }: BlockBaseProps & { onSubmit: (email: string) => void }) {\r\n const [email, setEmail] = React.useState(\"\");\r\n return (\r\n <form\r\n className={classNames?.formRow}\r\n style={styles.formRow}\r\n onSubmit={(event) => {\r\n event.preventDefault();\r\n onSubmit(email);\r\n }}\r\n >\r\n <input\r\n className={classNames?.input}\r\n style={styles.input}\r\n type=\"email\"\r\n autoComplete=\"email\"\r\n placeholder=\"Enter your email\"\r\n value={email}\r\n onChange={(event) => setEmail(event.target.value)}\r\n required\r\n />\r\n <button className={classNames?.button} style={styles.button} disabled={disabled} type=\"submit\">\r\n Continue\r\n </button>\r\n </form>\r\n );\r\n}\r\n\r\nfunction OtpBlock({\r\n onSubmit,\r\n disabled,\r\n email,\r\n styles,\r\n classNames,\r\n}: BlockBaseProps & { onSubmit: (code: string) => void; email: string }) {\r\n const [code, setCode] = React.useState(\"\");\r\n return (\r\n <form\r\n className={classNames?.formColumn}\r\n style={styles.formColumn}\r\n onSubmit={(event) => {\r\n event.preventDefault();\r\n onSubmit(code);\r\n }}\r\n >\r\n <p className={classNames?.caption} style={styles.caption}>\r\n Use the verification code sent to {email}.\r\n </p>\r\n <div className={classNames?.formRow} style={styles.formRow}>\r\n <input\r\n className={classNames?.input}\r\n style={styles.input}\r\n inputMode=\"numeric\"\r\n placeholder=\"Enter 6-digit code\"\r\n value={code}\r\n onChange={(event) => setCode(event.target.value.replace(/\\D/g, \"\").slice(0, 6))}\r\n required\r\n maxLength={6}\r\n pattern=\"[0-9]{6}\"\r\n />\r\n <button\r\n className={classNames?.button}\r\n style={styles.button}\r\n disabled={disabled || code.length !== 6}\r\n type=\"submit\"\r\n >\r\n Verify\r\n </button>\r\n </div>\r\n </form>\r\n );\r\n}\r\n\r\nfunction PasswordBlock({\r\n onSubmit,\r\n disabled,\r\n hasPassword,\r\n styles,\r\n classNames,\r\n}: BlockBaseProps & { onSubmit: (password: string) => void; hasPassword: boolean }) {\r\n const [password, setPassword] = React.useState(\"\");\r\n return (\r\n <form\r\n className={classNames?.formRow}\r\n style={styles.formRow}\r\n onSubmit={(event) => {\r\n event.preventDefault();\r\n onSubmit(password);\r\n }}\r\n >\r\n <input\r\n className={classNames?.input}\r\n style={styles.input}\r\n type=\"password\"\r\n autoComplete={hasPassword ? \"current-password\" : \"new-password\"}\r\n placeholder={hasPassword ? \"Enter your password\" : \"Create a password\"}\r\n value={password}\r\n onChange={(event) => setPassword(event.target.value)}\r\n required\r\n minLength={8}\r\n />\r\n <button className={classNames?.button} style={styles.button} disabled={disabled} type=\"submit\">\r\n Continue\r\n </button>\r\n </form>\r\n );\r\n}\r\n\r\nfunction ProfileBlock({\r\n onSubmit,\r\n disabled,\r\n defaultValue,\r\n requireJobTitle,\r\n styles,\r\n classNames,\r\n}: BlockBaseProps & {\r\n onSubmit: (profile: AdaptiveContext[\"profile\"]) => void;\r\n defaultValue: AdaptiveContext[\"profile\"];\r\n requireJobTitle: boolean;\r\n}) {\r\n const [firstName, setFirstName] = React.useState(defaultValue.firstName ?? \"\");\r\n const [lastName, setLastName] = React.useState(defaultValue.lastName ?? \"\");\r\n const [jobTitle, setJobTitle] = React.useState(defaultValue.jobTitle ?? \"\");\r\n\r\n return (\r\n <form\r\n className={classNames?.formColumn}\r\n style={styles.formColumn}\r\n onSubmit={(event) => {\r\n event.preventDefault();\r\n onSubmit({\r\n firstName: firstName || null,\r\n lastName: lastName || null,\r\n jobTitle: jobTitle || null,\r\n });\r\n }}\r\n >\r\n <div className={classNames?.formRow} style={styles.formRow}>\r\n <input\r\n className={classNames?.input}\r\n style={styles.input}\r\n type=\"text\"\r\n autoComplete=\"given-name\"\r\n placeholder=\"First name\"\r\n value={firstName}\r\n onChange={(event) => setFirstName(event.target.value)}\r\n required\r\n />\r\n <input\r\n className={classNames?.input}\r\n style={styles.input}\r\n type=\"text\"\r\n autoComplete=\"family-name\"\r\n placeholder=\"Last name\"\r\n value={lastName}\r\n onChange={(event) => setLastName(event.target.value)}\r\n required\r\n />\r\n </div>\r\n {requireJobTitle ? (\r\n <input\r\n className={classNames?.input}\r\n style={styles.input}\r\n type=\"text\"\r\n autoComplete=\"organization-title\"\r\n placeholder=\"Job title\"\r\n value={jobTitle}\r\n onChange={(event) => setJobTitle(event.target.value)}\r\n required\r\n />\r\n ) : null}\r\n <button className={classNames?.button} style={styles.button} disabled={disabled} type=\"submit\">\r\n Continue\r\n </button>\r\n </form>\r\n );\r\n}\r\n\r\nfunction TosBlock({\r\n onSubmit,\r\n disabled,\r\n styles,\r\n classNames,\r\n}: BlockBaseProps & { onSubmit: () => void }) {\r\n const [checked, setChecked] = React.useState(false);\r\n return (\r\n <form\r\n className={classNames?.formColumn}\r\n style={styles.formColumn}\r\n onSubmit={(event) => {\r\n event.preventDefault();\r\n if (checked) {\r\n onSubmit();\r\n }\r\n }}\r\n >\r\n <label className={classNames?.checkboxRow} style={styles.checkboxRow}>\r\n <input type=\"checkbox\" checked={checked} onChange={(event) => setChecked(event.target.checked)} />\r\n <span>I agree to the Terms of Service and Privacy Policy.</span>\r\n </label>\r\n <button\r\n className={classNames?.button}\r\n style={styles.button}\r\n disabled={disabled || !checked}\r\n type=\"submit\"\r\n >\r\n Accept and Continue\r\n </button>\r\n </form>\r\n );\r\n}\r\n\r\nfunction CompleteBlock({\r\n styles,\r\n classNames,\r\n}: {\r\n styles: Record<AdaptiveFlowStyleSlot, React.CSSProperties | undefined>;\r\n classNames?: AdaptiveFlowClassNames;\r\n}) {\r\n return (\r\n <div className={classNames?.complete} style={styles.complete}>\r\n <strong>You are fully authenticated.</strong>\r\n <p className={classNames?.caption} style={styles.caption}>\r\n All requirements are complete.\r\n </p>\r\n </div>\r\n );\r\n}\r\n\r\nconst defaultStyles: Record<AdaptiveFlowStyleSlot, React.CSSProperties> = {\r\n shell: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: 12,\r\n width: \"100%\",\r\n maxWidth: 560,\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 14,\r\n padding: 16,\r\n background: \"#ffffff\",\r\n fontFamily: \"system-ui, -apple-system, Segoe UI, Roboto, sans-serif\",\r\n },\r\n headerRow: {\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n gap: 12,\r\n },\r\n eyebrow: {\r\n fontSize: 12,\r\n textTransform: \"uppercase\",\r\n letterSpacing: 1.2,\r\n color: \"#6b7280\",\r\n marginBottom: 4,\r\n },\r\n title: {\r\n margin: 0,\r\n fontSize: 22,\r\n lineHeight: \"28px\",\r\n },\r\n badge: {\r\n border: \"1px solid #d1d5db\",\r\n borderRadius: 999,\r\n padding: \"4px 10px\",\r\n fontSize: 12,\r\n fontWeight: 600,\r\n color: \"#374151\",\r\n },\r\n success: {\r\n border: \"1px solid #bbf7d0\",\r\n background: \"#f0fdf4\",\r\n color: \"#166534\",\r\n borderRadius: 10,\r\n padding: \"8px 10px\",\r\n fontSize: 14,\r\n },\r\n error: {\r\n border: \"1px solid #fecaca\",\r\n background: \"#fef2f2\",\r\n color: \"#991b1b\",\r\n borderRadius: 10,\r\n padding: \"8px 10px\",\r\n fontSize: 14,\r\n },\r\n info: {\r\n border: \"1px solid #bfdbfe\",\r\n background: \"#eff6ff\",\r\n color: \"#1e3a8a\",\r\n borderRadius: 10,\r\n padding: \"8px 10px\",\r\n fontSize: 14,\r\n },\r\n caption: {\r\n margin: 0,\r\n color: \"#4b5563\",\r\n fontSize: 14,\r\n },\r\n formRow: {\r\n display: \"flex\",\r\n gap: 8,\r\n alignItems: \"center\",\r\n },\r\n formColumn: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: 10,\r\n },\r\n input: {\r\n width: \"100%\",\r\n border: \"1px solid #d1d5db\",\r\n borderRadius: 8,\r\n height: 40,\r\n padding: \"0 12px\",\r\n fontSize: 14,\r\n },\r\n button: {\r\n border: \"1px solid #d1d5db\",\r\n borderRadius: 8,\r\n height: 40,\r\n padding: \"0 14px\",\r\n fontWeight: 600,\r\n background: \"#ffffff\",\r\n whiteSpace: \"nowrap\",\r\n cursor: \"pointer\",\r\n },\r\n checkboxRow: {\r\n display: \"flex\",\r\n gap: 8,\r\n alignItems: \"flex-start\",\r\n fontSize: 14,\r\n color: \"#374151\",\r\n },\r\n complete: {\r\n border: \"1px solid #bbf7d0\",\r\n background: \"#f0fdf4\",\r\n color: \"#166534\",\r\n borderRadius: 12,\r\n padding: 12,\r\n },\r\n footer: {\r\n display: \"flex\",\r\n gap: 8,\r\n marginTop: 4,\r\n },\r\n oauthButton: {\r\n flex: 1,\r\n border: \"1px solid #d1d5db\",\r\n borderRadius: 8,\r\n padding: \"10px 12px\",\r\n background: \"#f9fafb\",\r\n cursor: \"pointer\",\r\n },\r\n};\r\n","export const DefaultAppRequirements = {\r\n HAS_EMAIL: \"has_email\",\r\n EMAIL_VERIFIED: \"email_verified\",\r\n HAS_PASSWORD: \"has_password\",\r\n HAS_FIRST_NAME: \"has_first_name\",\r\n HAS_LAST_NAME: \"has_last_name\",\r\n ACCEPTED_TOS: \"accepted_tos\",\r\n HAS_JOB_TITLE: \"has_job_title\",\r\n} as const;\r\n\r\nexport const DefaultAdaptiveSteps = {\r\n COLLECT_EMAIL: \"COLLECT_EMAIL\",\r\n VERIFY_OTP: \"VERIFY_OTP\",\r\n COLLECT_PASSWORD: \"COLLECT_PASSWORD\",\r\n COLLECT_PROFILE: \"COLLECT_PROFILE\",\r\n COLLECT_TOS: \"COLLECT_TOS\",\r\n COMPLETE: \"COMPLETE\",\r\n} as const;\r\n\r\nexport type DefaultAppRequirement = (typeof DefaultAppRequirements)[keyof typeof DefaultAppRequirements];\r\nexport type DefaultAdaptiveStep = (typeof DefaultAdaptiveSteps)[keyof typeof DefaultAdaptiveSteps];\r\n\r\nexport type AppRequirement = DefaultAppRequirement | (string & {});\r\nexport type AdaptiveStep = DefaultAdaptiveStep | (string & {});\r\n\r\nexport type AdaptiveContextBase = {\r\n email: string | null;\r\n isVerified: boolean;\r\n hasPassword: boolean;\r\n profile: {\r\n firstName: string | null;\r\n lastName: string | null;\r\n jobTitle: string | null;\r\n };\r\n agreedToTos: boolean;\r\n};\r\n\r\nexport type AdaptiveContext = AdaptiveContextBase;\r\n\r\nexport const defaultRequirements: DefaultAppRequirement[] = [\r\n DefaultAppRequirements.HAS_EMAIL,\r\n DefaultAppRequirements.EMAIL_VERIFIED,\r\n DefaultAppRequirements.HAS_PASSWORD,\r\n DefaultAppRequirements.HAS_FIRST_NAME,\r\n DefaultAppRequirements.ACCEPTED_TOS,\r\n];\r\n\r\nexport const initialContext: AdaptiveContextBase = {\r\n email: null,\r\n isVerified: false,\r\n hasPassword: false,\r\n profile: {\r\n firstName: null,\r\n lastName: null,\r\n jobTitle: null,\r\n },\r\n agreedToTos: false,\r\n};\r\n\r\nexport type MaybePromise<T> = T | Promise<T>;\r\n\r\nexport type RequirementResolver<\r\n TContext = AdaptiveContextBase,\r\n TStep extends string = AdaptiveStep,\r\n> = {\r\n isMet: (context: TContext) => MaybePromise<boolean>;\r\n step: TStep;\r\n};\r\n\r\nexport type RequirementGraphNode<\r\n TContext,\r\n TRequirement extends string,\r\n TStep extends string,\r\n> = {\r\n requirement: TRequirement;\r\n step: TStep;\r\n isMet: (context: TContext) => MaybePromise<boolean>;\r\n when?: (context: TContext) => MaybePromise<boolean>;\r\n priority?: number;\r\n dependsOn?: readonly TRequirement[];\r\n};\r\n\r\nexport type RequirementGraph<\r\n TContext,\r\n TRequirement extends string,\r\n TStep extends string,\r\n> = readonly RequirementGraphNode<TContext, TRequirement, TStep>[];\r\n\r\nexport const defaultRequirementResolvers: Record<\r\n DefaultAppRequirement,\r\n RequirementResolver<AdaptiveContextBase, AdaptiveStep>\r\n> = {\r\n has_email: {\r\n isMet: (context) => Boolean(context.email),\r\n step: DefaultAdaptiveSteps.COLLECT_EMAIL,\r\n },\r\n email_verified: {\r\n isMet: (context) => context.isVerified,\r\n step: DefaultAdaptiveSteps.VERIFY_OTP,\r\n },\r\n has_password: {\r\n isMet: (context) => context.hasPassword,\r\n step: DefaultAdaptiveSteps.COLLECT_PASSWORD,\r\n },\r\n has_first_name: {\r\n isMet: (context) => Boolean(context.profile.firstName),\r\n step: DefaultAdaptiveSteps.COLLECT_PROFILE,\r\n },\r\n has_last_name: {\r\n isMet: (context) => Boolean(context.profile.lastName),\r\n step: DefaultAdaptiveSteps.COLLECT_PROFILE,\r\n },\r\n accepted_tos: {\r\n isMet: (context) => context.agreedToTos,\r\n step: DefaultAdaptiveSteps.COLLECT_TOS,\r\n },\r\n has_job_title: {\r\n isMet: (context) => Boolean(context.profile.jobTitle),\r\n step: DefaultAdaptiveSteps.COLLECT_PROFILE,\r\n },\r\n};\r\n\r\nexport function createRequirementGraph<\r\n TContext,\r\n TRequirement extends string,\r\n TStep extends string,\r\n>(\r\n requirements: readonly TRequirement[],\r\n resolvers: Partial<Record<TRequirement, RequirementResolver<TContext, TStep>>>,\r\n options?: {\r\n priorities?: Partial<Record<TRequirement, number>>;\r\n conditions?: Partial<Record<TRequirement, (context: TContext) => MaybePromise<boolean>>>;\r\n dependencies?: Partial<Record<TRequirement, readonly TRequirement[]>>;\r\n },\r\n): RequirementGraph<TContext, TRequirement, TStep> {\r\n const graph: RequirementGraphNode<TContext, TRequirement, TStep>[] = [];\r\n\r\n for (const requirement of requirements) {\r\n const resolver = resolvers[requirement];\r\n if (!resolver) {\r\n continue;\r\n }\r\n\r\n graph.push({\r\n requirement,\r\n step: resolver.step,\r\n isMet: resolver.isMet,\r\n when: options?.conditions?.[requirement],\r\n priority: options?.priorities?.[requirement] ?? 0,\r\n dependsOn: options?.dependencies?.[requirement] ?? [],\r\n });\r\n }\r\n\r\n return graph;\r\n}\r\n\r\nexport function createDefaultRequirementGraph<\r\n TContext extends AdaptiveContextBase = AdaptiveContextBase,\r\n TRequirement extends string = DefaultAppRequirement,\r\n TStep extends string = AdaptiveStep,\r\n>(\r\n options?: {\r\n requirements?: readonly TRequirement[];\r\n resolvers?: Partial<Record<TRequirement, RequirementResolver<TContext, TStep>>>;\r\n priorities?: Partial<Record<TRequirement, number>>;\r\n conditions?: Partial<Record<TRequirement, (context: TContext) => MaybePromise<boolean>>>;\r\n dependencies?: Partial<Record<TRequirement, readonly TRequirement[]>>;\r\n },\r\n): RequirementGraph<TContext, TRequirement, TStep> {\r\n const requirements =\r\n (options?.requirements ?? (defaultRequirements as unknown as readonly TRequirement[]));\r\n\r\n const resolvers = {\r\n ...(defaultRequirementResolvers as unknown as Partial<Record<TRequirement, RequirementResolver<TContext, TStep>>>),\r\n ...(options?.resolvers ?? {}),\r\n };\r\n\r\n return createRequirementGraph(requirements, resolvers, {\r\n priorities: options?.priorities,\r\n conditions: options?.conditions,\r\n dependencies: options?.dependencies,\r\n });\r\n}\r\n\r\nfunction sortGraph<\r\n TContext,\r\n TRequirement extends string,\r\n TStep extends string,\r\n>(graph: RequirementGraph<TContext, TRequirement, TStep>) {\r\n return [...graph].sort((left, right) => {\r\n const byPriority = (right.priority ?? 0) - (left.priority ?? 0);\r\n if (byPriority !== 0) {\r\n return byPriority;\r\n }\r\n\r\n return 0;\r\n });\r\n}\r\n\r\nexport async function evaluateNextStep<\r\n TContext,\r\n TRequirement extends string,\r\n TStep extends string,\r\n>(\r\n context: TContext,\r\n graph: RequirementGraph<TContext, TRequirement, TStep>,\r\n completeStep: TStep,\r\n): Promise<TStep> {\r\n for (const node of sortGraph(graph)) {\r\n if (node.when && !(await node.when(context))) {\r\n continue;\r\n }\r\n\r\n if (node.dependsOn && node.dependsOn.length > 0) {\r\n const prerequisiteNodes = graph.filter((candidate) =>\r\n node.dependsOn?.includes(candidate.requirement),\r\n );\r\n\r\n if (prerequisiteNodes.length > 0) {\r\n const prerequisitesMet = await Promise.all(\r\n prerequisiteNodes.map(async (candidate) => candidate.isMet(context)),\r\n );\r\n if (prerequisitesMet.includes(false)) {\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n if (!(await node.isMet(context))) {\r\n return node.step;\r\n }\r\n }\r\n\r\n return completeStep;\r\n}\r\n\r\nexport async function getMissingRequirements<\r\n TContext,\r\n TRequirement extends string,\r\n TStep extends string,\r\n>(\r\n context: TContext,\r\n graph: RequirementGraph<TContext, TRequirement, TStep>,\r\n): Promise<TRequirement[]> {\r\n const missing: TRequirement[] = [];\r\n\r\n for (const node of sortGraph(graph)) {\r\n if (node.when && !(await node.when(context))) {\r\n continue;\r\n }\r\n\r\n if (!(await node.isMet(context))) {\r\n missing.push(node.requirement);\r\n }\r\n }\r\n\r\n return missing;\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,YAAuB;;;ACFhB,IAAM,yBAAyB;AAAA,EACpC,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,eAAe;AACjB;AAEO,IAAM,uBAAuB;AAAA,EAClC,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,UAAU;AACZ;AAsBO,IAAM,sBAA+C;AAAA,EAC1D,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AACzB;AAEO,IAAM,iBAAsC;AAAA,EACjD,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,SAAS;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,aAAa;AACf;AA+BO,IAAM,8BAGT;AAAA,EACF,WAAW;AAAA,IACT,OAAO,CAAC,YAAY,QAAQ,QAAQ,KAAK;AAAA,IACzC,MAAM,qBAAqB;AAAA,EAC7B;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO,CAAC,YAAY,QAAQ;AAAA,IAC5B,MAAM,qBAAqB;AAAA,EAC7B;AAAA,EACA,cAAc;AAAA,IACZ,OAAO,CAAC,YAAY,QAAQ;AAAA,IAC5B,MAAM,qBAAqB;AAAA,EAC7B;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO,CAAC,YAAY,QAAQ,QAAQ,QAAQ,SAAS;AAAA,IACrD,MAAM,qBAAqB;AAAA,EAC7B;AAAA,EACA,eAAe;AAAA,IACb,OAAO,CAAC,YAAY,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,IACpD,MAAM,qBAAqB;AAAA,EAC7B;AAAA,EACA,cAAc;AAAA,IACZ,OAAO,CAAC,YAAY,QAAQ;AAAA,IAC5B,MAAM,qBAAqB;AAAA,EAC7B;AAAA,EACA,eAAe;AAAA,IACb,OAAO,CAAC,YAAY,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,IACpD,MAAM,qBAAqB;AAAA,EAC7B;AACF;AAEO,SAAS,uBAKd,cACA,WACA,SAKiD;AACjD,QAAM,QAA+D,CAAC;AAEtE,aAAW,eAAe,cAAc;AACtC,UAAM,WAAW,UAAU,WAAW;AACtC,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,MAAM,SAAS;AAAA,MACf,OAAO,SAAS;AAAA,MAChB,MAAM,SAAS,aAAa,WAAW;AAAA,MACvC,UAAU,SAAS,aAAa,WAAW,KAAK;AAAA,MAChD,WAAW,SAAS,eAAe,WAAW,KAAK,CAAC;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,8BAKd,SAOiD;AACjD,QAAM,eACH,SAAS,gBAAiB;AAE7B,QAAM,YAAY;AAAA,IAChB,GAAI;AAAA,IACJ,GAAI,SAAS,aAAa,CAAC;AAAA,EAC7B;AAEA,SAAO,uBAAuB,cAAc,WAAW;AAAA,IACrD,YAAY,SAAS;AAAA,IACrB,YAAY,SAAS;AAAA,IACrB,cAAc,SAAS;AAAA,EACzB,CAAC;AACH;AAEA,SAAS,UAIP,OAAwD;AACxD,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,MAAM,UAAU;AACtC,UAAM,cAAc,MAAM,YAAY,MAAM,KAAK,YAAY;AAC7D,QAAI,eAAe,GAAG;AACpB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,eAAsB,iBAKpB,SACA,OACA,cACgB;AAChB,aAAW,QAAQ,UAAU,KAAK,GAAG;AACnC,QAAI,KAAK,QAAQ,CAAE,MAAM,KAAK,KAAK,OAAO,GAAI;AAC5C;AAAA,IACF;AAEA,QAAI,KAAK,aAAa,KAAK,UAAU,SAAS,GAAG;AAC/C,YAAM,oBAAoB,MAAM;AAAA,QAAO,CAAC,cACtC,KAAK,WAAW,SAAS,UAAU,WAAW;AAAA,MAChD;AAEA,UAAI,kBAAkB,SAAS,GAAG;AAChC,cAAM,mBAAmB,MAAM,QAAQ;AAAA,UACrC,kBAAkB,IAAI,OAAO,cAAc,UAAU,MAAM,OAAO,CAAC;AAAA,QACrE;AACA,YAAI,iBAAiB,SAAS,KAAK,GAAG;AACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAE,MAAM,KAAK,MAAM,OAAO,GAAI;AAChC,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,uBAKpB,SACA,OACyB;AACzB,QAAM,UAA0B,CAAC;AAEjC,aAAW,QAAQ,UAAU,KAAK,GAAG;AACnC,QAAI,KAAK,QAAQ,CAAE,MAAM,KAAK,KAAK,OAAO,GAAI;AAC5C;AAAA,IACF;AAEA,QAAI,CAAE,MAAM,KAAK,MAAM,OAAO,GAAI;AAChC,cAAQ,KAAK,KAAK,WAAW;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AACT;;;ADgcI;AApgBJ,IAAM,mBAA2C;AAAA,EAC/C,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,IAAM,aAAsC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,aACP,SACA,OACU;AACV,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG,QAAQ;AAAA,MACX,GAAG,MAAM;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,aAAmD,cAA4C;AACtG,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,SAAO,aAAa,gBAA4B,YAAY;AAC9D;AAEA,SAAS,QAAQ,OAAuB;AACtC,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,EACT;AACA,SAAO,IAAI,MAAM,8CAA8C;AACjE;AAEA,SAAS,MAAM,OAAqE;AAClF,QAAM,QAAQ,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK;AACnD,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAEA,SAAS,YAAY,SAA6F;AAChH,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,WAAW,YAAY,WAAW;AACrC,WAAO,OAAO;AAAA,EAChB;AAEA,MAAI,YAAY,SAAS;AACvB,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO;AACT;AAEA,SAAS,mBACP,aAC6C;AAC7C,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,YAAY,YAAY,OAAO;AAC/C,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,QAAQ,QAAQ,YAAY,GAAG;AAC3C,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,YAAY,gBAAgB,CAAC,UAAkB,KAAK,MAAM,KAAK;AACnF,SAAO,YAAY,GAAG;AACxB;AAEA,SAAS,oBACP,aACA,OACM;AACN,MAAI,CAAC,aAAa;AAChB;AAAA,EACF;AAEA,QAAM,UAAU,YAAY,YAAY,OAAO;AAC/C,MAAI,CAAC,SAAS;AACZ;AAAA,EACF;AAEA,QAAM,YAAY,YAAY,cAAc,CAAC,UAAgD,KAAK,UAAU,KAAK;AACjH,UAAQ,QAAQ,YAAY,KAAK,UAAU,KAAK,CAAC;AACnD;AAEA,SAAS,oBACP,aACM;AACN,MAAI,CAAC,aAAa;AAChB;AAAA,EACF;AAEA,QAAM,UAAU,YAAY,YAAY,OAAO;AAC/C,MAAI,CAAC,SAAS;AACZ;AAAA,EACF;AAEA,UAAQ,WAAW,YAAY,GAAG;AACpC;AAEA,eAAe,YAAY,QAA+D;AACxF,QAAM,UAAU,MAAM;AACtB,MAAI,OAAO,YAAY,YAAY,QAAQ,KAAK,EAAE,SAAS,GAAG;AAC5D,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AACF;AAEA,SAAS,cACP,UACA,gBACgE;AAChE,QAAM,WAAW,CAAC;AAElB,aAAW,QAAQ,YAAY;AAC7B,QAAI,UAAU;AACZ,eAAS,IAAI,IAAI,iBAAiB,IAAI;AACtC;AAAA,IACF;AAEA,aAAS,IAAI,IAAI;AAAA,MACf,GAAG,cAAc,IAAI;AAAA,MACrB,GAAI,iBAAiB,IAAI,KAAK,CAAC;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,aAId;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AACF,GAAqD;AACnD,QAAM,yBAA+B;AAAA,IACnC,MAAO,gBAAiB;AAAA,IACxB,CAAC,YAAY;AAAA,EACf;AACA,QAAM,yBAA+B;AAAA,IACnC,MAAO,gBAAiB;AAAA,IACxB,CAAC,YAAY;AAAA,EACf;AACA,QAAM,YAAkB;AAAA,IACtB,OACG;AAAA,MACC,GAAI;AAAA,MAGJ,GAAI,wBAAwB,CAAC;AAAA,IAC/B;AAAA,IACF,CAAC,oBAAoB;AAAA,EACvB;AACA,QAAM,QAAc;AAAA,IAClB,MACE,oBACA,8BAA8B;AAAA,MAC5B,cAAc;AAAA,MACd;AAAA,MACA,YAAY,wBAAwB;AAAA,MACpC,YAAY,wBAAwB;AAAA,MACpC,cAAc,wBAAwB;AAAA,IACxC,CAAC;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,wBAAwB;AAAA,MACxB,wBAAwB;AAAA,MACxB,wBAAwB;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,WAAiB,cAAQ,MAAM,cAAc,UAAU,MAAM,GAAG,CAAC,UAAU,MAAM,CAAC;AAExF,QAAM,CAAC,SAAS,UAAU,IAAU,eAAmB,MAAM,aAAa,YAAY,CAAC;AACvF,QAAM,CAAC,MAAM,OAAO,IAAU,eAAgB,sBAAsB;AACpE,QAAM,CAAC,qBAAqB,sBAAsB,IAAU,eAAyB,CAAC,CAAC;AACvF,QAAM,CAAC,aAAa,cAAc,IAAU,eAA0C,CAAC,CAAC;AACxF,QAAM,CAAC,MAAM,OAAO,IAAU,eAAS,KAAK;AAC5C,QAAM,CAAC,SAAS,UAAU,IAAU,eAAwB,IAAI;AAChE,QAAM,CAAC,cAAc,eAAe,IAAU,eAAwB,IAAI;AAC1E,QAAM,CAAC,sBAAsB,uBAAuB,IAAU,eAA+B,IAAI;AACjG,QAAM,CAAC,qBAAqB,sBAAsB,IAAU,eAAS,CAAC,WAAW;AACjF,QAAM,mBAAyB,aAA+B,CAAC,CAAC;AAChE,QAAM,kBAAwB,aAAqB,IAAI;AACvD,QAAM,gBAAsB,aAAO,CAAC;AACpC,QAAM,YAAkB,aAAO,KAAK;AAEpC,EAAM,gBAAU,MAAM;AACpB,QAAI,CAAC,aAAa;AAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,YAAY,mBAAmB,WAAW;AAChD,UAAI,WAAW,SAAS;AACtB,mBAAW,aAAa,aAAa,YAAY,GAAG,UAAU,OAAO,CAAC;AAAA,MACxE;AACA,UAAI,WAAW,sBAAsB;AACnC,gCAAwB,UAAU,oBAAoB;AAAA,MACxD;AAAA,IACF,QAAQ;AAAA,IAER,UAAE;AACA,6BAAuB,IAAI;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,cAAc,WAAW,CAAC;AAE9B,EAAM,gBAAU,MAAM;AACpB,QAAI,cAAc;AAClB,UAAM,oBAAoB,EAAE,cAAc;AAE1C,UAAM,YAAY;AAChB,YAAM,CAACA,UAAS,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,QACxC,uBAAuB,SAAS,KAAwD;AAAA,QACxF,iBAAiB,SAAS,OAA0D,sBAAsB;AAAA,MAC5G,CAAC;AAED,UAAI,eAAe,sBAAsB,cAAc,SAAS;AAC9D;AAAA,MACF;AAEA,6BAAuBA,QAAO;AAC9B,cAAQ,IAAI;AAEZ,YAAM,OAAO,gBAAgB;AAC7B,YAAM,aAAa,OAAO,IAAI;AAC9B,YAAM,cAAc,SAAS,QAAQ,iBAAiB,QAAQ,UAAU,KAAK,KAAK,IAAI;AACtF,uBAAiB,QAAQ,UAAU,IAAI;AAEvC,YAAM,aAA4C;AAAA,QAChD;AAAA,QACA,IAAI;AAAA,QACJ,IAAI,KAAK,IAAI;AAAA,QACb,SAAS;AAAA,MACX;AAEA,qBAAe,CAAC,aAAa,CAAC,GAAG,UAAU,UAAU,EAAE,MAAM,IAAI,CAAC;AAClE,sBAAgB,UAAU;AAC1B,yBAAmB,YAAY,OAAO;AAAA,IACxC,GAAG,EAAE,MAAM,CAAC,UAAU;AACpB,UAAI,eAAe,sBAAsB,cAAc,SAAS;AAC9D;AAAA,MACF;AAEA,YAAM,aAAa,QAAQ,KAAK;AAChC,sBAAgB,WAAW,OAAO;AAClC,gBAAU,UAAU;AAAA,IACtB,CAAC;AAED,WAAO,MAAM;AACX,oBAAc;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,SAAS,OAAO,wBAAwB,SAAS,gBAAgB,CAAC;AAEtE,EAAM,gBAAU,MAAM;AACpB,QAAI,SAAS,wBAAwB;AACnC,UAAI,CAAC,UAAU,SAAS;AACtB,kBAAU,UAAU;AACpB,qBAAa,OAAO;AAEpB,cAAM,yBAAyB,aAAa,mBAAmB;AAC/D,YAAI,wBAAwB;AAC1B,8BAAoB,WAAW;AAAA,QACjC;AAAA,MACF;AAAA,IACF,OAAO;AACL,gBAAU,UAAU;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,SAAS,wBAAwB,YAAY,aAAa,IAAI,CAAC;AAEnE,EAAM,gBAAU,MAAM;AACpB,QAAI,CAAC,eAAe,CAAC,qBAAqB;AACxC;AAAA,IACF;AAEA,QAAI;AACF,0BAAoB,aAAa,EAAE,SAAS,qBAAqB,CAAC;AAAA,IACpE,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,SAAS,sBAAsB,aAAa,mBAAmB,CAAC;AAEpE,QAAM,MAAY;AAAA,IAChB,OAAO,QAA6B;AAClC,cAAQ,IAAI;AACZ,sBAAgB,IAAI;AACpB,UAAI;AACF,cAAM,IAAI;AAAA,MACZ,SAAS,OAAO;AACd,cAAM,aAAa,QAAQ,KAAK;AAChC,wBAAgB,WAAW,OAAO;AAClC,kBAAU,UAAU;AAAA,MACtB,UAAE;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,QAAM,eAAqB,kBAAY,CAAC,UAA6B;AACnE,eAAW,CAAC,SAAS,aAAa,MAAM,KAAK,CAAC;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAyB;AAAA,IAC7B,CAAC,UAAwC;AACvC,mBAAa,KAA0B;AAAA,IACzC;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,EAAM,gBAAU,MAAM;AACpB,UAAM,gBAAgB,SAAS;AAC/B,QAAI,CAAC,wBAAwB,CAAC,eAAe;AAC3C;AAAA,IACF;AAEA,SAAK,IAAI,YAAY;AACnB,YAAM,QAAQ,MAAM,cAAc,sBAAsB,OAAO;AAC/D,UAAI,OAAO;AACT,qBAAa,KAAK;AAAA,MACpB;AACA,8BAAwB,IAAI;AAC5B,iBAAW,0BAA0B;AAAA,IACvC,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,SAAS,sBAAsB,cAAc,GAAG,CAAC;AAE9D,QAAM,cAAc,CAAC,eAAuB;AAC1C,UAAM,QAAQ,WAAW,KAAK,EAAE,YAAY;AAC5C,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,SAAK,IAAI,YAAY;AACnB,UAAI,YAAY,OAAO;AACrB,cAAM,YAAY,WAAW,MAAM,OAAO,EAAE,QAAQ,CAAC,CAAC;AAAA,MACxD;AAEA,YAAM,WAAY,MAAM,SAAS,gBAAgB,KAAK,KAAM;AAE5D,uBAAiB;AAAA,QACf;AAAA,QACA,aAAa,QAAQ,UAAU,WAAW;AAAA,QAC1C,YAAY,QAAQ,UAAU,UAAU;AAAA,QACxC,aAAa,QAAQ,UAAU,WAAW;AAAA,QAC1C,SAAS;AAAA,UACP,WAAW,UAAU,SAAS,aAAa;AAAA,UAC3C,UAAU,UAAU,SAAS,YAAY;AAAA,UACzC,UAAU,UAAU,SAAS,YAAY;AAAA,QAC3C;AAAA,MACF,CAAC;AAED,UAAI,UAAU,iBAAiB,SAAS,aAAa;AACnD,mBAAW,gDAAgD;AAC3D;AAAA,MACF;AAEA,UAAI,SAAS,YAAY;AACvB,cAAM,QAAQ,WAAW,KAAK;AAC9B,mBAAW,uCAAuC;AAAA,MACpD,OAAO;AACL,yBAAiB,EAAE,YAAY,KAAK,CAAC;AACrC,mBAAW,4DAA4D;AAAA,MACzE;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,CAAC,SAAiB;AAClC,QAAI,CAAC,QAAQ,OAAO;AAClB;AAAA,IACF;AAEA,SAAK,IAAI,YAAY;AACnB,UAAI,YAAY,KAAK;AACnB,cAAM,YAAY,WAAW,IAAI,MAAM,EAAE,SAAS,OAAO,QAAQ,MAAgB,CAAC,CAAC;AAAA,MACrF;AAEA,UAAI,SAAS,WAAW;AACtB,cAAM,QAAQ,UAAU,QAAQ,OAAiB,IAAI;AAAA,MACvD;AACA,uBAAiB,EAAE,YAAY,KAAK,CAAC;AACrC,iBAAW,iBAAiB;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,QAAM,iBAAiB,CAAC,aAAqB;AAC3C,QAAI,CAAC,QAAQ,OAAO;AAClB;AAAA,IACF;AAEA,SAAK,IAAI,YAAY;AACnB,UAAI,YAAY,UAAU;AACxB,cAAM,YAAY,WAAW,SAAS,UAAU,EAAE,SAAS,aAAa,QAAQ,YAAY,CAAC,CAAC;AAAA,MAChG;AAEA,UAAI,QAAQ,aAAa;AACvB,YAAI,SAAS,oBAAoB;AAC/B,gBAAM,QAAQ,mBAAmB,QAAQ,OAAiB,QAAQ;AAAA,QACpE;AAAA,MACF,OAAO;AACL,YAAI,SAAS,gBAAgB;AAC3B,gBAAM,QAAQ,eAAe,QAAQ;AAAA,QACvC;AACA,yBAAiB,EAAE,aAAa,KAAK,CAAC;AAAA,MACxC;AACA,iBAAW,yBAAyB;AAAA,IACtC,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB,CAAC,YAA4C;AACjE,SAAK,IAAI,YAAY;AACnB,UAAI,YAAY,SAAS;AACvB,cAAM,YAAY,WAAW,QAAQ,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,MAC5D;AAEA,YAAM,OAAO,aAAa,SAAS;AAAA,QACjC,SAAS;AAAA,UACP,WAAW,QAAQ,aAAa;AAAA,UAChC,UAAU,QAAQ,YAAY;AAAA,UAC9B,UAAU,QAAQ,YAAY;AAAA,QAChC;AAAA,MACF,CAAsB;AAEtB,UAAI,SAAS,aAAa;AACxB,cAAM,QAAQ,YAAY,IAAI;AAAA,MAChC;AAEA,mBAAa,EAAE,SAAS,KAAK,QAAQ,CAAsB;AAC3D,iBAAW,gBAAgB;AAAA,IAC7B,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,MAAM;AACtB,SAAK,IAAI,YAAY;AACnB,UAAI,YAAY,KAAK;AACnB,cAAM,YAAY,WAAW,IAAI,MAAM,EAAE,QAAQ,CAAC,CAAC;AAAA,MACrD;AAEA,YAAM,OAAO,aAAa,SAAS,EAAE,aAAa,KAAK,CAAsB;AAC7E,UAAI,SAAS,WAAW;AACtB,cAAM,QAAQ,UAAU,IAAI;AAAA,MAC9B;AACA,uBAAiB,EAAE,aAAa,KAAK,CAAC;AACtC,iBAAW,iBAAiB;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,CAAC,aAA4B;AAC/C,UAAM,aAAa,SAAS;AAC5B,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,SAAK,IAAI,YAAY;AACnB,8BAAwB,QAAQ;AAChC,iBAAW,YAAY,QAAQ,aAAa;AAC5C,YAAM,WAAW,UAAU,OAAO;AAAA,IACpC,CAAC;AAAA,EACH;AAEA,QAAM,UAAU;AAChB,QAAM,gBAAgB,uBAAuB,SAAS,eAA+B;AACrF,QAAM,YAAY,aAAa,IAAI,KAAK,iBAAiB,IAAI,KAAK;AAElE,QAAM,cACJ,4EACG;AAAA,aAAS,kBACR;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR;AAAA;AAAA,IACF,IACE;AAAA,IACH,SAAS,eACR;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,OAAO,QAAQ,SAAS;AAAA,QACxB,UAAU;AAAA,QACV,QAAQ;AAAA,QACR;AAAA;AAAA,IACF,IACE;AAAA,IACH,SAAS,qBACR;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,UAAU;AAAA,QACV,aAAa,QAAQ;AAAA,QACrB,QAAQ;AAAA,QACR;AAAA;AAAA,IACF,IACE;AAAA,IACH,SAAS,oBACR;AAAA,MAAC;AAAA;AAAA,QACC,cAAc,QAAQ;AAAA,QACtB,iBAAiB;AAAA,QACjB,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR;AAAA;AAAA,IACF,IACE;AAAA,IACH,SAAS,gBACR;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR;AAAA;AAAA,IACF,IACE;AAAA,IACH,SAAS,yBACR,4CAAC,iBAAc,QAAQ,UAAU,YAAwB,IACvD;AAAA,IACH,SAAS,mBACV,SAAS,gBACT,SAAS,sBACT,SAAS,qBACT,SAAS,iBACT,SAAS,yBACP,6CAAC,SAAI,WAAW,YAAY,MAAM,OAAO,SAAS,MAAM;AAAA;AAAA,MACvB;AAAA,MAAK;AAAA,OACtC,IACE;AAAA,KACN;AAGF,QAAM,aAAa,aACf,WAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,IACrB,cAAc;AAAA,IACd;AAAA,IACA,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,IACD;AACJ,QAAM,eAAe,eAAe,IAAI,IACpC,aAAa,IAAI,IAAI;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,IACrB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,IACD;AAEJ,SACE,6CAAC,SAAI,WAAW,GAAG,WAAW,YAAY,KAAK,GAAG,OAAO,SAAS,OAChE;AAAA,iDAAC,SAAI,WAAW,YAAY,WAAW,OAAO,SAAS,WACrD;AAAA,mDAAC,SACC;AAAA,oDAAC,SAAI,WAAW,YAAY,SAAS,OAAO,SAAS,SAAS,2BAE9D;AAAA,QACA,4CAAC,QAAG,WAAW,YAAY,OAAO,OAAO,SAAS,OAC/C,qBACH;AAAA,SACF;AAAA,MACA,6CAAC,SAAI,WAAW,YAAY,OAAO,OAAO,SAAS,OAChD;AAAA,+BAAuB,SAAS,QAAQ;AAAA,QAAO;AAAA,QAAE,uBAAuB;AAAA,SAC3E;AAAA,OACF;AAAA,IAEC,UACC,4CAAC,SAAI,WAAW,YAAY,SAAS,OAAO,SAAS,SAClD,mBACH,IACE;AAAA,IACH,eACC,4CAAC,SAAI,WAAW,YAAY,OAAO,OAAO,SAAS,OAChD,wBACH,IACE;AAAA,IAEH,cAAc,gBAAgB;AAAA,IAE/B,6CAAC,SAAI,WAAW,YAAY,QAAQ,OAAO,SAAS,QAClD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW,YAAY;AAAA,UACvB,OAAO,SAAS;AAAA,UAChB,UAAU,QAAQ,CAAC,SAAS;AAAA,UAC5B,SAAS,MAAM;AACb,wBAAY,QAAQ;AAAA,UACtB;AAAA,UACD;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW,YAAY;AAAA,UACvB,OAAO,SAAS;AAAA,UAChB,UAAU,QAAQ,CAAC,SAAS;AAAA,UAC5B,SAAS,MAAM;AACb,wBAAY,OAAO;AAAA,UACrB;AAAA,UACD;AAAA;AAAA,MAED;AAAA,OACF;AAAA,KACF;AAEJ;AAQA,SAAS,WAAW,EAAE,UAAU,UAAU,QAAQ,WAAW,GAA2D;AACtH,QAAM,CAAC,OAAO,QAAQ,IAAU,eAAS,EAAE;AAC3C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,YAAY;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,UAAU,CAAC,UAAU;AACnB,cAAM,eAAe;AACrB,iBAAS,KAAK;AAAA,MAChB;AAAA,MAEA;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,YAAY;AAAA,YACvB,OAAO,OAAO;AAAA,YACd,MAAK;AAAA,YACL,cAAa;AAAA,YACb,aAAY;AAAA,YACZ,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,YAChD,UAAQ;AAAA;AAAA,QACV;AAAA,QACA,4CAAC,YAAO,WAAW,YAAY,QAAQ,OAAO,OAAO,QAAQ,UAAoB,MAAK,UAAS,sBAE/F;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyE;AACvE,QAAM,CAAC,MAAM,OAAO,IAAU,eAAS,EAAE;AACzC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,YAAY;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,UAAU,CAAC,UAAU;AACnB,cAAM,eAAe;AACrB,iBAAS,IAAI;AAAA,MACf;AAAA,MAEA;AAAA,qDAAC,OAAE,WAAW,YAAY,SAAS,OAAO,OAAO,SAAS;AAAA;AAAA,UACrB;AAAA,UAAM;AAAA,WAC3C;AAAA,QACA,6CAAC,SAAI,WAAW,YAAY,SAAS,OAAO,OAAO,SACjD;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,YAAY;AAAA,cACvB,OAAO,OAAO;AAAA,cACd,WAAU;AAAA,cACV,aAAY;AAAA,cACZ,OAAO;AAAA,cACP,UAAU,CAAC,UAAU,QAAQ,MAAM,OAAO,MAAM,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,cAC9E,UAAQ;AAAA,cACR,WAAW;AAAA,cACX,SAAQ;AAAA;AAAA,UACV;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,YAAY;AAAA,cACvB,OAAO,OAAO;AAAA,cACd,UAAU,YAAY,KAAK,WAAW;AAAA,cACtC,MAAK;AAAA,cACN;AAAA;AAAA,UAED;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoF;AAClF,QAAM,CAAC,UAAU,WAAW,IAAU,eAAS,EAAE;AACjD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,YAAY;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,UAAU,CAAC,UAAU;AACnB,cAAM,eAAe;AACrB,iBAAS,QAAQ;AAAA,MACnB;AAAA,MAEA;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,YAAY;AAAA,YACvB,OAAO,OAAO;AAAA,YACd,MAAK;AAAA,YACL,cAAc,cAAc,qBAAqB;AAAA,YACjD,aAAa,cAAc,wBAAwB;AAAA,YACnD,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,YAAY,MAAM,OAAO,KAAK;AAAA,YACnD,UAAQ;AAAA,YACR,WAAW;AAAA;AAAA,QACb;AAAA,QACA,4CAAC,YAAO,WAAW,YAAY,QAAQ,OAAO,OAAO,QAAQ,UAAoB,MAAK,UAAS,sBAE/F;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,WAAW,YAAY,IAAU,eAAS,aAAa,aAAa,EAAE;AAC7E,QAAM,CAAC,UAAU,WAAW,IAAU,eAAS,aAAa,YAAY,EAAE;AAC1E,QAAM,CAAC,UAAU,WAAW,IAAU,eAAS,aAAa,YAAY,EAAE;AAE1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,YAAY;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,UAAU,CAAC,UAAU;AACnB,cAAM,eAAe;AACrB,iBAAS;AAAA,UACP,WAAW,aAAa;AAAA,UACxB,UAAU,YAAY;AAAA,UACtB,UAAU,YAAY;AAAA,QACxB,CAAC;AAAA,MACH;AAAA,MAEA;AAAA,qDAAC,SAAI,WAAW,YAAY,SAAS,OAAO,OAAO,SACjD;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,YAAY;AAAA,cACvB,OAAO,OAAO;AAAA,cACd,MAAK;AAAA,cACL,cAAa;AAAA,cACb,aAAY;AAAA,cACZ,OAAO;AAAA,cACP,UAAU,CAAC,UAAU,aAAa,MAAM,OAAO,KAAK;AAAA,cACpD,UAAQ;AAAA;AAAA,UACV;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,YAAY;AAAA,cACvB,OAAO,OAAO;AAAA,cACd,MAAK;AAAA,cACL,cAAa;AAAA,cACb,aAAY;AAAA,cACZ,OAAO;AAAA,cACP,UAAU,CAAC,UAAU,YAAY,MAAM,OAAO,KAAK;AAAA,cACnD,UAAQ;AAAA;AAAA,UACV;AAAA,WACF;AAAA,QACC,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,YAAY;AAAA,YACvB,OAAO,OAAO;AAAA,YACd,MAAK;AAAA,YACL,cAAa;AAAA,YACb,aAAY;AAAA,YACZ,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,YAAY,MAAM,OAAO,KAAK;AAAA,YACnD,UAAQ;AAAA;AAAA,QACV,IACE;AAAA,QACJ,4CAAC,YAAO,WAAW,YAAY,QAAQ,OAAO,OAAO,QAAQ,UAAoB,MAAK,UAAS,sBAE/F;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8C;AAC5C,QAAM,CAAC,SAAS,UAAU,IAAU,eAAS,KAAK;AAClD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,YAAY;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,UAAU,CAAC,UAAU;AACnB,cAAM,eAAe;AACrB,YAAI,SAAS;AACX,mBAAS;AAAA,QACX;AAAA,MACF;AAAA,MAEA;AAAA,qDAAC,WAAM,WAAW,YAAY,aAAa,OAAO,OAAO,aACvD;AAAA,sDAAC,WAAM,MAAK,YAAW,SAAkB,UAAU,CAAC,UAAU,WAAW,MAAM,OAAO,OAAO,GAAG;AAAA,UAChG,4CAAC,UAAK,iEAAmD;AAAA,WAC3D;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,YAAY;AAAA,YACvB,OAAO,OAAO;AAAA,YACd,UAAU,YAAY,CAAC;AAAA,YACvB,MAAK;AAAA,YACN;AAAA;AAAA,QAED;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AACF,GAGG;AACD,SACE,6CAAC,SAAI,WAAW,YAAY,UAAU,OAAO,OAAO,UAClD;AAAA,gDAAC,YAAO,0CAA4B;AAAA,IACpC,4CAAC,OAAE,WAAW,YAAY,SAAS,OAAO,OAAO,SAAS,4CAE1D;AAAA,KACF;AAEJ;AAEA,IAAM,gBAAoE;AAAA,EACxE,OAAO;AAAA,IACL,SAAS;AAAA,IACT,eAAe;AAAA,IACf,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,WAAW;AAAA,IACT,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,KAAK;AAAA,EACP;AAAA,EACA,SAAS;AAAA,IACP,UAAU;AAAA,IACV,eAAe;AAAA,IACf,eAAe;AAAA,IACf,OAAO;AAAA,IACP,cAAc;AAAA,EAChB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,cAAc;AAAA,IACd,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,cAAc;AAAA,IACd,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,cAAc;AAAA,IACd,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AAAA,EACA,YAAY;AAAA,IACV,SAAS;AAAA,IACT,eAAe;AAAA,IACf,KAAK;AAAA,EACP;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,aAAa;AAAA,IACX,SAAS;AAAA,IACT,KAAK;AAAA,IACL,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AAAA,EACA,UAAU;AAAA,IACR,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,cAAc;AAAA,IACd,SAAS;AAAA,EACX;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,WAAW;AAAA,EACb;AAAA,EACA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AACF;","names":["missing"]}