import { html as n, attr as o } from "@tempots/dom";
const r = {
  /**
   * Creates a loading state.
   * @param previousValue - The previous value.
   * @returns A loading state.
   * @public
   */
  notAsked: { type: "NotAsked" },
  /**
   * Creates a loading state.
   * @param previousValue - The previous value.
   * @returns A loading state.
   * @public
   */
  loading(s = void 0) {
    return { type: "Loading", previousValue: s };
  },
  /**
   * Creates a successful state.
   * @param value - The value.
   * @returns A successful state.
   * @public
   */
  success(s) {
    return { type: "AsyncSuccess", value: s };
  },
  /**
   * Creates a failure state.
   * @param error - The error.
   * @returns A failure state.
   * @public
   */
  failure(s) {
    return { type: "AsyncFailure", error: s };
  },
  /**
   * Checks if the result is a success.
   * @param r - The result.
   * @returns `true` if the result is a success; otherwise, `false`.
   * @public
   */
  isSuccess(s) {
    return s.type === "AsyncSuccess";
  },
  /**
   * Checks if the result is a failure.
   * @param r - The result.
   * @returns `true` if the result is a failure; otherwise, `false`.
   * @public
   */
  isFailure(s) {
    return s.type === "AsyncFailure";
  },
  /**
   * Checks if the result is a not-asked.
   * @param r - The result.
   * @returns `true` if the result is not-asked; otherwise, `false`.
   * @public
   */
  isNotAsked(s) {
    return s.type === "NotAsked";
  },
  /**
   * Checks if the result is a loading.
   * @param r - The result.
   * @returns `true` if the result is loading; otherwise, `false`.
   * @public
   */
  isLoading(s) {
    return s.type === "Loading";
  },
  /**
   * Gets the value if the result is a success; otherwise, returns the alternative value.
   * @param r - The result.
   * @param alt - The alternative value.
   * @returns The value if the result is a success; otherwise, the alternative value.
   * @public
   */
  getOrElse(s, e) {
    return r.isSuccess(s) ? s.value : e;
  },
  /**
   * Gets the value if the result is a success; otherwise, returns the value from the alternative function.
   * @param r - The result.
   * @param altf - The alternative function.
   * @returns The value if the result is a success; otherwise, the value from the alternative
   * @public
   * function.
   */
  getOrElseLazy(s, e) {
    return r.isSuccess(s) ? s.value : e();
  },
  /**
   * Gets the value if the result is a success; otherwise, returns `null`.
   * @param r - The result.
   * @returns The value if the result is a success; otherwise, `null`.
   * @public
   */
  getOrNull(s) {
    return r.isSuccess(s) ? s.value : null;
  },
  /**
   * Gets the value if the result is a success; otherwise, returns `undefined`.
   * @param r - The result.
   * @returns The value if the result is a success; otherwise, `undefined`.
   * @public
   */
  getOrUndefined(s) {
    return r.isSuccess(s) ? s.value : void 0;
  },
  /**
   * Gets the value of a `AsyncResult` if it is a `Success`, otherwise it throws the error contained in the `Failure`.
   * @param r - The `AsyncResult` to get the value from.
   * @returns The value of the `AsyncResult` if it is a `Success`.
   */
  getUnsafe: (s) => {
    if (r.isSuccess(s))
      return s.value;
    throw r.isFailure(s) ? s.error : new Error("Cannot get value from a not-asked or loading result");
  },
  /**
   * Based on the state of the result, it picks the appropriate function to call and returns the result.
   * @param success - The function to call if the result is a success.
   * @param failure - The function to call if the result is a failure.
   * @param loading - The function to call if the result is loading.
   * @param notAsked - The function to call if the result is not-asked.
   * @returns The result of calling the appropriate function based on the state of the result.
   * @public
   */
  match: (s, {
    success: e,
    failure: u,
    loading: i,
    notAsked: l = i
  }) => r.isSuccess(s) ? e(s.value) : r.isFailure(s) ? u(s.error) : r.isNotAsked(s) ? l() : i(s.previousValue),
  /**
   * Executes side effects based on the state of the result.
   * Unlike `match`, all handlers are optional, allowing you to react only to specific states.
   * The `else` handler is called when no specific handler is provided for the current state.
   * @param r - The result.
   * @param handlers - An object with optional handlers for each state and an optional `else` fallback.
   * @returns The result that was passed in, allowing for chaining.
   * @public
   */
  effect: (s, e) => {
    switch (s.type) {
      case "AsyncSuccess":
        e.success ? e.success(s.value) : e.else?.();
        break;
      case "AsyncFailure":
        e.failure ? e.failure(s.error) : e.else?.();
        break;
      case "Loading":
        e.loading ? e.loading(s.previousValue) : e.else?.();
        break;
      case "NotAsked":
        e.notAsked ? e.notAsked() : e.else?.();
        break;
    }
    return s;
  },
  /**
   * When the result is a success, it applies the function to the value.
   *
   * @param r - The result.
   * @param apply - The function to apply.
   * @returns The result that was passed in.
   * @public
   */
  whenSuccess: (s, e) => (r.isSuccess(s) && e(s.value), s),
  /**
   * When the result is a failure, it applies the function to the error.
   *
   * @param r - The result.
   * @param apply - The function to apply.
   * @returns The result that was passed in.
   * @public
   */
  whenFailure: (s, e) => (r.isFailure(s) && e(s.error), s),
  /**
   * Compares two results for equality.
   * @param r1 - The first result.
   * @param r2 - The second result.
   * @param options - The options to use for comparison. By default, uses strict equality.
   * @returns `true` if the results are equal, `false` otherwise.
   */
  equals: (s, e, u = {
    valueEquals: (i, l) => i === l,
    errorEquals: (i, l) => i === l
  }) => s.type === "AsyncSuccess" && e.type === "AsyncSuccess" ? u.valueEquals(s.value, e.value) : s.type === "AsyncFailure" && e.type === "AsyncFailure" ? u.errorEquals(s.error, e.error) : s.type === "Loading" && e.type === "Loading" ? u.valueEquals(s.previousValue, e.previousValue) : s.type === "NotAsked" && e.type === "NotAsked",
  /**
   * Combines multiple results into a single result.
   * @param results - The results to combine.
   * @returns A single result that is a success if all the input results are successes, otherwise a failure.
   */
  all: (s) => {
    const e = [];
    for (const u of s)
      if (r.isSuccess(u))
        e.push(u.value);
      else
        return u;
    return r.success(e);
  },
  /**
   * Converts a Promise to an AsyncResult.
   * @param p - The Promise to convert.
   * @returns A Promise that resolves to an AsyncResult.
   */
  ofPromise: async (s) => {
    try {
      const e = await s;
      return r.success(e);
    } catch (e) {
      return r.failure(e instanceof Error ? e : new Error(String(e)));
    }
  },
  /**
   * Maps the value of a successful `AsyncResult` to a new value using the provided function.
   * For other states (NotAsked, Loading, Failure), the state is preserved.
   * When mapping a Loading state with a previous value, the previous value is also mapped.
   * @param result - The `AsyncResult` to map.
   * @param fn - The mapping function to apply to the success value.
   * @returns A new `AsyncResult` with the mapped value if successful, otherwise the original state.
   * @public
   */
  map: (s, e) => {
    switch (s.type) {
      case "AsyncSuccess":
        return r.success(e(s.value));
      case "NotAsked":
        return r.notAsked;
      case "AsyncFailure":
        return r.failure(s.error);
      case "Loading":
        return r.loading(
          s.previousValue != null ? e(s.previousValue) : void 0
        );
    }
  },
  /**
   * Maps the value of a successful `AsyncResult` to a new `AsyncResult` using the provided function.
   * This is useful for chaining operations that may also fail.
   * @param result - The `AsyncResult` to flat map.
   * @param fn - The mapping function that returns a new `AsyncResult`.
   * @returns The result of the mapping function if successful, otherwise the original state.
   * @public
   */
  flatMap: (s, e) => {
    switch (s.type) {
      case "AsyncSuccess":
        return e(s.value);
      case "NotAsked":
        return r.notAsked;
      case "AsyncFailure":
        return r.failure(s.error);
      case "Loading":
        return r.loading();
    }
  },
  /**
   * Maps the error of a failed `AsyncResult` to a new error using the provided function.
   * For other states, the state is preserved.
   * @param result - The `AsyncResult` to map the error of.
   * @param fn - The mapping function to apply to the error.
   * @returns A new `AsyncResult` with the mapped error if failed, otherwise the original state.
   * @public
   */
  mapError: (s, e) => {
    switch (s.type) {
      case "AsyncSuccess":
        return r.success(s.value);
      case "NotAsked":
        return r.notAsked;
      case "AsyncFailure":
        return r.failure(e(s.error));
      case "Loading":
        return r.loading(s.previousValue);
    }
  },
  /**
   * Maps the error of a failed `AsyncResult` to a new `AsyncResult` using the provided function.
   * This allows recovery from errors by returning a new successful result.
   * @param result - The `AsyncResult` to recover from.
   * @param fn - The recovery function that returns a new `AsyncResult`.
   * @returns The result of the recovery function if failed, otherwise the original state.
   * @public
   */
  flatMapError: (s, e) => {
    switch (s.type) {
      case "AsyncSuccess":
        return r.success(s.value);
      case "NotAsked":
        return r.notAsked;
      case "AsyncFailure":
        return e(s.error);
      case "Loading":
        return r.loading(s.previousValue);
    }
  },
  /**
   * Converts an `AsyncResult` to a `Result`, discarding the loading and not-asked states.
   * Returns `undefined` if the result is not settled (i.e., NotAsked or Loading).
   * @param result - The `AsyncResult` to convert.
   * @returns A `Result` if the `AsyncResult` is settled, otherwise `undefined`.
   * @public
   */
  toResult: (s) => {
    switch (s.type) {
      case "AsyncSuccess":
        return { type: "Success", value: s.value };
      case "AsyncFailure":
        return { type: "Failure", error: s.error };
      case "NotAsked":
      case "Loading":
        return;
    }
  },
  /**
   * Checks if the result is settled (either success or failure).
   * @param r - The result.
   * @returns `true` if the result is settled; otherwise, `false`.
   * @public
   */
  isSettled(s) {
    return s.type === "AsyncSuccess" || s.type === "AsyncFailure";
  },
  /**
   * Recovers from a failure by providing an alternative value.
   * @param result - The `AsyncResult` to recover from.
   * @param fn - The function that provides an alternative value given the error.
   * @returns A successful `AsyncResult` with the alternative value if failed, otherwise the original state.
   * @public
   */
  recover: (s, e) => {
    switch (s.type) {
      case "AsyncSuccess":
        return r.success(s.value);
      case "NotAsked":
        return r.notAsked;
      case "AsyncFailure":
        return r.success(e(s.error));
      case "Loading":
        return r.loading(s.previousValue);
    }
  },
  /**
   * Applies a function wrapped in an `AsyncResult` to a value wrapped in an `AsyncResult`.
   * Useful for applying multiple arguments to a function in a safe way.
   * @param resultFn - The `AsyncResult` containing the function.
   * @param resultVal - The `AsyncResult` containing the value.
   * @returns A new `AsyncResult` with the result of applying the function to the value.
   * @public
   */
  ap: (s, e) => r.isSuccess(s) && r.isSuccess(e) ? r.success(s.value(e.value)) : r.isFailure(s) ? r.failure(s.error) : r.isFailure(e) ? r.failure(e.error) : r.isLoading(s) || r.isLoading(e) ? r.loading() : r.notAsked,
  /**
   * Maps two `AsyncResult` values using a function.
   * @param r1 - The first `AsyncResult`.
   * @param r2 - The second `AsyncResult`.
   * @param fn - The function to apply to both values.
   * @returns A new `AsyncResult` with the result of applying the function to both values.
   * @public
   */
  map2: (s, e, u) => r.isSuccess(s) && r.isSuccess(e) ? r.success(u(s.value, e.value)) : r.isFailure(s) ? r.failure(s.error) : r.isFailure(e) ? r.failure(e.error) : r.isLoading(s) || r.isLoading(e) ? r.loading() : r.notAsked,
  /**
   * Maps three `AsyncResult` values using a function.
   * @param r1 - The first `AsyncResult`.
   * @param r2 - The second `AsyncResult`.
   * @param r3 - The third `AsyncResult`.
   * @param fn - The function to apply to all three values.
   * @returns A new `AsyncResult` with the result of applying the function to all three values.
   * @public
   */
  map3: (s, e, u, i) => r.isSuccess(s) && r.isSuccess(e) && r.isSuccess(u) ? r.success(i(s.value, e.value, u.value)) : r.isFailure(s) ? r.failure(s.error) : r.isFailure(e) ? r.failure(e.error) : r.isFailure(u) ? r.failure(u.error) : r.isLoading(s) || r.isLoading(e) || r.isLoading(u) ? r.loading() : r.notAsked
}, c = {
  /**
   * Creates a valid `Validation`.
   * @returns A `Validation` that is `Valid`.
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  valid: { type: "valid" },
  /**
   * Creates an invalid `Validation`.
   * @param error - The error associated with the invalid value.
   * @returns A `Validation` that is `Invalid`.
   */
  invalid(s) {
    return { type: "invalid", error: s };
  },
  /**
   * Checks if a `Validation` is `Valid`.
   * @param r - The `Validation` to check.
   * @returns `true` if the `Validation` is `Valid`, otherwise `false`.
   */
  isValid(s) {
    return s.type === "valid";
  },
  /**
   * Checks if a `Validation` is `Invalid`.
   * @param r - The `Validation` to check.
   * @returns `true` if the `Validation` is `Invalid`, otherwise `false`.
   */
  isInvalid(s) {
    return s.type === "invalid";
  },
  /**
   * Maps the value of a `Validation` to a new value.
   * @param r - The `Validation` to map.
   * @param valid - The mapping function for a valid value.
   * @param invalid - The mapping function for an invalid value.
   * @returns The mapped value.
   */
  match: (s, e, u) => c.isValid(s) ? e() : u(s.error),
  /**
   * Maps the value of a `Validation` to a new `Validation`.
   * @param validation - The `Validation` to map.
   * @param value - The value to map.
   * @returns A new `Validation` with the mapped value.
   */
  toResult: (s, e) => c.match(
    s,
    () => a.success(e),
    (u) => a.failure(u)
  ),
  /**
   * Executes side effects based on the state of the validation.
   * Unlike `match`, all handlers are optional, allowing you to react only to specific states.
   * The `else` handler is called when no specific handler is provided for the current state.
   * @param v - The validation.
   * @param handlers - An object with optional handlers for each state and an optional `else` fallback.
   * @returns The validation that was passed in, allowing for chaining.
   * @public
   */
  effect: (s, e) => (s.type === "valid" ? e.valid ? e.valid() : e.else?.() : e.invalid ? e.invalid(s.error) : e.else?.(), s),
  /**
   * Execute a function when the `Validation` is valid.
   *
   * @param r - The `Validation` to check.
   * @param apply - The function to execute when the `Validation` is valid.
   * @returns The `Validation` object.
   */
  whenValid: (s, e) => (c.isValid(s) && e(), s),
  /**
   * Execute a function when the `Validation` is invalid.
   *
   * @param r - The `Validation` to check.
   * @param apply - The function to execute when the `Validation` is invalid.
   * @returns The `Validation` object.
   */
  whenInvalid: (s, e) => (c.isInvalid(s) && e(s.error), s),
  /**
   * Maps the error of an invalid `Validation` to a new error using the provided function.
   * For valid validations, the validation is preserved unchanged.
   * @param v - The `Validation` to map the error of.
   * @param f - The mapping function to apply to the error.
   * @returns A new `Validation` with the mapped error if invalid, otherwise the original valid.
   * @public
   */
  mapError: (s, e) => s.type === "invalid" ? c.invalid(e(s.error)) : s,
  /**
   * Maps the error of an invalid `Validation` to a new `Validation` using the provided function.
   * This allows recovery from errors by returning a valid validation.
   * @param v - The `Validation` to recover from.
   * @param f - The recovery function that returns a new `Validation`.
   * @returns The result of the recovery function if invalid, otherwise the original valid.
   * @public
   */
  flatMapError: (s, e) => s.type === "invalid" ? e(s.error) : s,
  /**
   * Combines two validations. Both must be valid for the result to be valid.
   * If both are invalid, errors are combined using the provided function.
   * @param v1 - The first validation.
   * @param v2 - The second validation.
   * @param combineErrors - The function to combine two errors.
   * @returns A combined validation.
   * @public
   */
  combine: (s, e, u) => c.isValid(s) && c.isValid(e) ? c.valid : c.isInvalid(s) && c.isInvalid(e) ? c.invalid(u(s.error, e.error)) : c.isInvalid(s) ? s : e,
  /**
   * Combines multiple validations into a single validation.
   * All must be valid for the result to be valid.
   * Returns the first invalid validation if any.
   * @param validations - The validations to combine.
   * @returns A single validation that is valid only if all inputs are valid.
   * @public
   */
  all: (s) => {
    for (const e of s)
      if (c.isInvalid(e))
        return e;
    return c.valid;
  },
  /**
   * Combines multiple validations, accumulating all errors.
   * All must be valid for the result to be valid.
   * If any are invalid, all errors are collected into an array.
   * @param validations - The validations to combine.
   * @returns A validation that is valid only if all inputs are valid, otherwise contains all errors.
   * @public
   */
  allErrors: (s) => {
    const e = [];
    for (const u of s)
      c.isInvalid(u) && e.push(u.error);
    return e.length > 0 ? c.invalid(e) : c.valid;
  },
  /**
   * Compares two validations for equality.
   * @param v1 - The first validation.
   * @param v2 - The second validation.
   * @param errorEquals - Optional custom equality function for errors. Defaults to strict equality.
   * @returns `true` if the validations are equal, `false` otherwise.
   * @public
   */
  equals: (s, e, u = (i, l) => i === l) => s.type === "valid" && e.type === "valid" ? !0 : s.type === "invalid" && e.type === "invalid" ? u(s.error, e.error) : !1,
  /**
   * Recovers from an invalid validation by returning a valid validation.
   * @param v - The `Validation` to recover from.
   * @returns A valid validation regardless of the input.
   * @public
   */
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  recover: (s) => c.valid,
  /**
   * Gets the error if the validation is invalid, otherwise returns undefined.
   * @param v - The validation to get the error from.
   * @returns The error if invalid, otherwise undefined.
   * @public
   */
  getError: (s) => {
    if (c.isInvalid(s))
      return s.error;
  },
  /**
   * Gets the error if the validation is invalid, otherwise returns the default value.
   * @param v - The validation to get the error from.
   * @param defaultError - The default error to return if valid.
   * @returns The error if invalid, otherwise the default error.
   * @public
   */
  getErrorOrElse: (s, e) => c.isInvalid(s) ? s.error : e
}, a = {
  /**
   * Creates a successful `Result`.
   * @param value - The value to wrap in a `Success` type.
   * @returns A `Result` that is a `Success`.
   * @public
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  success(s) {
    return { type: "Success", value: s };
  },
  /**
   * Creates a failure `Result`.
   * @param error - The error to wrap in a `Failure` type.
   * @returns A `Result` that is a `Failure`.
   * @public
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  failure(s) {
    return { type: "Failure", error: s };
  },
  /**
   * Maps the value of a `Result` to a new value.
   * @param r - The `Result` to map.
   * @param f - The mapping function.
   * @returns A new `Result` with the mapped value.
   * @public
   */
  map: (s, e) => s.type === "Success" ? a.success(e(s.value)) : s,
  /**
   * Maps the value of a `Result` to a new `Result`.
   * @param r - The `Result` to map.
   * @param f - The mapping function.
   * @returns A new `Result` with the mapped value.
   * @public
   */
  flatMap: (s, e) => s.type === "Success" ? e(s.value) : s,
  /**
   * Converts a `Result` to an `AsyncResult`.
   * @param r - The `Result` to convert.
   * @returns An `AsyncResult` that is equivalent to the input `Result`.
   * @public
   */
  toAsync(s) {
    return a.match(
      s,
      (e) => r.success(e),
      (e) => r.failure(e)
    );
  },
  /**
   * Converts a `Result` to a `Validation`.
   * @param r - The `Result` to convert.
   * @returns A `Validation` that is equivalent to the input `Result`.
   * @public
   */
  toValidation(s) {
    return a.match(
      s,
      () => c.valid,
      (e) => c.invalid(e)
    );
  },
  /**
   * Checks if a `Result` is a success.
   * @param r - The `Result` to check.
   * @returns `true` if the `Result` is a `Success`, `false` otherwise.
   * @public
   */
  isSuccess(s) {
    return s.type === "Success";
  },
  /**
   * Checks if a `Result` is a failure.
   * @param r - The `Result` to check.
   * @returns `true` if the `Result` is a `Failure`, `false` otherwise.
   * @public
   */
  isFailure(s) {
    return s.type === "Failure";
  },
  /**
   * Gets the value of a `Result` if it is a `Success`, otherwise returns the provided default value.
   * @param r - The `Result` to get the value from.
   * @param alt - The default value to return if the `Result` is a `Failure`.
   * @returns The value of the `Result` if it is a `Success`, otherwise the default value.
   * @public
   */
  getOrElse(s, e) {
    return a.isSuccess(s) ? s.value : e;
  },
  /**
   * Gets the value of a `Result` if it is a `Success`, otherwise returns the result of the provided function.
   * @param r - The `Result` to get the value from.
   * @param altf - The function to call if the `Result` is a `Failure`.
   * @returns The value of the `Result` if it is a `Success`, otherwise the result of the function.
   * @public
   */
  getOrElseLazy(s, e) {
    return a.isSuccess(s) ? s.value : e();
  },
  /**
   * Gets the value of a `Result` if it is a `Success`, otherwise returns `null`.
   * @param r - The `Result` to get the value from.
   * @returns The value of the `Result` if it is a `Success`, otherwise `null`.
   * @public
   */
  getOrNull(s) {
    return a.isSuccess(s) ? s.value : null;
  },
  /**
   * Gets the value of a `Result` if it is a `Success`, otherwise returns `undefined`.
   * @param r - The `Result` to get the value from.
   * @returns The value of the `Result` if it is a `Success`, otherwise `undefined`.
   * @public
   */
  getOrUndefined(s) {
    return a.isSuccess(s) ? s.value : void 0;
  },
  /**
   * Gets the value of a `Result` if it is a `Success`, otherwise it throws the error contained in the `Failure`.
   * @param r - The `Result` to get the value from.
   * @returns The value of the `Result` if it is a `Success`.
   */
  getUnsafe: (s) => {
    if (a.isSuccess(s))
      return s.value;
    throw s.error;
  },
  /**
   * Based on the state of the result, it picks the appropriate function to call and returns the result.
   * @param success - The function to call if the result is a success.
   * @param failure - The function to call if the result is a failure.
   * @returns The result of calling the appropriate function based on the state of the result.
   * @public
   */
  match: (s, e, u) => a.isSuccess(s) ? e(s.value) : u(s.error),
  /**
   * Executes side effects based on the state of the result.
   * Unlike `match`, all handlers are optional, allowing you to react only to specific states.
   * The `else` handler is called when no specific handler is provided for the current state.
   * @param r - The result.
   * @param handlers - An object with optional handlers for each state and an optional `else` fallback.
   * @returns The result that was passed in, allowing for chaining.
   * @public
   */
  effect: (s, e) => (s.type === "Success" ? e.success ? e.success(s.value) : e.else?.() : e.failure ? e.failure(s.error) : e.else?.(), s),
  /**
   * Calls the provided function if the result is a success.
   * @param apply - The function to call if the result is a success.
   * @returns A function that takes a `Result` and calls the provided function if the result is a success.
   * @public
   */
  whenSuccess: (s, e) => (a.isSuccess(s) && e(s.value), s),
  /**
   * Calls the provided function if the result is a failure.
   * @param apply - The function to call if the result is a failure.
   * @returns The result that was passed in.
   * @public
   */
  whenFailure: (s, e) => (a.isFailure(s) && e(s.error), s),
  /**
   * Combines two results into a single result.
   * @param r1 - The first result.
   * @param r2 - The second result.
   * @param combineV - The function to combine two values.
   * @param combineE - The function to combine two errors.
   * @returns The combined result.
   * @public
   */
  combine: (s, e, u, i) => a.match(
    s,
    (l) => a.match(
      e,
      (t) => a.success(u(l, t)),
      (t) => a.failure(t)
    ),
    (l) => a.match(
      e,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      (t) => a.failure(l),
      (t) => a.failure(i(l, t))
    )
  ),
  /**
   * Compares two results for equality.
   * @param r1 - The first result.
   * @param r2 - The second result.
   * @param options - The options to use for comparison. By default, uses strict equality.
   * @returns `true` if the results are equal, `false` otherwise.
   */
  equals: (s, e, u = {
    valueEquals: (i, l) => i === l,
    errorEquals: (i, l) => i === l
  }) => s.type === "Success" && e.type === "Success" ? u.valueEquals(s.value, e.value) : s.type === "Failure" && e.type === "Failure" ? u.errorEquals(s.error, e.error) : !1,
  /**
   * Combines multiple results into a single result.
   * @param results - The results to combine.
   * @returns A single result that is a success if all the input results are successes, otherwise a failure.
   */
  all: (s) => {
    const e = [];
    for (const u of s)
      if (a.isSuccess(u))
        e.push(u.value);
      else
        return u;
    return a.success(e);
  },
  /**
   * Maps the error of a failed `Result` to a new error using the provided function.
   * For success results, the result is preserved unchanged.
   * @param r - The `Result` to map the error of.
   * @param f - The mapping function to apply to the error.
   * @returns A new `Result` with the mapped error if failed, otherwise the original success.
   * @public
   */
  mapError: (s, e) => s.type === "Failure" ? a.failure(e(s.error)) : s,
  /**
   * Maps the error of a failed `Result` to a new `Result` using the provided function.
   * This allows recovery from errors by returning a new successful result.
   * @param r - The `Result` to recover from.
   * @param f - The recovery function that returns a new `Result`.
   * @returns The result of the recovery function if failed, otherwise the original success.
   * @public
   */
  flatMapError: (s, e) => s.type === "Failure" ? e(s.error) : s,
  /**
   * Recovers from a failure by providing an alternative value.
   * @param r - The `Result` to recover from.
   * @param f - The function that provides an alternative value given the error.
   * @returns A successful `Result` with the alternative value if failed, otherwise the original success.
   * @public
   */
  recover: (s, e) => s.type === "Failure" ? { type: "Success", value: e(s.error) } : s,
  /**
   * Applies a function wrapped in a `Result` to a value wrapped in a `Result`.
   * Useful for applying multiple arguments to a function in a safe way.
   * @param resultFn - The `Result` containing the function.
   * @param resultVal - The `Result` containing the value.
   * @returns A new `Result` with the result of applying the function to the value.
   * @public
   */
  ap: (s, e) => a.isSuccess(s) && a.isSuccess(e) ? a.success(s.value(e.value)) : a.isFailure(s) ? a.failure(s.error) : a.failure(e.error),
  /**
   * Maps two `Result` values using a function.
   * @param r1 - The first `Result`.
   * @param r2 - The second `Result`.
   * @param f - The function to apply to both values.
   * @returns A new `Result` with the result of applying the function to both values.
   * @public
   */
  map2: (s, e, u) => a.isSuccess(s) && a.isSuccess(e) ? a.success(u(s.value, e.value)) : a.isFailure(s) ? a.failure(s.error) : a.failure(e.error),
  /**
   * Maps three `Result` values using a function.
   * @param r1 - The first `Result`.
   * @param r2 - The second `Result`.
   * @param r3 - The third `Result`.
   * @param f - The function to apply to all three values.
   * @returns A new `Result` with the result of applying the function to all three values.
   * @public
   */
  map3: (s, e, u, i) => a.isSuccess(s) && a.isSuccess(e) && a.isSuccess(u) ? a.success(i(s.value, e.value, u.value)) : a.isFailure(s) ? a.failure(s.error) : a.isFailure(e) ? a.failure(e.error) : a.failure(u.error),
  /**
   * Converts a Promise to a Result.
   * @param p - The Promise to convert.
   * @returns A Promise that resolves to a Result.
   * @public
   */
  ofPromise: async (s) => {
    try {
      const e = await s;
      return a.success(e);
    } catch (e) {
      return a.failure(e instanceof Error ? e : new Error(String(e)));
    }
  },
  /**
   * Swaps the success and failure values of a Result.
   * A success becomes a failure with the value as the error,
   * and a failure becomes a success with the error as the value.
   * @param r - The Result to swap.
   * @returns A new Result with swapped success and failure.
   * @public
   */
  swap: (s) => a.isSuccess(s) ? a.failure(s.value) : a.success(s.error),
  /**
   * Converts a nullable value to a Result.
   * @param value - The nullable value.
   * @param error - The error to use if the value is null or undefined.
   * @returns A Result containing the value if not null/undefined, otherwise a failure.
   * @public
   */
  fromNullable: (s, e) => s == null ? a.failure(e) : a.success(s),
  /**
   * Converts a nullable value to a Result using a lazy error function.
   * @param value - The nullable value.
   * @param errorFn - The function to call to get the error if the value is null or undefined.
   * @returns A Result containing the value if not null/undefined, otherwise a failure.
   * @public
   */
  fromNullableLazy: (s, e) => s == null ? a.failure(e()) : a.success(s),
  /**
   * Wraps a function that may throw into a function that returns a Result.
   * @param f - The function that may throw.
   * @returns A function that returns a Result instead of throwing.
   * @public
   */
  tryCatch: (s) => {
    try {
      return a.success(s());
    } catch (e) {
      return a.failure(e instanceof Error ? e : new Error(String(e)));
    }
  }
};
function d(s) {
  return `bc-label bc-label--${s}`;
}
const p = (...s) => n.span(o.class(d("emphasis")), ...s), y = (...s) => n.span(o.class(d("default")), ...s), f = (...s) => n.span(o.class(d("muted")), ...s), S = (...s) => n.span(o.class(d("danger")), ...s);
function g(...s) {
  return n.div(o.class("bc-stack"), ...s);
}
export {
  S as D,
  p as E,
  y as L,
  f as M,
  g as S,
  c as i
};
