/**
 * 基础工具库。基于 {@link https://lodash.com/docs/4.17.15 | Lodash}。
 *
 * @packageDocumentation
 */

/// <reference types="wechat-miniprogram" />

import { Config } from 'decimal.js-light';
import DecimalLight from 'decimal.js-light';
import type { IsLowerCase } from './internal';
import type { IsNumeric } from './internal';
import type { IsUpperCase } from './internal';
import { Numeric } from 'decimal.js-light';
import type { ParseSelector } from 'typed-query-selector/parser';
import type { TruncateOptions } from 'lodash';
import type { UpperCaseCharacters } from './internal';
import type { WordSeparators } from './internal';

declare type AllValues<T extends Record<EnumKey, EnumValue>> = {
    [P in keyof T]: {
        label: P;
        value: T[P] extends true ? 'true' : T[P] extends false ? 'false' : T[P];
    };
}[keyof T];

/**
 * 任意异步函数。
 *
 * @public
 */
declare type AnyAsyncFunction = Record<any, any> & {
    (...args: any[]): Promise<any>;
};

/**
 * 任意函数。
 *
 * @public
 */
declare type AnyFunction_2 = Record<any, any> & {
    (...args: any[]): any;
};

/**
 * 任意对象。
 *
 * @public
 */
declare type AnyObject_2 = Record<any, any>;

/**
 * 将给定的值 `RequiredDeep` 化。
 *
 * @param value 值
 */
export declare function asRequiredDeep<T>(value: T): RequiredDeep<T>;

/**
 * 异步函数并行执行限制。
 *
 * @param asyncFn 异步函数
 * @param options 选项
 */
export declare function asyncLimit<T extends (...args: any[]) => Promise<any>>(asyncFn: T, options?: AsyncLimitOptions): T;

export declare interface AsyncLimitOptions {
    /**
     * 并行量。
     *
     * @default 1
     */
    concurrency?: number;
}

/**
 * 异步函数执行缓存。
 *
 * @param asyncFn 异步函数
 * @param options 选项
 */
export declare function asyncMemoize<T extends (...args: any[]) => Promise<any>>(asyncFn: T, options?: AsyncMemoizeOptions<T>): T & {
    cache: AsyncMemoizeCacheMap;
};

export declare type AsyncMemoizeCacheMap = Map<string, {
    value: any;
    expiredAt: number;
}>;

export declare interface AsyncMemoizeOptions<T extends (...args: any[]) => Promise<any>> {
    /**
     * 缓存键。
     *
     * @default arg0 => arg0
     */
    cacheKey?: (...args: Parameters<T>) => any;
    /**
     * 缓存时效（毫秒）。
     *
     * @default 0
     */
    cacheTTL?: number;
}

/** Useful as a return type in interfaces or abstract classes with missing implementation */
declare type AsyncOrSync<T> = PromiseLike<T> | T;

/**
 * 将给定的 base64 字符串解码为 UTF8 字符串。
 *
 * @public
 * @param value 要解码的 base64 字符串
 * @returns 返回解码后的 UTF8 字符串
 * @example
 * ```typescript
 * base64Decode('dg==') // => 'v'
 * base64Decode('6b6Z') // => '龙'
 * base64Decode('8J+QsQ==') // => '🐱'
 * ```
 */
export declare function base64Decode(value: string): string;

/**
 * base64.js
 * Dan Kogai (https://github.com/dankogai)
 * Licensed under the BSD 3-Clause License
 * https://github.com/dankogai/js-base64/blob/master/LICENSE.md
 *
 * Modified by Jay Fong
 */
/**
 * 将给定的 UTF8 字符串编码为 base64 字符串。
 *
 * @public
 * @param value 要编码的 UTF8 字符串
 * @returns 返回编码后的 base64 字符串
 * @example
 * ```typescript
 * base64Encode('v') // => 'dg=='
 * base64Encode('龙') // => '6b6Z'
 * base64Encode('🐱') // => '8J+QsQ=='
 * ```
 */
export declare function base64Encode(value: string): string;

/**
 * 将给定的 base64url 字符串解码为 UTF8 字符串。
 *
 * @public
 * @param value 要解码的 base64url 字符串
 * @returns 返回解码后的 UTF8 字符串
 * @example
 * ```typescript
 * base64UrlDecode('dg') // => 'v'
 * base64UrlDecode('6b6Z') // => '龙'
 * base64UrlDecode('8J-QsQ') // => '🐱'
 * ```
 */
export declare function base64UrlDecode(value: string): string;

/**
 * 将给定的 UTF8 字符串编码为 URL 安全的 base64url 字符串。
 *
 * @public
 * @param value 要编码的 UTF8 字符串
 * @returns 返回编码后的 base64url 字符串
 * @example
 * ```typescript
 * base64UrlEncode('v') // => 'dg'
 * base64UrlEncode('龙') // => '6b6Z'
 * base64UrlEncode('🐱') // => '8J-QsQ'
 * ```
 */
export declare function base64UrlEncode(value: string): string;

declare type BaseElements = ParentNode | Iterable<ParentNode>;

/**
 * 绑定事件。
 *
 * @public
 * @param target 事件绑定的目标
 * @returns 返回事件绑定函数
 * @example
 * ```typescript
 * const bindWindowEvent = bindEvent(window)
 * const unbindClick = bindWindowEvent('click', console.log)
 * const unbindScroll = bindWindowEvent('scroll', console.log)
 * ```
 */
export declare function bindEvent<T extends Record<'addEventListener' | 'removeEventListener', AnyFunction_2>>(target: T): BindEventFunction<T>;

/**
 * 绑定事件函数。
 *
 * @public
 * @param type 事件类型
 * @param callback 事件回调
 * @param options 事件选项
 * @returns 返回事件解绑函数
 */
export declare type BindEventFunction<T> = <E extends T extends typeof window ? WindowEventMap : T extends HTMLMediaElement ? HTMLMediaElementEventMap : T extends HTMLBodyElement ? HTMLBodyElementEventMap : T extends HTMLFrameSetElement ? HTMLFrameSetElementEventMap : T extends FileReader ? FileReaderEventMap : T extends WebSocket ? WebSocketEventMap : T extends SVGElement ? SVGElementEventMap : T extends HTMLElement ? HTMLElementEventMap : Record<string, any>, K extends keyof E>(type: K, callback: (this: T, ev: E[K]) => any, options?: boolean | AddEventListenerOptions) => () => any;

declare const brands: readonly ["微信", "QQ", "支付宝", "京东", "百度", "字节跳动", "钉钉"];

declare type Builtin = Primitive_2 | Function | Date | Error | RegExp;

/**
 * 获取字节值。
 *
 * @param value 值
 * @param unit 单位
 */
export declare function bytes(value: number, unit: BytesUnit): number;

/**
 * 获取字节值。
 *
 * @param value 值
 */
export declare function bytes(value: BytesValue): number;

export declare type BytesNumberValue = number;

export declare type BytesStringValue = `${number}${BytesUnit}`;

export declare type BytesUnit = 'PB' | 'TB' | 'GB' | 'MB' | 'KB' | 'B';

export declare type BytesValue = BytesNumberValue | BytesStringValue;

/**
 * 科学计算器。主要是为了避免 js 的浮点数精度计算问题。
 */
export declare const Calculator: CalculatorInstance<number>;

export declare interface CalculatorConfig extends Config {
    /** 小数位数 */
    decimalPlaces?: number;
}

export declare type CalculatorFunctionValue = (calculator: CalculatorInstance<DecimalLight>) => OneOrMore<DecimalLight>;

export declare interface CalculatorInstance<T = number> {
    /**
     * decimal.js 引用。
     */
    decimal: typeof DecimalLight;
    /**
     * 根据配置创建一个新的计算器。
     *
     * @param config 配置
     */
    make(config?: CalculatorConfig): CalculatorInstance;
    /**
     * 加。
     *
     * - 加数列表为空时返回 0；
     * - 加数列表长度为 1 时返回第 1 个的值。
     *
     * @param values 加数列表
     */
    add(...values: CalculatorValue[]): T;
    /**
     * 减。
     *
     * - 减数列表为空时返回 0；
     * - 减数列表长度为 1 时返回第 1 个的值。
     *
     * @param values 减数列表
     */
    sub(...values: CalculatorValue[]): T;
    /**
     * 乘。
     *
     * - 乘数列表为空时返回 0；
     * - 乘数列表长度为 1 时返回第 1 个的值。
     *
     * @param values 乘数列表
     */
    mul(...values: CalculatorValue[]): T;
    /**
     * 除。
     *
     * - 除数列表为空时返回 0；
     * - 除数列表长度为 1 时返回第 1 个的值。
     *
     * @param values 除数列表
     */
    div(...values: CalculatorValue[]): T;
    /**
     * 转换为数字。
     *
     * @param value 值
     */
    toNumber(value: CalculatorPrimitiveValue): T;
}

export declare type CalculatorPrimitiveValue = Numeric;

export declare type CalculatorValue = CalculatorPrimitiveValue | CalculatorFunctionValue;

/**
 Convert a string literal to camel-case.

 This can be useful when, for example, converting some kebab-cased command-line flags or a snake-cased database result.

 By default, consecutive uppercase letter are preserved. See {@link CamelCaseOptions.preserveConsecutiveUppercase preserveConsecutiveUppercase} option to change this behaviour.

 @example
 ```
 import type {CamelCase} from 'type-fest';

 // Simple

 const someVariable: CamelCase<'foo-bar'> = 'fooBar';

 // Advanced

 type CamelCasedProperties<T> = {
 	[K in keyof T as CamelCase<K>]: T[K]
 };

 interface RawOptions {
 	'dry-run': boolean;
 	'full_family_name': string;
 	foo: number;
 	BAR: string;
 	QUZ_QUX: number;
 	'OTHER-FIELD': boolean;
 }

 const dbResult: CamelCasedProperties<RawOptions> = {
 	dryRun: true,
 	fullFamilyName: 'bar.js',
 	foo: 123,
 	bar: 'foo',
 	quzQux: 6,
 	otherField: false
 };
 ```

 @category Change case
 @category Template literal
 */
declare type CamelCase<Type, Options extends CamelCaseOptions = {preserveConsecutiveUppercase: true}> = Type extends string
	? string extends Type
		? Type
		: Uncapitalize<CamelCaseFromArray<Words<Type extends Uppercase<Type> ? Lowercase<Type> : Type>, Options>>
	: Type;

/**
 Convert an array of words to camel-case.
 */
declare type CamelCaseFromArray<
	Words extends string[],
	Options extends CamelCaseOptions,
	OutputString extends string = '',
> = Words extends [
	infer FirstWord extends string,
	...infer RemainingWords extends string[],
]
	? Options['preserveConsecutiveUppercase'] extends true
		? `${Capitalize<FirstWord>}${CamelCaseFromArray<RemainingWords, Options>}`
		: `${Capitalize<Lowercase<FirstWord>>}${CamelCaseFromArray<RemainingWords, Options>}`
	: OutputString;

/**
 CamelCase options.

 @see {@link CamelCase}
 */
declare type CamelCaseOptions = {
    	/**
     	Whether to preserved consecutive uppercase letter.

     	@default true
     	*/
    	preserveConsecutiveUppercase?: boolean;
};

/**
 * 计算多个数组的笛卡尔积。
 *
 * @param arr 数组内容
 * @example
 * ```typescript
 * cartesianProduct([
 *   ['a', 'b'],
 *   [1, 2],
 * ])
 * // => [['a', 1], ['a', 2], ['b', 1], ['b', 2]]
 * ```
 */
export declare function cartesianProduct<T>(arr: [T[]]): [T][];

export declare function cartesianProduct<T, U>(arr: [T[], U[]]): [T, U][];

export declare function cartesianProduct<T, U, V>(arr: [T[], U[], V[]]): [T, U, V][];

export declare function cartesianProduct<T, U, V, W>(arr: [T[], U[], V[], W[]]): [T, U, V, W][];

export declare function cartesianProduct<T, U, V, W, X>(arr: [T[], U[], V[], W[], X[]]): [T, U, V, W, X][];

export declare function cartesianProduct<T, U, V, W, X, Y>(arr: [T[], U[], V[], W[], X[], Y[]]): [T, U, V, W, X, Y][];

export declare function cartesianProduct<T, U, V, W, X, Y, Z>(arr: [T[], U[], V[], W[], X[], Y[], Z[]]): [T, U, V, W, X, Y, Z][];

export declare function cartesianProduct(arr: any[][]): any[][];

/**
 * UTF8 字符转为 Unicode 码点。
 *
 * @param character 字符，支持多个字符，返回的码点将以 `-` 分割
 */
export declare function characterToCodepoint(character: string): string;

/**
 * 选择文件。
 *
 * @param accept 接受的文件类型，其中默认的 `image` 表示 `image/*`
 * @param multiple 是否多选
 * @returns 返回选中的文件列表
 */
export declare function chooseFile(accept: LiteralUnion<'image', string>, multiple?: boolean): Promise<ReadonlyArray<File>>;

/**
 * 选择文件。
 *
 * @param accept 接受的文件类型，其中默认的 `image` 表示 `image/*`
 * @param options 选项
 * @returns 返回选中的文件列表
 */
export declare function chooseFile(accept: LiteralUnion<'image', string>, options?: ChooseFileOptions): Promise<ReadonlyArray<File>>;

export declare interface ChooseFileOptions {
    /**
     * 是否多选
     *
     * @default false
     */
    multiple?: boolean;
    /**
     * 元素准备好后的回调
     */
    afterElementReady?: (payload: {
        el: HTMLInputElement;
    }) => any;
}

/**
 * 类似 `chunk`，但当每组条目数量不一致时会在最后一组添加填充值以达到每组条目数量一致。
 *
 * @param array 数组
 * @param size 分组大小
 * @param filler 填充值
 * @param consistent 是否保持一致性，默认 false，设为 true 则当数组长度小于分组大小时也填充数组使其长度达到分组大小
 */
export declare function chunkEqual<T>(array: T[], size: number, filler: (index: number) => T, consistent?: boolean): T[][];

/**
 * 深克隆快速版。
 *
 * @param value 要克隆的值
 * @param ignore 忽略的值
 * @returns 返回克隆后的值
 * @example
 * ```typescript
 * cloneDeepFast({ x: [1] })
 * // => { x: [1] }
 * ```
 */
export declare function cloneDeepFast<T>(value: T, ignore?: (value: unknown) => boolean | undefined): T;

/**
 * Unicode 码点转为 UTF8 字符。
 *
 * @param codepoint 码点，支持以 `-` 分割多个码点
 */
export declare function codepointToCharacter(codepoint: string): string;

export declare type ConditionalArrayItem<T, K extends keyof T = never> = (IsNever<K> extends true ? T : Merge<T, {
    [k in K]: Array<ConditionalArrayItem<T, K>>;
}>) | false;

/**
 Convert a string literal to screaming-snake-case.

 This can be useful when, for example, converting a camel-cased object property to a screaming-snake-cased SQL column name.

 @example
 ```
 import type {ScreamingSnakeCase} from 'type-fest';

 const someVariable: ScreamingSnakeCase<'fooBar'> = 'FOO_BAR';
 ```

 @category Change case
 @category Template literal
 */
declare type ConstantCase<Value> = Value extends string
	? IsScreamingSnakeCase<Value> extends true
		? Value
		: Uppercase<SnakeCase<Value>>
	: Value;

/**
 * 转换文本为大写字符串，单词之间带有下划线。
 *
 * @param text 要转换的文本
 * @returns 返回结果
 * @example
 * ```typescript
 * constantCase('test string')
 * // => TEST_STRING
 * ```
 */
export declare function constantCase<T extends string>(text: T): ConstantCase<T>;

/**
 * 复制文本到剪切板。
 *
 * @param text 要复制的文本
 * @param options 选项
 * @returns 返回是否复制成功
 */
export declare function copyTextToClipboard(text: string, options?: CopyTextToClipboardOptions): boolean;

export declare interface CopyTextToClipboardOptions {
    /**
     * 复制容器的类名。
     */
    containerClass?: string;
}

/**
 * 创建提交类行为。
 *
 * @param options 选项
 */
export declare function createSubmit(options: CreateSubmitOptions<string>): CreateSubmitResult<string>;

/**
 * 创建提交类行为。
 *
 * @param options 选项
 */
export declare function createSubmit<T>(options: CreateSubmitOptions<T>): CreateSubmitResult<T>;

export declare interface CreateSubmitOptions<T = string> {
    /**
     * 开始回调。
     *
     * @param message 提示信息
     */
    start(message: T | undefined, id: number): AsyncOrSync<any>;
    /**
     * 失败回调。
     *
     * @param message 提示信息
     * @param duration 持续时间（毫秒）
     */
    fail(message: T, duration: number, id: number): AsyncOrSync<any>;
    /**
     * 成功回调。
     *
     * @param message 提示信息
     * @param duration 持续时间（毫秒）
     */
    success(message: T, duration: number, id: number): AsyncOrSync<any>;
    /**
     * 完成回调。
     */
    complete(id: number): AsyncOrSync<any>;
    /**
     * 异常回调。
     */
    throw?(error: unknown, id: number): AsyncOrSync<any>;
}

export declare type CreateSubmitResult<T = string> = (<TResult>(action: (payload: SubmitActionPayload<T>) => Promise<TResult>) => Promise<TResult>) & Pick<SubmitActionPayload<T>, 'fail' | 'success'>;

/**
 * 创建 url 查询字符串。
 *
 * @param parameters 查询参数
 * @param options 选项
 * @returns 返回 url 查询字符串
 * @example
 * ```typescript
 * createUrlQueryString({ x: 1, y: 'z' }) // => x=1&y=z
 * ```
 */
export declare function createUrlQueryString(parameters: AnyObject_2, options?: CreateUrlQueryStringOptions): string;

export declare interface CreateUrlQueryStringOptions {
    /**
     * 键值内部的连接符。
     */
    pairSeparator?: string;
    /**
     * 各参数间的连接符。
     */
    partSeparator?: string;
}

/**
 * 数据打包器。
 */
export declare class DataPacker {
    private static encodeIndexes;
    private static decodeIndexes;
    /**
     * 打包数据。
     */
    static pack<TRawObjectData extends RawData>(rawData: TRawObjectData): PackedData<TRawObjectData>;
    /**
     * 返回结果同 `pack()`，不过类型是原数据的类型。
     */
    static packAsRawType<T>(rawData: T): T;
    /**
     * 解包数据。
     */
    static unpack<TRawObjectData extends RawData>(packedData: PackedData<TRawObjectData>): RawData<TRawObjectData>;
    /**
     * 如果是打包后的数据，则解包后返回，否则直接返回。如果是对象，则递归尝试解包。
     *
     * @param value 数据
     * @param depth 递归层级，默认：2
     * @returns 返回结果数据
     */
    static unpackIfNeeded(value: any, depth?: number): any;
}

/**
 * 移除每一行的公共前导空白。
 *
 * @public
 * @param text 文本
 * @returns 返回处理后的结果
 * @example
 * ```typescript
 * dedent(' a\n b') // => 'a\nb'
 * ```
 */
export declare function dedent(text: string): string;

/**
 * 首先，每一行紧跟前导空白的插入值为多行时，保持缩进。
 * 然后，移除每一行的公共前导空白。
 *
 * @public
 * @param literals 字面值
 * @param interpolations 插入值
 * @returns 返回处理后的结果
 * @example
 * ```typescript
 * dedent` a\n b` // => 'a\nb'
 * ```
 */
export declare function dedent(literals: TemplateStringsArray, ...interpolations: Array<string | number>): string;

/**
 * 设置默认索引。当前索引为 `-1` 或 `NaN` 时会使用默认索引。
 *
 * @param index 当前索引
 * @param defaultIndex 默认索引
 */
export declare function defaultIndexTo(index: number, defaultIndex: number): number;

/**
 Convert a string literal to a custom string delimiter casing.

 This can be useful when, for example, converting a camel-cased object property to an oddly cased one.

 @see KebabCase
 @see SnakeCase

 @example
 ```
 import type {DelimiterCase} from 'type-fest';

 // Simple

 const someVariable: DelimiterCase<'fooBar', '#'> = 'foo#bar';

 // Advanced

 type OddlyCasedProperties<T> = {
 	[K in keyof T as DelimiterCase<K, '#'>]: T[K]
 };

 interface SomeOptions {
 	dryRun: boolean;
 	includeFile: string;
 	foo: number;
 }

 const rawCliOptions: OddlyCasedProperties<SomeOptions> = {
 	'dry#run': true,
 	'include#file': 'bar.js',
 	foo: 123
 };
 ```

 @category Change case
 @category Template literal
 */
declare type DelimiterCase<Value, Delimiter extends string> = string extends Value ? Value : Value extends string
	? StringArrayToDelimiterCase<
	SplitIncludingDelimiters<Value, WordSeparators | UpperCaseCharacters>,
	true,
	WordSeparators,
	UpperCaseCharacters,
	Delimiter
	>
	: Value;

/**
 * 文本脱敏。
 *
 * @param text 待脱敏的文本
 * @param options 脱敏选项
 */
export declare function desensitize(text: string, options?: DesensitizeOptions): string;

export declare interface DesensitizeOptions {
    /**
     * 脱敏策略
     */
    strategy?: DesensitizeStrategy;
    /**
     * 脱敏替换字符
     *
     * @default '*'
     */
    replacer?: string;
    /**
     * 前置保留字符数
     *
     * @default 0
     */
    preKeep?: number;
    /**
     * 后置保留字符数
     *
     * @default 0
     */
    postKeep?: number;
}

export declare enum DesensitizeStrategy {
    CHINESE_NAME = "CHINESE_NAME",
    CHINESE_ID_CARD_NUMBER = "CHINESE_ID_CARD_NUMBER",
    CHINESE_MOBILE_PHONE_NUMBER = "CHINESE_MOBILE_PHONE_NUMBER",
    EMAIL = "EMAIL"
}

/**
 * 开发环境和生产环境返回不同的值或调用不同的函数。
 *
 * `process.env.NODE_ENV` 为空值、`production`、`prod` 时被认为是生产环境，否则是开发环境。
 *
 * @param devValue 开发环境返回的值或调用的函数
 * @param prodValue 生产环境返回的值或调用的函数
 */
export declare const devOrProd: {
    <R, T extends R = R, F extends () => R = () => R>(devValue: T | F, prodValue: T | F): R;
    /**
     * 构造 devOrProd。
     */
    make: typeof makeDevOrProd;
};

export declare type ElementOfRawData<TRawData extends RawData> = TRawData extends RawData<infer X> ? X : never;

export declare type EnumKey = string;

export declare type EnumMap = Record<EnumKey, EnumValue>;

export declare type EnumResult<T extends EnumMap> = T & InvertResult<T> & {
    $list: List<T>;
    $buildList: (keys: Array<keyof T> | Record<keyof T, any>) => List<T>;
    $is(value: any, keys: OneOrMore<LiteralUnion<keyof T, ValueOf<T>>>): boolean;
};

export declare type EnumValue = string | number | boolean;

/**
 * 事件巴士，管理事件的发布与订阅。
 *
 * @template TListeners 事件名称及其对应的回调描述
 * @example
 * ```typescript
 * const bus = new EventBus<{
 *   success: (payload: { message: string }) => any
 * }>()
 * bus.on('success', ({ message }) => console.log(message))
 * bus.emit('success', { message: '提交成功' })
 * // => 控制台输出: 提交成功
 * ```
 */
export declare class EventBus<TListeners extends EventBusListeners> {
    private options?;
    /**
     * 构造函数。
     */
    constructor(options?: EventBusOptions<TListeners> | undefined);
    /**
     * 回调列表。
     */
    private callbacks;
    /**
     * 订阅多个事件。
     *
     * @param eventNames 事件名称
     * @param callback 事件触发回调
     * @returns 返回取消订阅的函数
     */
    on<TListenerName extends keyof TListeners>(eventNames: TListenerName[], callback: (firstPayload: {
        [K in TListenerName]: Parameters<TListeners[K]>[0];
    }, payload: {
        [K in TListenerName]: Parameters<TListeners[K]>;
    }) => any): EventBusOffListener;
    /**
     * 订阅单个事件。
     *
     * @param eventName 事件名称
     * @param callback 事件触发回调
     * @returns 返回取消订阅的函数
     */
    on<TListenerName extends keyof TListeners>(eventName: TListenerName, callback: TListeners[TListenerName]): EventBusOffListener;
    /**
     * 订阅事件，但只订阅一次即取消订阅。
     *
     * @param eventName 事件名称
     * @param callback 事件触发回调
     * @returns 返回取消订阅的函数
     */
    once<TListenerName extends keyof TListeners>(eventName: TListenerName, callback: TListeners[TListenerName]): EventBusOffListener;
    /**
     * 取消订阅事件，若没有指定回调，则取消所有回调。
     *
     * @param eventName 事件名称
     * @param callback 事件触发回调
     */
    off<TListenerName extends keyof TListeners>(eventName: TListenerName, callbackOrTag?: TListeners[TListenerName] | string | number): void;
    /**
     * 发布事件。
     *
     * @param eventNameAndContext 事件名称和上下文
     * @param args 传给事件回调的参数
     * @returns 返回各事件回调的返回结果组成的数组
     */
    emit<TListenerName extends keyof TListeners>(eventName: TListenerName | EventBusListenerDescriptor<TListenerName>, ...args: Parameters<TListeners[TListenerName]>): Array<ReturnType<TListeners[TListenerName]>>;
    /**
     * 局部执行。
     *
     * @param fn 执行函数
     * @returns 可以返回一个或多个取消订阅的函数
     */
    run(fn: (bus: this) => void | EventBusOffListener | EventBusOffListener[]): EventBusOffListener;
    /**
     * 清空事件订阅。
     */
    clear(): void;
    /**
     * 销毁。
     */
    destroy(): void;
}

export declare type EventBusBeforeEmit<TListeners extends EventBusListeners> = {
    [TListenerName in keyof TListeners]?: (this: EventBus<TListeners>, context: any) => any;
};

export declare type EventBusBeforeOn<TListeners extends EventBusListeners> = {
    [TListenerName in keyof TListeners]?: (this: EventBus<TListeners>, callback: EventBusListener<TListeners[TListenerName]>) => TListeners[TListenerName];
};

export declare type EventBusListener<TCallback extends (...args: any[]) => any = (...args: any[]) => any> = TCallback & {
    __EVENT_BUS_TAG__?: EventBusListenerTag;
};

export declare interface EventBusListenerDescriptor<TListenerName extends keyof EventBusListeners> {
    name: TListenerName;
    context?: any;
    tag?: EventBusListenerTag;
    filter?: (callback: EventBusListener, index: number, callbacks: EventBusListener[]) => boolean;
}

export declare type EventBusListeners = Record<string, EventBusListener>;

export declare type EventBusListenerTag = string | number;

export declare type EventBusOffListener = () => any;

export declare interface EventBusOptions<TListeners extends EventBusListeners> {
    beforeOn?: EventBusBeforeOn<TListeners>;
    beforeEmit?: EventBusBeforeEmit<TListeners>;
}

/**
 * 格式化字节数，以 1024 作为千字节数。
 *
 * @param value 要格式化的字节数
 * @returns 返回结果
 */
export declare function formatBytes(value: number): string;

/**
 * 格式化数字。
 *
 * @param value 要格式化的数字
 * @param options 选项
 * @returns 返回格式化后的数值
 * @example
 * ```typescript
 * formatNumber(1314.56789) // => '1,314.56789'
 * formatNumber(1314.56789, { thousandsSeparator: ' ' }) // => '1 314.56789'
 * formatNumber(1314.56789, { thousandthsSeparator: ',' }) // => '1,314.567,89'
 * ```
 */
export declare function formatNumber(value: number, options?: FormatNumberOptions): string;

/**
 * 格式化数字选项。
 */
export declare interface FormatNumberOptions {
    /**
     * 整数部分的千分位分隔符。
     *
     * @default ','
     */
    thousandsSeparator?: string;
    /**
     * 小数部分的千分位分隔符。
     *
     * @default ''
     */
    thousandthsSeparator?: string;
}

/**
 * 地理坐标系转换工具。
 *
 * - `大地坐标系（WGS84 坐标系）`: GPS 全球卫星定位系统使用的坐标系；
 * - `火星坐标系（GCJ02 坐标系）`: 腾讯地图、高德地图等使用的坐标系，是由中国国家测绘局制定的由 WGS84 加密后得到的坐标系；
 * - `百度坐标系（BD09 坐标系）`: 百度地图使用的坐标系，是在 GCJ02 基础上再次加密得到的坐标系。
 */
export declare class GeoCoord {
    /**
     * `WGS84 坐标系` 转 `GCJ02 坐标系`。
     *
     * 应用场景：GPS 坐标转腾讯地图、高德地图坐标。
     */
    static WGS84ToGCJ02: (input: GeoCoordTransformInput) => GeoCoordTransformOutput;
    /**
     * `WGS84 坐标系` 转 `BD09 坐标系`。
     *
     * 应用场景：GPS 坐标转百度地图坐标。
     */
    static WGS84ToBD09: (input: GeoCoordTransformInput) => GeoCoordTransformOutput;
    /**
     * `GCJ02 坐标系` 转 `WGS84 坐标系`。
     *
     * 应用场景：腾讯地图、高德地图坐标转 GPS 坐标。
     */
    static GCJ02ToWGS84: (input: GeoCoordTransformInput) => GeoCoordTransformOutput;
    /**
     * `GCJ02 坐标系` 转 `BD09 坐标系`。
     *
     * 应用场景：腾讯地图、高德地图坐标转百度地图坐标。
     */
    static GCJ02ToBD09: (input: GeoCoordTransformInput) => GeoCoordTransformOutput;
    /**
     * `BD09 坐标系` 转 `WGS84 坐标系`。
     *
     * 应用场景：百度地图坐标转 GPS 坐标。
     */
    static BD09ToWGS84: (input: GeoCoordTransformInput) => GeoCoordTransformOutput;
    /**
     * `BD09 坐标系` 转 `GCJ02 坐标系`。
     *
     * 应用场景：百度地图坐标转腾讯地图、高德地图坐标。
     */
    static BD09ToGCJ02: (input: GeoCoordTransformInput) => GeoCoordTransformOutput;
}

export declare interface GeoCoordTransformInput {
    /**
     * 经度。
     */
    longitude: number;
    /**
     * 纬度。
     */
    latitude: number;
}

export declare interface GeoCoordTransformOutput {
    /**
     * 经度。
     */
    longitude: number;
    /**
     * 纬度。
     */
    latitude: number;
}

/**
 * 返回当前正在运行的脚本所属的 `<script>` 元素。有两点限制：
 *
 * - 只在脚本被解析后首次运行时有效；
 * - 如果当前正在执行的代码是被其他代码作为回调函数或者事件处理函数调用的，会返回 `null`。
 */
export declare function getCurrentScript(): HTMLScriptElement | null;

/**
 * 获取邮件链接。
 *
 * @param options 选项
 */
export declare function getEmailUrl(options: GetEmailUrlOptions): string;

export declare interface GetEmailUrlOptions {
    /** 收件人 */
    to?: string | string[];
    /** 抄送人 */
    cc?: string | string[];
    /** 密送人 */
    bcc?: string | string[];
    /** 主题 */
    subject?: string;
    /** 内容 */
    body?: string;
}

/**
 * 获取运行环境信息。
 *
 * @returns 返回运行环境信息
 */
export declare function getEnvironment(): GetEnvironmentResult;

export declare interface GetEnvironmentResult {
    /** 浏览器 */
    readonly browser: boolean;
    /** 微信 WebView */
    readonly wechatWebView: boolean;
    /** 小程序 */
    readonly miniProgram: boolean;
    /** 微信小程序 */
    readonly wechatMiniProgram: boolean;
    /** iOS */
    readonly ios: boolean;
    /** 安卓 */
    readonly android: boolean;
    /** Node.js */
    readonly nodejs: boolean;
    /** Deno */
    readonly deno: boolean;
    /** Taro 3 */
    readonly taro: boolean;
}

/**
 * 获取短信链接。
 *
 * @param options 选项
 * @see https://stackoverflow.com/questions/6480462/how-to-pre-populate-the-sms-body-text-via-an-html-link
 */
export declare function getSmsUrl(options: GetSmsUrlOptions): string;

export declare interface GetSmsUrlOptions {
    /** 手机号 */
    phoneNumber?: string;
    /** 消息 */
    message?: string;
    /** 用户代理 */
    userAgent?: string;
}

/**
 * 获取微信公众号的二维码链接。
 *
 * @param accountId 公众号 ID
 * @returns 返回二维码链接
 * @example
 * ```typescript
 * getWechatPublicAccountQrcodeUrl('rmrbwx')
 * // => https://open.weixin.qq.com/qr/code?username=rmrbwx
 * ```
 */
export declare function getWechatPublicAccountQrcodeUrl(accountId: string): string;

/**
 * 将 HTML 字符串转为 DocumentFragment。
 *
 * @param html HTML 字符串
 */
export declare function htmlToDocumentFragment(html: string): DocumentFragment;

/**
 * 将 HTML 字符串转为 Element。
 *
 * @param html HTML 字符串
 */
export declare function htmlToElement<T extends Element = Element>(html: string): T | undefined;

/**
 * 立即调用函数并返回其返回值。
 *
 * 注：`ii = immediately invoke`
 *
 * @param fn 要调用的函数
 * @returns 返回被调用函数的返回值
 * @example
 * ```typescript
 * ii(() => 1) // => 1
 * ```
 */
export declare function ii<R, F extends () => R = () => R>(fn: F): R;

/**
 * 检查是否在 Android 设备中。
 *
 * @returns 返回检查结果
 * @example
 * ```typescript
 * if (inAndroid()) {
 *   console.log('你在 Android 设备中')
 * }
 * ```
 */
export declare function inAndroid(): boolean;

/**
 * 检查是否在浏览器环境中。
 *
 * @returns 返回检查结果
 * @example
 * ```typescript
 * if (inBrowser()) {
 *   console.log('你在浏览器中')
 * }
 * ```
 */
export declare function inBrowser(): boolean;

/**
 Returns a boolean for whether the given array includes the given item.

 This can be useful if another type wants to make a decision based on whether the array includes that item.

 @example
 ```
 import type {Includes} from 'type-fest';

 type hasRed<array extends any[]> = Includes<array, 'red'>;
 ```

 @category Array
 */
declare type Includes<Value extends readonly any[], Item> =
	Value extends readonly [Value[0], ...infer rest]
		? IsEqual<Value[0], Item> extends true
			? true
			: Includes<rest, Item>
		: false;

/**
 * 检查是否在 Deno 中。
 *
 * @returns 返回检查结果
 * @example
 * ```typescript
 * if (inDeno()) {
 *   console.log('你在 Deno 中')
 * }
 * ```
 */
export declare function inDeno(): boolean;

/**
 * 每一行紧跟前导空白的插入值为多行时，保持缩进。
 *
 * @public
 * @param literals 字面值
 * @param interpolations 插入值
 * @returns 返回处理后的结果
 * @example
 * ```typescript
 * indent` ${'a\nb'}` // => ' a\n b'
 * ```
 */
export declare function indent(literals: TemplateStringsArray, ...interpolations: Array<string | number>): string;

/**
 * 检查是否在 iOS 设备中。
 *
 * @returns 返回检查结果
 * @example
 * ```typescript
 * if (inIOS()) {
 *   console.log('你在 iOS 设备中')
 * }
 * ```
 */
export declare function inIOS(): boolean;

/**
 * 检查是否在指定品牌的小程序中，若在，返回承载其 API 的全局对象，若不在，返回 false。
 *
 * @param brand 指定的小程序品牌，若未指定，则表示所有小程序品牌
 * @returns 返回检查结果
 */
export declare function inMiniProgram(brand?: MiniProgramBrand | MiniProgramBrand[]): MiniProgramApi | false;

/**
 * 检查是否在小程序 WebView 中。
 *
 * 仅支持微信、QQ、支付宝、抖音、百度。
 */
export declare function inMiniProgramWebView(): boolean;

/**
 * 检查是否在 Node.js 中。
 *
 * @returns 返回检查结果
 * @example
 * ```typescript
 * if (inNodeJS()) {
 *   console.log('你在 Node.js 中')
 * }
 * ```
 */
export declare function inNodeJS(): boolean;

/**
 * 检查是否在 [Taro 3](https://taro.js.org/) 中。
 *
 * @returns 返回检查结果
 */
export declare function inTaro(): boolean;

declare type InvertResult<T extends Record<EnumKey, EnumValue>> = {
    [P in AllValues<T>['value']]: Extract<AllValues<T>, {
        value: P;
    }>['label'];
};

/**
 * 检查是否在微信内置浏览器中。
 *
 * @returns 返回检查结果
 * @example
 * ```typescript
 * if (inWechatWebView()) {
 *   console.log('你在微信内置浏览器中')
 * }
 * ```
 */
export declare function inWechatWebView(): boolean;

/**
 * 检测传入值是否是 Blob URL，也称 Object URL。
 *
 * @public
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isBlobUrl('http://foo.bar') // => false
 * isBlobUrl('blob:https://example.org/9115d58c-bcda-ff47-86e5-083e9a215304') // => true
 * ```
 */
export declare function isBlobUrl(value: string): boolean;

/**
 * 检测传入的值是否是合法的中国大陆居民 `18` 位身份证号码。
 *
 * @public
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isChineseIDCardNumber('123456') // => false
 * ```
 */
export declare function isChineseIDCardNumber(value: string): boolean;

/**
 * 检测传入值是否是 Cuid。
 *
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isCuid('1') // => false
 * isCuid('cjld2cjxh0000qzrmn831i7rn') // => true
 * ```
 * @see https://github.com/paralleldrive/cuid
 */
export declare function isCuid(value: string): boolean;

/**
 * 检测传入值是否是 Cuid2。
 *
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isCuid2('1') // => false
 * isCuid2('tz4a98xxat96iws9zmbrgj3a') // => true
 * ```
 * @see https://github.com/paralleldrive/cuid2
 */
export declare function isCuid2(value: string, options?: IsCuid2Options): boolean;

export declare interface IsCuid2Options {
    /**
     * @default 24
     */
    minLength?: number;
    /**
     * @default 24
     */
    maxLength?: number;
}

/**
 * 检测传入值是否是 Data URL。
 *
 * @public
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isDataUrl('http://foo.bar') // => false
 * isDataUrl('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D') // => true
 * ```
 */
export declare function isDataUrl(value: string): boolean;

/**
 * 检查 HTML 元素是否可见。
 *
 * @param el 要检查的 HTML 元素
 */
export declare function isElementVisible(el: HTMLElement): boolean;

/**
 * 检测传入值是否是邮箱地址。
 *
 * @public
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isEmail('xx@gmail.com') // => true
 * isEmail('http://foo.bar') // => false
 * ```
 */
export declare function isEmail(value: string): boolean;

/**
 Returns a boolean for whether the two given types are equal.

 @link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
 @link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796

 Use-cases:
 - If you want to make a conditional branch based on the result of a comparison of two types.

 @example
 ```
 import type {IsEqual} from 'type-fest';

 // This type returns a boolean for whether the given array includes the given item.
 // `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal.
 type Includes<Value extends readonly any[], Item> =
 	Value extends readonly [Value[0], ...infer rest]
 		? IsEqual<Value[0], Item> extends true
 			? true
 			: Includes<rest, Item>
 		: false;
 ```

 @category Type Guard
 @category Utilities
 */
declare type IsEqual<A, B> =
	(<G>() => G extends A & G | G ? 1 : 2) extends
	(<G>() => G extends B & G | G ? 1 : 2)
		? true
		: false;

declare type IsEqual_2<A, B> = (<G>() => G extends A ? 1 : 2) extends <G>() => G extends B ? 1 : 2 ? true : false;

/**
 * 判断 `T` 是否是 `never` 类型。
 *
 * @public
 * @example
 * ```typescript
 * type X = IsNever<never>
 * // => true
 * ```
 */
declare type IsNever<T> = [T] extends [never] ? true : false;

/**
 * 检查 `value` 是否是数值，需要注意的是 `Infinity`、`-Infinity`、`NaN` 不被认为是数值。
 *
 * @param value 要检查的值
 * @returns 返回检查结果
 * @example
 * ```typescript
 * isNumeric(1) // => true
 * isNumeric('1') // => true
 * ```
 */
export declare function isNumeric(value: any): value is number | string;

/**
 * 检测传入的值是否可能是中国的手机号码。
 *
 * @public
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isPossibleChineseMobilePhoneNumber('10086') // => false
 * isPossibleChineseMobilePhoneNumber('18087030088') // => true
 * ```
 */
export declare function isPossibleChineseMobilePhoneNumber(value: string | number): boolean;

/**
 * 检查 `value` 是否像 `Promise`。
 *
 * @param value 要检查的值
 * @returns 返回检查结果
 * @example
 * ```typescript
 * isPromiseLike(Promise.resolve()) // => true
 * ```
 */
export declare function isPromiseLike(value: any): value is PromiseLike<any>;

/**
 Returns a boolean for whether the string is screaming snake case.
 */
declare type IsScreamingSnakeCase<Value extends string> = Value extends Uppercase<Value>
	? Includes<SplitIncludingDelimiters<Lowercase<Value>, '_'>, '_'> extends true
		? true
		: false
	: false;

/**
 * 对 `value is T` 的封装。
 */
export declare function isType<T>(value: any): value is T;

/**
 * 检测传入值是否是 URL。
 *
 * @public
 * @param value 要检测的值
 * @returns 返回检测结果
 * @example
 * ```typescript
 * isUrl('foo.bar') // => false
 * isUrl('http://foo.bar') // => true
 * ```
 */
export declare function isUrl(value: string): boolean;

/**
 Matches a JSON array.

 @category JSON
 */
declare type JsonArray = JsonValue[] | readonly JsonValue[];

/**
 Matches a JSON object.

 This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`.

 @category JSON
 */
declare type JsonObject = {[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined};

/**
 * 发起 jsonp 请求。
 *
 * @param url 请求地址
 * @param keyOfCallbackName 回调函数名的键
 */
export declare function jsonp<T>(url: string, keyOfCallbackName?: string): Promise<T>;

/**
 Matches any valid JSON primitive value.

 @category JSON
 */
declare type JsonPrimitive = string | number | boolean | null;

/**
 Matches any valid JSON value.

 @see `Jsonify` if you need to transform a type to one that is assignable to `JsonValue`.

 @category JSON
 */
declare type JsonValue = JsonPrimitive | JsonObject | JsonArray;

export declare type KeyOfRawData<TRawData extends RawData> = keyof ElementOfRawData<TRawData>;

/**
 * 同 {@link https://lodash.com/docs/4.17.15#keys | keys}，不过采用了严格的类型定义。
 *
 * @public
 */
export declare const keysStrict: <T extends Record<any, any>>(object: T) => Array<keyof T>;

declare type List<T extends Record<EnumKey, EnumValue>> = Array<{
    [P in keyof T]: {
        label: P;
        value: T[P];
    };
}[keyof T]>;

/**
 Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.

 Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.

 This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore.

 @example
 ```
 import type {LiteralUnion} from 'type-fest';

 // Before

 type Pet = 'dog' | 'cat' | string;

 const pet: Pet = '';
 // Start typing in your TypeScript-enabled IDE.
 // You **will not** get auto-completion for `dog` and `cat` literals.

 // After

 type Pet2 = LiteralUnion<'dog' | 'cat', string>;

 const pet: Pet2 = '';
 // You **will** get auto-completion for `dog` and `cat` literals.
 ```

 @category Type
 */
declare type LiteralUnion<
	LiteralType,
	BaseType extends Primitive,
> = LiteralType | (BaseType & Record<never, never>);

/**
 * 加载 CSS 样式，支持链接和内容。
 *
 * @param urlOrContent 链接或内容
 * @example
 * ```typescript
 * loadCss('https://foo.bar/global.css')
 * loadCss(`body { font-size: 20px; }`)
 * ```
 */
export declare function loadCss(urlOrContent: string): Promise<LoadCssResult>;

export declare interface LoadCssResult {
    /**
     * 样式元素。
     */
    el: HTMLStyleElement;
    /**
     * 销毁函数。
     */
    destroy: () => void;
}

/**
 * 加载图片、代码、样式等资源。
 *
 * @public
 * @param url 要加载的资源地址
 * @param options 选项
 * @returns 返回各资源的 HTML 元素组成的数组
 * @example
 * ```typescript
 * loadResource([
 *   'https://foo.bar/all.js',
 *   'https://foo.bar/all.css',
 *   'https://foo.bar/logo.png',
 *   {
 *     type: LoadResourceUrlType.js,
 *     path: 'https://s1.foo.bar/js/full',
 *     alternatePath: 'https://s2.foo.bar/js/full',
 *   },
 * ]).then(() => {
 *   // 资源加载完成后的操作
 * })
 * ```
 */
export declare function loadResource(url: string | LoadResourceUrl | Array<string | LoadResourceUrl>, options?: LoadResourceOptions): Promise<Array<LoadResourceElement>>;

export declare type LoadResourceElement = HTMLScriptElement | HTMLLinkElement | HTMLStyleElement | HTMLImageElement;

export declare type LoadResourceHook = (el: LoadResourceElement) => any;

export declare interface LoadResourceOptions {
    /** 钩子 */
    hook?: LoadResourceHook;
}

/**
 * 资源地址。
 *
 * @public
 */
export declare interface LoadResourceUrl {
    /** 资源类型 */
    type: LoadResourceUrlType;
    /** 资源路径 */
    path: string;
    /** 备用资源路径 */
    alternatePath?: string;
    /** 钩子 */
    hook?: LoadResourceHook;
}

/**
 * 资源类型。
 *
 * @public
 */
export declare enum LoadResourceUrlType {
    /** 样式资源 */
    css = "css",
    /** 样式文本 */
    cssText = "cssText",
    /** 代码资源 */
    js = "js",
    /** 代码文本 */
    jsText = "jsText",
    /** 图片资源 */
    img = "img"
}

/**
 * 本地存储增强。
 *
 * 已兼容小程序。
 */
export declare class LocalStoragePlus<T extends JsonValue> {
    private options;
    /**
     * 本地存储键名前缀。
     */
    private static prefix;
    /**
     * 获取完全的键名。
     *
     * @param key 键名
     */
    private static getFullKey;
    /**
     * 设置本地存储。
     *
     * @param key 键
     * @param value 值
     * @param options 选项
     */
    static set<T extends JsonValue>(key: string, value: T | ((prevValue: T | null) => T), options?: LocalStoragePlusSetOptions): void;
    /**
     * 获取本地存储。
     *
     * @param key 键
     * @param options 选项
     */
    static get<T extends JsonValue>(key: string, options?: LocalStoragePlusGetOptions): T | null;
    /**
     * 是否存在本地存储。
     *
     * @param key 键
     * @param options 选项
     */
    static has(key: string, options?: LocalStoragePlusGetOptions): boolean;
    /**
     * 删除本地存储。
     *
     * @param key 键
     */
    static remove(key: string): void;
    /**
     * 清空本地存储。
     */
    static clear(): void;
    /**
     * 将本地存储的值增加给定值，若本地存储不存在，则初始化为 `0` 后操作。
     *
     * @param key 键
     * @param value 增加值，默认 `1`
     * @param options 选项
     */
    static increase(key: string, value?: number, options?: LocalStoragePlusSetOptions): void;
    /**
     * 将本地存储的值减少给定值，若本地存储不存在，则初始化为 `0` 后操作。
     *
     * @param key 键
     * @param value 减小值，默认 `1`
     * @param options 选项
     */
    static decrease(key: string, value?: number, options?: LocalStoragePlusSetOptions): void;
    constructor(options: LocalStoragePlusOptions);
    /**
     * 设置值。
     *
     * @param value 值
     * @param options 选项
     */
    set(value: T | ((prevValue: T | null) => T), options?: LocalStoragePlusSetOptions): void;
    /**
     * 获取值。
     *
     * @param options 选项
     */
    get(options?: LocalStoragePlusGetOptions): T | null;
    /**
     * 是否存在值。
     *
     * @param options 选项
     */
    has(options?: LocalStoragePlusGetOptions): boolean;
    /**
     * 删除值。
     */
    remove(): void;
    /**
     * 自增。
     *
     * @param value 增加值
     * @param options 选项
     */
    increase(value?: number, options?: LocalStoragePlusSetOptions): void;
    /**
     * 自减。
     *
     * @param value 减少值
     * @param options 选项
     */
    decrease(value?: number, options?: LocalStoragePlusSetOptions): void;
}

export declare interface LocalStoragePlusGetOptions {
    /** 标签 */
    tag?: string | number;
}

export declare interface LocalStoragePlusOptions {
    /** 存储键 */
    key: string;
}

export declare interface LocalStoragePlusSetOptions {
    /** 存活时间(毫秒) */
    ttl?: number;
    /** 标签 */
    tag?: string | number;
}

export declare function loopUntil<T>(fn: () => AsyncOrSync<T>, condition: (res: T) => AsyncOrSync<boolean>, options: LoopUntilOptions): Promise<T>;

export declare function loopUntil(condition: () => AsyncOrSync<boolean>, options: LoopUntilOptions): Promise<void>;

export declare interface LoopUntilOptions {
    /**
     * 重试延时，为数组时随机挑选一个。
     */
    retryDelay: OneOrMore<number>;
    /**
     * 重试限制。
     */
    retryLimit?: number;
}

export declare class LoopUntilRetryLimitExceededError extends Error {
}

/**
 * 构造条件数组，即允许一个数组的项出现 false 值，且最终 false 值的项目会被排除。
 *
 * @param array 数组
 * @param childrenKey 子数组键
 */
export declare function makeConditionalArray<T extends any, K extends keyof T>(array: Array<ConditionalArrayItem<T, K>>, childrenKey: K): T[];

/**
 * 构造条件数组，即允许一个数组的项出现 false 值，且最终 false 值的项目会被排除。
 *
 * @param array 数组
 */
export declare function makeConditionalArray<T extends any>(array: Array<ConditionalArrayItem<T>>): T[];

export declare namespace makeConditionalArray {
    var fork: typeof makeConditionalArrayFork;
}

declare function makeConditionalArrayFork<T extends any>(): (array: Array<ConditionalArrayItem<T>>) => T[];

declare function makeConditionalArrayFork<T extends any, K extends keyof T>(childrenKey: K): (array: Array<ConditionalArrayItem<T, K>>) => T[];

declare function makeDevOrProd(getNodeEnv: () => 'dev' | 'prod'): {
    <R, T extends R = R, F extends () => R = () => R>(devValue: T | F, prodValue: T | F): R;
    /**
     * 构造 devOrProd。
     */
    make: typeof makeDevOrProd;
};

/**
 * 构造枚举数据。
 *
 * @param map 枚举映射数据
 */
export declare function makeEnum<T extends EnumMap>(map: T): EnumResult<T>;

/**
 * 根据给定的字符串计算 MD5 值。
 *
 * @param string 要进行 MD5 计算的字符串
 * @param key 用于创建 HMAC 的密码
 * @param raw 是否输出原始数据
 * @returns 返回计算的 MD5 结果
 * @example
 * ```typescript
 * md5('龙') // => '682570a229cbd3d67e76ad99b3152060'
 * md5('龙', '🐉') // => '293a529180e8b949aa820b9d071f31fa'
 * ```
 */
export declare function md5(string: string, key?: string, raw?: boolean): string;

/** Merge 2 types, properties types from the latter override the ones defined on the former type */
declare type Merge<M, N> = Omit<M, keyof N> & N;

export declare type MiniProgramApi = WechatMiniprogram.Wx & {
    /** 小程序品牌 */
    readonly $brand: MiniProgramBrand;
};

export declare type MiniProgramBrand = typeof brands[number];

/**
 * 小程序链接。
 */
export declare class MiniProgramUrl {
    private payload;
    constructor(payload: MiniProgramUrlInput);
    private getPath;
    update(payload: Partial<MiniProgramUrlJsonInput>): this;
    toJson(): MiniProgramUrlJsonInput;
    toString(): string;
    toWxOpenLaunchWeappAttrs(): {
        username: string | undefined;
        path: string;
        envVersion: MiniProgramUrlVersion | undefined;
        extraData: string | undefined;
    };
    toWxNavigateToMiniProgramParams(): {
        appId: string | undefined;
        path: string;
        envVersion: MiniProgramUrlVersion | undefined;
        extraData: any;
    };
    static is(value: MiniProgramUrlStringInput): value is MiniProgramUrlStringInput;
}

export declare type MiniProgramUrlInput = MiniProgramUrlStringInput | MiniProgramUrlJsonInput;

export declare type MiniProgramUrlJsonInput = {
    /** 提供商 */
    provider?: MiniProgramUrlProvider;
    /** APPID */
    appId?: string;
    /** 原始ID */
    rawId?: string;
    /** 版本 */
    version?: MiniProgramUrlVersion;
    /** 路径 */
    path?: string;
    /** 查询参数 */
    query?: Record<string, any>;
    /** 额外数据 */
    data?: any;
};

export declare type MiniProgramUrlProvider = 'wechat';

export declare type MiniProgramUrlStringInput = `mp://${string}`;

export declare type MiniProgramUrlVersion = 'release' | 'develop' | 'trial';

/**
 * 原地移动数组中的元素。
 *
 * @param arr 要处理的数组
 * @param from 要移动元素的索引
 * @param to 要移动到的位置索引
 * @returns 返回移动后的数组
 * @example
 * ```typescript
 * move([1, 2, 3], 0, 1) // => [2, 1, 3]
 * ```
 */
export declare function move<T>(arr: T[], from: number, to: number): T[];

/**
 * 原地下移数组中的某个元素。
 *
 * @param arr 要处理的数组
 * @param from 要移动元素的索引
 * @param step 移动步值
 * @returns 返回移动后的数组
 * @example
 * ```typescript
 * moveDown([1, 2, 3], 0) // => [2, 1, 3]
 * moveDown([1, 2, 3], 0, 2) // => [2, 3, 1]
 * ```
 */
export declare function moveDown<T>(arr: T[], from: number, step?: number): T[];

/**
 * 原地置底数组中的某个元素。
 *
 * @param arr 要处理的数组
 * @param from 要移动元素的索引
 * @returns 返回移动后的数组
 * @example
 * ```typescript
 * moveToBottom([1, 2, 3], 0) // => [2, 3, 1]
 * ```
 */
export declare function moveToBottom<T>(arr: T[], from: number): T[];

/**
 * 原地置顶数组中的某个元素。
 *
 * @param arr 要处理的数组
 * @param from 要移动元素的索引
 * @returns 返回移动后的数组
 * @example
 * ```typescript
 * moveToTop([1, 2, 3], 2) // => [3, 1, 2]
 * ```
 */
export declare function moveToTop<T>(arr: T[], from: number): T[];

/**
 * 原地上移数组中的某个元素。
 *
 * @param arr 要处理的数组
 * @param from 要移动元素的索引
 * @param step 移动步值
 * @returns 返回移动后的数组
 * @example
 * ```typescript
 * moveUp([1, 2, 3], 2) // => [1, 3, 2]
 * moveUp([1, 2, 3], 2, 2) // => [3, 1, 2]
 * ```
 */
export declare function moveUp<T>(arr: T[], from: number, step?: number): T[];

/**
 * 获取毫秒值。
 *
 * @param value 值
 * @param unit 单位
 * @param returnSeconds 是否返回秒值
 */
export declare function ms(value: number, unit: MsUnit, returnSeconds?: boolean): number;

/**
 * 获取毫秒值。
 *
 * @param value 值
 * @param returnSeconds 是否返回秒值
 */
export declare function ms(value: MsValue, returnSeconds?: boolean): number;

export declare type MsNumberValue = number;

export declare type MsStringValue = `${number}${MsUnit}`;

export declare type MsUnit = 'y' | 'w' | 'd' | 'h' | 'm' | 's' | 'ms';

export declare type MsValue = MsNumberValue | MsStringValue;

/** Similar to the builtin Omit, but checks the filter strictly. */
declare type OmitStrict<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

/**
 * 同 {@link https://lodash.com/docs/4.17.15#omit | omit}，不过采用了严格的类型定义。
 *
 * @public
 */
export declare const omitStrict: <T extends Record<any, any>, K extends keyof T>(object: T, ...paths: Array<OneOrMore<K>>) => OmitStrict<T, K>;

/**
 * 同一时间对函数的调用只会触发一次运行。
 *
 * @param fn 函数
 * @returns 返回函数调用结果
 */
export declare function onceMeanwhile<TFunc extends AnyAsyncFunction>(fn: TFunc): TFunc;

/**
 * 同 `T | T[]`。
 *
 * @public
 * @example
 * ```typescript
 * type X = OneOrMore<number> // => number | number[]
 * ```
 */
declare type OneOrMore<T> = T | T[];

/**
 * 允许指定一个或多个规则对数据进行排序。
 *
 * @param data 要排序的数据
 * @param rules 一个或多个规则
 * @returns 返回排序后的数据
 * @example
 * ```ts
 * orderByRules(
 *   ['x', 'xyz', 'xy'],
 *   {
 *     iteratee: item => item.length,
 *     type: 'desc',
 *   },
 * )
 * // => ['xyz', 'xy', 'x']
 * ```
 */
export declare function orderByRules<T>(data: T[], rules: OneOrMore<OrderByRulesRule<T>>): T[];

export declare type OrderByRulesRule<T> = OrderByRulesRuleObject<T> | OrderByRulesRuleArray<T>;

export declare type OrderByRulesRuleArray<T> = [
/**
 * 迭代函数。
 *
 * @param item 项目
 * @returns 返回参与排序计算的值
 */
iteratee: (item: T) => any,
/**
 * 类型。
 */
type: 'asc' | 'desc'
];

export declare type OrderByRulesRuleObject<T> = {
    /**
     * 迭代函数。
     *
     * @param item 项目
     * @returns 返回参与排序计算的值
     */
    iteratee: (item: T) => any;
    /**
     * 类型。
     */
    type: 'asc' | 'desc';
};

export declare type PackedData<TRawData extends RawData> = {
    readonly _k: Array<KeyOfRawData<TRawData>>;
    readonly _v: Array<Array<ValueOfRawData<TRawData>>>;
    readonly _s: string;
};

/**
 * 解析 Data URL。
 *
 * @param dataUrl 要解析的 Data URL
 * @returns 返回结果
 */
export declare function parseDataUrl(dataUrl: string): ParseDataUrlResult;

export declare interface ParseDataUrlResult {
    mimeType: string;
    parameters: Record<LiteralUnion<'name' | 'charset' | 'base64', string>, string>;
    content: string;
    base64: boolean;
}

export declare interface ParsedFileRichUrl {
    url: string;
    file: File;
}

export declare interface ParsedRichUrl<TDesc> {
    url: string;
    desc?: TDesc;
}

/**
 * 解析 url 查询字符串。
 *
 * 兼容以 `?` 开头的查询字符串，因此你可以直接传入 `location.search` 的值。
 *
 * @param query 查询字符串
 * @param options 选项
 * @returns 返回 url 查询参数
 * @example
 * ```typescript
 * parseUrlQueryString('x=1&y=z') // => { x: '1', y: 'z' }
 * ```
 */
export declare function parseUrlQueryString<T extends Record<string, string> = Record<string, string>>(query: string, options?: CreateUrlQueryStringOptions): T;

/**
 Converts a string literal to pascal-case.

 @example
 ```
 import type {PascalCase} from 'type-fest';

 // Simple

 const someVariable: PascalCase<'foo-bar'> = 'FooBar';

 // Advanced

 type PascalCaseProps<T> = {
 	[K in keyof T as PascalCase<K>]: T[K]
 };

 interface RawOptions {
 	'dry-run': boolean;
 	'full_family_name': string;
 	foo: number;
 }

 const dbResult: CamelCasedProperties<ModelProps> = {
 	DryRun: true,
 	FullFamilyName: 'bar.js',
 	Foo: 123
 };
 ```

 @category Change case
 @category Template literal
 */
declare type PascalCase<Value, Options extends CamelCaseOptions = {preserveConsecutiveUppercase: true}> = CamelCase<Value, Options> extends string
	? Capitalize<CamelCase<Value, Options>>
	: CamelCase<Value, Options>;

/**
 * 转换文本为没有分隔符的大写单词字符串。
 *
 * @param text 要转换的文本
 * @returns 返回结果
 * @example
 * ```typescript
 * pascalCase('test string')
 * // => TestString
 * ```
 */
export declare function pascalCase<T extends string>(text: T): PascalCase<T>;

/**
 * 选中对象中的所有类型上可见的属性并返回。
 *
 * @param data 对象
 * @param keys 属性列表
 */
export declare function pickAll<T extends Record<string, any>, K extends keyof T, Tuple extends ReadonlyArray<K>>(data: T, keys: TupleOf<Tuple, K>): T;

/**
 * 同 {@link https://lodash.com/docs/4.17.15#pick | pick}，不过采用了严格的类型定义。
 *
 * @public
 */
export declare const pickStrict: <T extends Record<any, any>, K extends keyof T>(object: T, ...paths: Array<OneOrMore<K>>) => Pick<T, K>;

/**
 * 给定大小获取占位猫咪图片。
 *
 * @param size 大小
 * @returns 返回占位图地址
 */
export declare function placeKitten(size: number): string;

/**
 * 给定宽高获取占位猫咪图片。
 *
 * @param width 宽度
 * @param height 高度
 * @returns 返回占位图地址
 */
export declare function placeKitten(width: number, height: number): string;

/**
 * `Promise.all(data.map(callback))` 的简写。
 *
 * @param list 列表数据
 * @param callback 回调
 * @example
 * ```typescript
 * const res = await pMap(
 *   [1, 2],
 *   i => Promise.resolve(i),
 * )
 * // => [1, 2]
 * ```
 */
export declare function pMap<T, R>(list: T[], callback: (item: T, index: number, list: T[]) => R | PromiseLike<R>): Promise<R[]>;

/**
 * 准备数据。
 *
 * @param getter 数据源
 */
export declare function prepareData<T extends Record<string, () => any>>(getter: T): Promise<{
    [K in keyof T]: Awaited<ReturnType<T[K]>>;
}>;

/**
 Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).

 @category Type
 */
declare type Primitive =
	| null
	| undefined
	| string
	| number
	| boolean
	| symbol
	| bigint;

/** Essentials */
declare type Primitive_2 = string | number | boolean | bigint | symbol | undefined | null;

export declare type RawData<TRawObjectData extends RawObjectData = RawObjectData> = TRawObjectData | RawListData<TRawObjectData>;

export declare type RawListData<TRawObjectData extends RawObjectData = RawObjectData> = TRawObjectData[];

export declare type RawObjectData = Record<any, any>;

/**
 * 读取给定文件的内容。
 *
 * @public
 * @param file 要读取的文件
 * @returns 返回各种内容类型的读取器
 * @example
 * ```typescript
 * const file = new File(['{"x":1}'], 'x.json')
 * const reader = readFile(file)
 * console.log(await reader.text()) // => '{"x":1}'
 * console.log(await reader.json()) // => {x: 1}
 * ```
 */
export declare function readFile(file: File): ReadFileReader;

/**
 * 各种内容类型的读取器。
 *
 * @public
 */
export declare interface ReadFileReader {
    /**
     * 读取并返回文本内容。
     */
    text(): Promise<string>;
    /**
     * 读取并返回 JSON 内容。
     */
    json<T>(): Promise<T>;
    /**
     * 读取并返回 dataURL 内容。
     */
    dataUrl(): Promise<string>;
    /**
     * 读取并返回 base64 内容。
     */
    base64(): Promise<string>;
    /**
     * 读取并返回 ArrayBuffer 内容。
     */
    arrayBuffer(): Promise<ArrayBuffer>;
}

/**
 * 从字符串中移除空白字符。
 *
 * @param value 要操作的字符串
 * @returns 返回移除空白字符后的字符串
 */
export declare function removeBlankChars(value: string): string;

/**
 * 从字符串中移除 emoji 字符。
 *
 * @param value 要操作的字符串
 * @returns 返回移除 emoji 字符后的字符串
 */
export declare function removeEmojiChars(value: string): string;

declare type RemoveLastCharacter<Sentence extends string, Character extends string> = Sentence extends `${infer LeftSide}${Character}`
	? SkipEmptyWord<LeftSide>
	: never;

/**
 * 从字符串中移除非单词字符（移除非英文单词、阿拉伯数字、汉字的所有字符）。
 *
 * @param value 要操作的字符串
 * @returns 返回移除非单词字符后的字符串
 */
export declare function removeNonWordChars(value: string): string;

/** Like Required but recursive */
declare type RequiredDeep<T> = T extends Builtin
? NonNullable<T>
: T extends Map<infer K, infer V>
? Map<RequiredDeep<K>, RequiredDeep<V>>
: T extends ReadonlyMap<infer K, infer V>
? ReadonlyMap<RequiredDeep<K>, RequiredDeep<V>>
: T extends WeakMap<infer K, infer V>
? WeakMap<RequiredDeep<K>, RequiredDeep<V>>
: T extends Set<infer U>
? Set<RequiredDeep<U>>
: T extends ReadonlySet<infer U>
? ReadonlySet<RequiredDeep<U>>
: T extends WeakSet<infer U>
? WeakSet<RequiredDeep<U>>
: T extends Promise<infer U>
? Promise<RequiredDeep<U>>
: T extends {}
? {
    [K in keyof T]-?: RequiredDeep<T[K]>;
}
: NonNullable<T>;

/**
 * 富链接，同普通链接相比，富链接可包含一些描述信息。
 *
 * 结构描述：
 * ```text
 * rich://{"url":"***","desc":"***"}
 * ```
 */
export declare class RichUrl {
    /**
     * 标识符。
     */
    private static readonly identity;
    /**
     * 检查是否是富链接。
     *
     * @param value 要检查的值
     * @returns 返回检查结果
     * @example
     * ```typescript
     * RichUrl.check('http://www.google.com') // => false
     * ```
     */
    static check(value: any): value is string;
    /**
     * 创建富链接。
     *
     * @param url 普通链接
     * @param desc 描述信息
     * @returns 返回创建的富链接
     */
    static build(url: string, desc?: any): string;
    /**
     * 解析富链接。非富链接的会直接将其值作为 url 返回。
     *
     * @param richUrl 富链接
     * @returns 返回解析结果
     */
    static parse<TDesc>(richUrl: string): ParsedRichUrl<TDesc>;
    /**
     * 转换数据中的富链接。
     *
     * @param data 数据
     * @param callback 回调
     * @returns 返回转换后的数据
     */
    static transform<TData, TDesc>(data: TData, callback: (parsedRichUrl: ParsedRichUrl<TDesc>, data: TData) => Promise<string>): Promise<TData>;
    /**
     * 将文件转换为文件富链接。
     *
     * @param file 要转换的文件
     * @returns 返回转换后的文件富链接
     */
    static fromFile(file: File): string;
    /**
     * 将文件富链接转换为文件和普通链接。
     *
     * @param richUrl 要转换的文件富链接
     * @returns 返回转换后的文件和普通链接
     */
    static toFile(richUrl: string | ParsedRichUrl<File>): Promise<ParsedFileRichUrl>;
    /**
     * 转换数据中的文件富链接。
     *
     * @param data 数据
     * @param callback 回调
     * @returns 返回转换后的数据
     */
    static transformFile<TData>(data: TData, callback: (parsedFileRichUrl: ParsedFileRichUrl) => Promise<string>): Promise<TData>;
}

/**
 * 回转 13 位替换式密码。
 *
 * @param str 原文
 * @see https://zh.wikipedia.org/wiki/ROT13
 * @example
 * ```typescript
 * rot13('hello world') // => 'uryyb jbeyq'
 * ```
 */
export declare function rot13(str: string): string;

/**
 * 保留 n 位小数下的 x 舍 y 入。
 *
 * @param number 数值
 * @param precision 精度
 * @param threshold 舍入阈值，等于大于这个值时入，小于这个值时舍
 */
export declare function roundTo(number: number, precision?: number, threshold?: number): number;

/**
 * 以数组的方式返回函数执行的结果，如果函数返回一个异步操作，将会执行该异步操作并将其结果作为函数执行的结果返回。
 *
 * @param fn 要执行的函数
 * @returns 返回 `[错误信息, 结果数据]`，错误信息为 `null` 表示没有错误
 * @example
 * ```typescript
 * // 函数执行成功
 * const [err, res] = await run(() => 'ok') // => [null, 'ok']
 * const [err, res] = await run(async () => 'ok') // => [null, 'ok']
 *
 * // 函数执行出错
 * const [err, res] = await run(() => { throw 'err' }) // => ['err']
 * const [err, res] = await run(async () => { throw 'err' }) // => ['err']
 * ```
 */
export declare function run<T extends () => any, R extends ReturnType<T>>(fn: T): Promise<[
unknown,
R extends PromiseLike<any> ? R extends PromiseLike<infer X> ? X : unknown : R
]>;

/**
 * 从集合中随机获得一个元素的迭代值。
 *
 * @param collection 集合
 * @param iteratee 迭代函数
 */
export declare function sampleBy<T, X>(collection: T[], iteratee: (element: T, index: number) => X): X | undefined;

export declare function sampleBy<T extends Record<any, any>, X>(collection: T, iteratee: <K extends keyof T>(value: T[K], key: K) => X): X | undefined;

/**
 * 从集合中随机获得一个元素的索引（数组）或键（对象）。
 *
 * @param collection 集合
 */
export declare function sampleIndex<T>(collection: T[]): number | undefined;

export declare function sampleIndex<T extends Record<any, any>>(collection: T): keyof T | undefined;

/**
 * @param selectors      One or more CSS selectors separated by commas
 * @param [baseElement]  The element to look inside of
 * @return               The element found, if any
 */
export declare function selectElement<Selector extends string, TElement extends Element = ParseSelector<Selector, HTMLElement>>(selectors: Selector | Selector[], baseElement?: ParentNode): TElement | undefined;

export declare function selectElement<TElement extends Element = HTMLElement>(selectors: string | string[], baseElement?: ParentNode): TElement | undefined;

/**
 * @param selectors       One or more CSS selectors separated by commas
 * @param [baseElements]  The element or list of elements to look inside of
 * @return                An array of elements found
 */
export declare function selectElementAll<Selector extends string, TElement extends Element = ParseSelector<Selector, HTMLElement>>(selectors: Selector | Selector[], baseElements?: BaseElements): TElement[];

export declare function selectElementAll<TElement extends Element = HTMLElement>(selectors: string | string[], baseElements?: BaseElements): TElement[];

/**
 * @param selectors      One or more CSS selectors separated by commas
 * @param [baseElement]  The element to look inside of
 * @return               Whether it's been found
 */
export declare function selectElementExists(selectors: string | string[], baseElement?: ParentNode): boolean;

/**
 * @param selectors      One or more CSS selectors separated by commas
 * @param [baseElement]  The element to look inside of
 * @return               The element found, if any
 */
export declare function selectElementLast<Selector extends string, TElement extends Element = ParseSelector<Selector, HTMLElement>>(selectors: Selector | Selector[], baseElement?: ParentNode): TElement | undefined;

export declare function selectElementLast<TElement extends Element = HTMLElement>(selectors: string | string[], baseElement?: ParentNode): TElement | undefined;

/**
 * 信号。
 */
export declare function signal<T>(): SignalResult<T>;

export declare interface SignalResult<T> {
    set(value: T): void;
    throw(error: any): void;
    get(): Promise<T>;
}

declare type SkipEmptyWord<Word extends string> = Word extends '' ? [] : [Word];

/**
 Convert a string literal to snake-case.

 This can be useful when, for example, converting a camel-cased object property to a snake-cased SQL column name.

 @example
 ```
 import type {SnakeCase} from 'type-fest';

 // Simple

 const someVariable: SnakeCase<'fooBar'> = 'foo_bar';

 // Advanced

 type SnakeCasedProperties<T> = {
 	[K in keyof T as SnakeCase<K>]: T[K]
 };

 interface ModelProps {
 	isHappy: boolean;
 	fullFamilyName: string;
 	foo: number;
 }

 const dbResult: SnakeCasedProperties<ModelProps> = {
 	'is_happy': true,
 	'full_family_name': 'Carla Smith',
 	foo: 123
 };
 ```

 @category Change case
 @category Template literal
 */
declare type SnakeCase<Value> = DelimiterCase<Value, '_'>;

/**
 Unlike a simpler split, this one includes the delimiter splitted on in the resulting array literal. This is to enable splitting on, for example, upper-case characters.

 @category Template literal
 */
declare type SplitIncludingDelimiters<Source extends string, Delimiter extends string> = SplitIncludingDelimiters_<UpperCaseToLowerCase<Source>, Delimiter>;

declare type SplitIncludingDelimiters_<Source extends string, Delimiter extends string> =
	Source extends '' ? [] :
		Source extends `${infer FirstPart}${Delimiter}${infer SecondPart}` ?
			(
				Source extends `${FirstPart}${infer UsedDelimiter}${SecondPart}`
					? UsedDelimiter extends Delimiter
						? Source extends `${infer FirstPart}${UsedDelimiter}${infer SecondPart}`
							? [...SplitIncludingDelimiters<FirstPart, Delimiter>, UsedDelimiter, ...SplitIncludingDelimiters<SecondPart, Delimiter>]
							: never
						: never
					: never
			) :
			[Source];

/**
 Takes the result of a splitted string literal and recursively concatenates it together into the desired casing.

 It receives `UsedWordSeparators` and `UsedUpperCaseCharacters` as input to ensure it's fully encapsulated.

 @see SplitIncludingDelimiters
 */
declare type StringArrayToDelimiterCase<Parts extends readonly any[], Start extends boolean, UsedWordSeparators extends string, UsedUpperCaseCharacters extends string, Delimiter extends string> =
	Parts extends [`${infer FirstPart}`, ...infer RemainingParts]
		? `${StringPartToDelimiterCase<FirstPart, Start, UsedWordSeparators, UsedUpperCaseCharacters, Delimiter>}${StringArrayToDelimiterCase<RemainingParts, false, UsedWordSeparators, UsedUpperCaseCharacters, Delimiter>}`
		: Parts extends [string]
			? string
			: '';

/**
 Format a specific part of the splitted string literal that `StringArrayToDelimiterCase<>` fuses together, ensuring desired casing.

 @see StringArrayToDelimiterCase
 */
declare type StringPartToDelimiterCase<StringPart extends string, Start extends boolean, UsedWordSeparators extends string, UsedUpperCaseCharacters extends string, Delimiter extends string> =
	StringPart extends UsedWordSeparators ? Delimiter :
		Start extends true ? Lowercase<StringPart> :
			StringPart extends UsedUpperCaseCharacters ? `${Delimiter}${Lowercase<StringPart>}` :
				StringPart;

/**
 * 字符串模板。
 */
export declare class StringTemplate {
    /**
     * 渲染字符串模板。语法：
     *
     * - 用 `{key}` 直接替换；
     * - 用 `{key#10}` 直接替换，取前10个字符省略；
     * - 用 `{key:param1,param2}` 执行函数替换；
     * - 用 `{{key==='test'?'hi':'hello'}}` 执行代码替换（内部使用 eval 实现，需开启选项里的 `code` 参数）。
     *
     * @param template 要渲染的模板
     * @param data 渲染数据
     * @param options 渲染选项
     * @returns 返回渲染后字符串
     */
    static render(template: string, data: Record<string, any>, options?: StringTemplateRenderOptions): string;
    /** 判断是否有代码块 */
    static hasCodeBlock(template: string): boolean;
}

export declare interface StringTemplateRenderOptions {
    /** 是否启用代码渲染，需环境支持 eval */
    code?: boolean;
    /** 是否仅代码渲染 */
    onlyCode?: boolean;
    /** 替换前操作 */
    beforeReplace?: (value: string, key: string) => string;
}

export declare interface SubmitActionPayload<T = string> {
    /**
     * 开始提示。
     *
     * @param message 提示信息
     */
    start(message?: T): Promise<any>;
    /**
     * 失败提示。
     *
     * @param message 提示信息
     * @param duration 持续时间（毫秒），默认 1500
     */
    fail(message: T, duration?: number): Promise<any>;
    /**
     * 成功提示。
     *
     * @param message 提示信息
     * @param duration 持续时间（毫秒），默认 1500
     */
    success(message: T, duration?: number): Promise<any>;
}

/**
 * 原地交换数组中的两个元素。
 *
 * @param arr 要处理的数组
 * @param i 第一个元素的索引
 * @param j 第二个元素的索引
 * @returns 返回交换后的数组
 * @example
 * ```typescript
 * swap([1, 2, 3], 0, 2) // => [3, 2, 1]
 * ```
 */
export declare function swap<T>(arr: T[], i: number, j: number): T[];

/**
 * 转换为全角字符串。
 *
 * @param value 要转换的字符串
 * @returns 返回转换后的全角字符串
 */
export declare function toFullWidthString(value: string): string;

/**
 * 转换为半角字符串。
 *
 * @param value 要转换的字符串
 * @returns 返回转换后的半角字符串
 */
export declare function toHalfWidthString(value: string): string;

/**
 * 转换为 https 链接。
 *
 * @param url 原链接
 */
export declare function toHttpsUrl(url: string): string;

/**
 * 将多行字符串转换为单行字符串。
 *
 * @param value 要转换的字符串
 * @returns 返回结果
 */
export declare function toSingleLineString(value: string, truncateOptions?: number | TruncateOptions): string;

/**
 * 遍历对象和数组。
 *
 * @param value 要遍历的值
 * @param callback 遍历回调
 * @returns 返回结果
 * @example
 * ```typescript
 * traverse([1, 2, {3: 4}], value => {
 *   console.log(value)
 *   // => 1
 *   // => 2
 *   // => {3: 4}
 *   // => 4
 * })
 * ```
 */
export declare function traverse(value: any, callback: (value: any, key: string | number, parent: any) => any): void;

/**
 * 树数据处理。支持单根节点、多根节点树数据。
 */
export declare class TreeData<TNode extends TreeDataNode> {
    private data;
    private childrenPropName;
    private searchStrategy;
    private cloneIgnore;
    /**
     * 构造函数。
     *
     * @param data 整棵树的数据
     * @param options 选项
     */
    constructor(data: TreeDataSingleRootData<TNode> | TreeDataMultipleRootData<TNode>, options?: TreeDataOptions<TNode>);
    private cloneDeep;
    /**
     * 核心遍历函数。
     */
    private static traverse;
    /**
     * 设置选项。
     *
     * @param options 选项
     */
    setOptions(options: TreeDataOptions<TNode>): this;
    /**
     * 遍历节点。
     *
     * @param node 节点
     * @param fn 遍历函数
     * @param searchStrategy 遍历搜索方式，默认为选项中的遍历搜索方式
     */
    traverseNode(node: OneOrMore<TNode> | ((payload: TreeDataTraverseFnPayload<TNode>) => boolean), fn: OneOrMore<TreeDataTraverseFn<TNode> | false>, searchStrategy?: TreeDataSearchStrategy): this;
    /**
     * 深度优先遍历节点。
     *
     * @param fn 遍历函数
     */
    traverseNodeDFS(node: OneOrMore<TNode> | ((payload: TreeDataTraverseFnPayload<TNode>) => boolean), fn: OneOrMore<TreeDataTraverseFn<TNode> | false>): this;
    /**
     * 广度优先遍历节点。
     *
     * @param fn 遍历函数
     */
    traverseNodeBFS(node: OneOrMore<TNode> | ((payload: TreeDataTraverseFnPayload<TNode>) => boolean), fn: OneOrMore<TreeDataTraverseFn<TNode> | false>): this;
    /**
     * 遍历。
     *
     * @param fn 遍历函数
     * @param searchStrategy 遍历搜索方式，默认为选项中的遍历搜索方式
     */
    traverse(fn: OneOrMore<TreeDataTraverseFn<TNode> | false>, searchStrategy?: TreeDataSearchStrategy): this;
    /**
     * 深度优先遍历。
     *
     * @param fn 遍历函数
     */
    traverseDFS(fn: OneOrMore<TreeDataTraverseFn<TNode> | false>): this;
    /**
     * 广度优先遍历。
     *
     * @param fn 遍历函数
     */
    traverseBFS(fn: OneOrMore<TreeDataTraverseFn<TNode> | false>): this;
    /**
     * 设置数据深度。从 `0` 开始，将会移除超过指定深度的数据。
     *
     * @param depth 深度
     */
    setDepth(depth: number): this;
    /**
     * 设置节点属性。
     *
     * @param props 节点属性键值映射对象，值为函数，用其返回值作为新的属性值
     */
    setNodeProps<TProps extends {
        [K in keyof TNode]?: (payload: TreeDataTraverseFnPayload<TNode>) => any;
    } & {
        [K: string]: (payload: TreeDataTraverseFnPayload<TNode>) => any;
    }>(props: TProps): TreeData<Merge<TNode, {
        [K in keyof TProps]: ReturnType<TProps[K]>;
    }>>;
    /**
     * 移除节点上指定的属性。
     *
     * @param propNames 属性名列表
     */
    omitNodeProps<TPropName extends keyof TNode>(propNames: TPropName[]): TreeData<Omit<TNode, TPropName>>;
    /**
     * 选取节点上指定的属性。
     *
     * @param propNames 属性名列表
     */
    pickNodeProps<TPropName extends keyof TNode>(propNames: TPropName[]): TreeData<Pick<TNode, TPropName>>;
    /**
     * 筛选符合条件的节点。
     *
     * @param predicate 条件
     */
    filter(predicate: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): this;
    /**
     * 查找符合条件的第一个节点。
     *
     * @param predicate 条件
     */
    findNode(predicate: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): TNode | undefined;
    /**
     * 查找符合条件的所有节点。
     *
     * @param predicate 条件
     */
    findNodeAll(predicate: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): TNode[];
    /**
     * 查找符合条件的第一个节点的路径。
     *
     * @param predicate 条件
     */
    findNodePath(predicate: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): TNode[] | undefined;
    /**
     * 查找符合条件的所有节点的路径。
     *
     * @param predicate 条件
     */
    findNodePathAll(predicate: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): Array<TNode[]>;
    /**
     * 移除符合条件的第一个节点。返回被移除的节点。
     *
     * @param predicate 条件
     */
    removeNode(predicate: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): TNode | undefined;
    /**
     * 移除符合条件的所有节点。返回被移除的节点组成的数组。
     *
     * @param predicate 条件
     */
    removeNodeAll(predicate: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): TNode[];
    /**
     * 计算符合条件的节点个数。不给出条件则计算所有节点的个数。
     *
     * @param predicate 条件
     */
    count(predicate?: (payload: TreeDataTraverseFnPayload<TNode>) => boolean): number;
    /**
     * 克隆实例。
     */
    clone(): TreeData<TNode>;
    /**
     * 导出数据。
     */
    export(): TreeDataData<TNode>;
    /**
     * 导出一维列表数据。
     */
    exportList(): TNode[];
    /**
     * 从一维列表生成实例。
     *
     * @param list 列表
     * @param idKey ID 所在键
     * @param parentIdKey 父 ID 所在键
     */
    static fromList<TItem extends Record<any, any>>(list: TItem[], idKey: keyof TItem, parentIdKey: keyof TItem): TreeData<TreeDataStandardNode<TItem>>;
}

export declare type TreeDataChildrenPropName<TNode extends TreeDataNode> = {
    [K in keyof TNode]: Exclude<TNode[K], undefined> extends TreeDataData<TNode> ? K : never;
}[keyof TNode];

export declare type TreeDataData<TNode extends TreeDataNode> = TNode[];

export declare type TreeDataMultipleRootData<TNode extends TreeDataNode> = TNode[];

export declare interface TreeDataNode extends Record<any, any> {
}

export declare interface TreeDataOptions<TNode extends TreeDataNode> {
    /**
     * 节点上子树数据所在的属性名。
     *
     * @default 'children'
     */
    childrenPropName?: TreeDataChildrenPropName<TNode>;
    /**
     * 遍历时的搜索策略。
     *
     * - `DFS`: 深度优先搜索
     * - `BFS`: 广度优先搜索
     *
     * @default 'DFS'
     */
    searchStrategy?: TreeDataSearchStrategy;
    /**
     * 克隆数据时忽略的值。
     */
    cloneIgnore?: (value: unknown) => boolean | undefined;
}

export declare type TreeDataSearchStrategy = 'DFS' | 'BFS';

export declare type TreeDataSingleRootData<TNode extends TreeDataNode> = TNode;

export declare type TreeDataStandardNode<TNode extends TreeDataNode> = Merge<TNode, {
    children: Array<TreeDataStandardNode<TNode>>;
}>;

export declare type TreeDataTraverseFn<TNode extends TreeDataNode> = (payload: TreeDataTraverseFnPayload<TNode>) => void;

export declare interface TreeDataTraverseFnPayload<TNode extends TreeDataNode> {
    /**
     * 当前节点。
     */
    node: TNode;
    /**
     * 当前节点索引。
     */
    index: number;
    /**
     * 当前深度。从 `0` 开始。
     */
    depth: number;
    /**
     * 父节点。为 `undefined` 时表示当前节点是根节点。
     */
    parentNode: TNode | undefined;
    /**
     * 到当前节点的路径节点列表。
     */
    path: TNode[];
    /**
     * 移除当前节点。
     */
    removeNode: () => void;
    /**
     * 退出遍历。
     */
    exit: () => void;
    /**
     * 跳过子树遍历。
     */
    skipChildrenTraverse: () => void;
}

declare type TupleOf<Tuple extends ReadonlyArray<Values>, Values> = IsEqual_2<Values, TupleToUnion<Tuple>> extends true ? Tuple : never;

declare type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never;

declare type UpperCaseToLowerCase<T extends string> = T extends Uppercase<T> ? Lowercase<T> : T;

/** Easily extract the type of a given object's values */
declare type ValueOf<T> = T[keyof T];

export declare type ValueOfRawData<TRawData extends RawData> = ElementOfRawData<TRawData>[KeyOfRawData<TRawData>];

/**
 * 等待一段时间 resolve。
 *
 * @public
 * @param milliseconds 等待时间(毫秒)
 * @param value resolve 值
 * @example
 * ```typescript
 * wait(1000).then(() => {
 *   console.log('ok')
 * }) // => 1秒后在控制台打印字符串: ok
 * ```
 */
export declare function wait<T>(milliseconds: number, value?: T): WaitResult<T>;

export declare namespace wait {
    var reject: (milliseconds: number, value?: any) => WaitResult<never>;
}

/**
 * @public
 */
export declare interface WaitResult<T> extends Promise<T> {
    /**
     * 取消等待，不执行后续逻辑。
     */
    cancel: () => void;
}

/**
 * 对微信 JSSDK 的封装。
 *
 * @public
 * @example
 * ```typescript
 * const wechat = new Wechat()
 * getWechatConfigAsync().then(config => {
 *   wechat.config(config)
 * })
 * wechat.updateShareData({
 *   title: '分享标题',
 *   desc: '分享描述',
 *   link: '分享链接',
 *   imgUrl: '缩略图地址',
 * })
 * wechat.invoke('scanQRCode').then(res => {
 *   // => API 调用结果
 * })
 * ```
 */
export declare class Wechat {
    /**
     * 微信 JSSDK 是否已准备完成。
     */
    private ready;
    /**
     * 消息巴士。
     */
    private bus;
    /**
     * 上一次设置分享时的参数。
     */
    private prevShareParams;
    private beforeInvokeCallbacks;
    /**
     * 注入微信 `JSSDK` 的权限验证配置参数。
     */
    configParams: WechatConfigParams;
    /**
     * 构造函数。
     *
     * @param params 注入微信 `JSSDK` 的权限验证配置参数
     */
    constructor(params?: WechatConfigParams);
    /**
     * 注入微信 `JSSDK` 的权限验证配置。
     *
     * @param params 配置参数
     */
    config(params?: WechatConfigParams): Promise<void>;
    /**
     * 微信 JSSDK 是否准备好可用。
     */
    isReady(): boolean;
    /**
     * 判断当前客户端版本是否支持指定 JS 接口。
     *
     * @param jsApiList 需要检测的 JS 接口列表
     * @returns 以键值对的形式返回，可用的 `api` 值 `true`，不可用为 `false`
     */
    checkJsApi<T extends WechatJsApi>(jsApiList: T[]): Promise<Record<T, boolean>>;
    /**
     * 设置分享数据。
     *
     * **注意**：每次分享的数据会和上次分享的数据合并作为最终分享的数据，因此，可以设置全局的分享数据。
     *
     * @param params 分享数据
     */
    updateShareData(params: WechatUpdateShareDataParams): Promise<void>;
    /**
     * 选择图片。
     *
     * @param params 参数
     * @returns 选定照片的本地 ID 列表，它们可以作为 img 标签的 src 属性显示图片
     */
    chooseImage(params?: WechatChooseImageParams): Promise<WechatChooseImageResult>;
    /**
     * 预览图片。
     *
     * @param params 参数
     */
    previewImage(params: WechatPreviewImageParams): Promise<any>;
    /**
     * 上传图片。
     *
     * 内部已作处理保证同时只能有一个图片在上传。
     *
     * **备注：** 上传图片有效期3天，
     * 可用微信多媒体接口下载图片到自己的服务器，
     * 此处获得的服务器端 ID 即 `media_id`。
     *
     * @param params 参数
     */
    uploadImage: (params: WechatUploadImageParams) => Promise<WechatUploadImageResult>;
    /**
     * 获取地理位置接口。
     *
     * @param params 参数
     */
    getLocation(params?: WechatGetLocationParams): Promise<WechatGetLocationResult>;
    /**
     * 使用微信内置地图查看位置。
     *
     * @param params 参数
     */
    openLocation(params: WechatOpenLocationParams): Promise<any>;
    /**
     * 关闭当前网页窗口。
     */
    closeWindow(): Promise<any>;
    /**
     * 批量隐藏非基础菜单项。
     *
     * @param menuList 要隐藏的非基础菜单项列表
     */
    hideNonBaseMenuItems(menuList: WechatNonBaseMenuItem[]): Promise<any>;
    /**
     * 批量显示非基础菜单项。
     *
     * @param menuList 要显示的非基础菜单项列表
     */
    showNonBaseMenuItems(menuList: WechatNonBaseMenuItem[]): Promise<any>;
    /**
     * 隐藏所有的非基础菜单项。
     */
    hideAllNonBaseMenuItems(): Promise<any>;
    /**
     * 显示所有的非基础菜单项。
     */
    showAllNonBaseMenuItems(): Promise<any>;
    /**
     * 发起微信支付。
     *
     * @param params 参数
     */
    requestPayment(params: WechatRequestPaymentParams): Promise<any>;
    /**
     * 开始音频录制。
     */
    startVoiceRecord(params: {
        on?: (type: 'error' | 'start' | 'stop' | 'end', localId?: string) => any;
    }): Promise<void>;
    /**
     * 停止音频录制。
     */
    stopVoiceRecord(): Promise<{
        localId: string;
    }>;
    private audioElMap;
    /**
     * 开始音频播放。
     */
    startVoicePlay(params: {
        localId: string;
        on?: (type: 'error' | 'start' | 'pause' | 'stop' | 'end') => any;
    }): Promise<void>;
    /**
     * 暂停音频播放。
     */
    pauseVoicePlay(params: {
        localId: string;
    }): Promise<void>;
    /**
     * 停止音频播放。
     */
    stopVoicePlay(params: {
        localId: string;
    }): Promise<void>;
    /**
     * 开始音频上传。
     *
     * 上传语音有效期3天，可用微信多媒体接口下载语音到自己的服务器，此处获得的 serverId 即 media_id。
     */
    startVoiceUpload(params: {
        localId: string;
        isShowProgressTips?: boolean;
    }): Promise<{
        serverId: string;
    }>;
    /**
     * 错误处理。
     *
     * @param callback 出错时的回调函数
     */
    onError(callback: WechatErrorCallback): EventBusOffListener;
    beforeInvoke(cb: WechatBeforeInvokeCallback): void;
    /**
     * 调用 JSSDK 的 API 方法。
     *
     * @param jsApi 要调用的 API 名称
     * @param params 传给 API 的参数
     * @returns 调用结果
     */
    invoke<P extends Record<string, any> = Record<string, any>, T = any>(jsApi: WechatJsApi, params?: P): Promise<T>;
}

export declare type WechatBeforeInvokeCallback = (jsApi: WechatJsApi, params: Record<string, any>) => any;

/**
 * @public
 */
export declare interface WechatChooseImageParams {
    /**
     * 选择图片数量。
     *
     * @default 9
     */
    count?: number;
    /**
     * 图片质量，可以指定是原图还是压缩图。
     *
     * @default ['original', 'compressed']
     */
    sizeType?: Array<'original' | 'compressed'>;
    /**
     * 选择来源，可以指定是相册还是相机。
     *
     * @default ['album', 'camera']
     */
    sourceType?: Array<'album' | 'camera'>;
}

/**
 * @public
 */
export declare type WechatChooseImageResult = Array<{
    /** 本地 ID，用于上传 */
    localId: string;
    /** 预览链接，已兼容 iOS WKWebview */
    previewUrl: string;
}>;

/**
 * @public
 */
export declare interface WechatConfigParams {
    /**
     * 开启调试模式。
     *
     * 调用的所有api的返回值会在客户端 alert 出来，
     * 若要查看传入的参数，可以在 pc 端打开，
     * 参数信息会通过 log 打出，仅在 pc 端时才会打印。
     *
     * @default false
     */
    debug?: boolean;
    /**
     * 公众号的唯一标识。
     */
    appId: string;
    /**
     * 生成签名的时间戳。
     */
    timestamp: number | string;
    /**
     * 生成签名的随机串。
     */
    nonceStr: string;
    /**
     * 签名。
     */
    signature: string;
    /**
     * 需要使用的JS接口列表。
     *
     * @default []
     */
    jsApiList?: WechatJsApi[];
    /**
     * 是否可分享。
     *
     * 设置为 `true` 将把分享系列接口自动加入 `jsApiList`。
     *
     * @default true
     */
    sharable?: boolean;
    /**
     * 当全局变量 `wx` 不存在时，自动引入微信 JSSDK。
     *
     * - 设为 `false` 可禁止自动引入；
     * - 设为版本号表示引入特定版本的 JSSDK；
     * - 设为链接表示通过该链接引入 JSSDK。
     *
     * @default '1.4.0'
     */
    autoLoadJSSDK?: false | string;
}

/**
 * @public
 */
export declare type WechatErrorCallback = (err: any) => void;

/**
 * @public
 */
export declare interface WechatGetLocationParams {
    /**
     * 默认为 wgs84 的 gps 坐标，如果要返回直接给 openLocation 用的火星坐标，可传入 gcj02。
     */
    type?: 'wgs84' | 'gcj02';
}

/**
 * @public
 */
export declare interface WechatGetLocationResult {
    /**
     * 纬度，浮点数，范围为90 ~ -90。
     */
    latitude: number;
    /**
     * 经度，浮点数，范围为180 ~ -180。
     */
    longitude: number;
    /**
     * 速度，以米/每秒计。
     */
    speed: number;
    /**
     * 位置精度。
     */
    accuracy: number;
}

/**
 * 微信 JSSDK 支持的 API。
 *
 * @public
 */
export declare type WechatJsApi = 'checkJsApi' | 'updateAppMessageShareData' | 'updateTimelineShareData' | 'onMenuShareTimeline' | 'onMenuShareAppMessage' | 'onMenuShareQQ' | 'onMenuShareQZone' | 'startRecord' | 'stopRecord' | 'onVoiceRecordEnd' | 'playVoice' | 'pauseVoice' | 'stopVoice' | 'onVoicePlayEnd' | 'uploadVoice' | 'downloadVoice' | 'chooseImage' | 'previewImage' | 'uploadImage' | 'downloadImage' | 'translateVoice' | 'getNetworkType' | 'openLocation' | 'getLocation' | 'hideOptionMenu' | 'showOptionMenu' | 'hideMenuItems' | 'showMenuItems' | 'hideAllNonBaseMenuItem' | 'showAllNonBaseMenuItem' | 'closeWindow' | 'scanQRCode' | 'chooseWXPay' | 'openProductSpecificView' | 'addCard' | 'chooseCard' | 'openCard' | 'getLocalImgData';

/**
 * 微信内网页的非基础菜单列表。
 *
 * @public
 */
export declare type WechatNonBaseMenuItem = 'menuItem:share:appMessage' | 'menuItem:share:timeline' | 'menuItem:share:qq' | 'menuItem:share:weiboApp' | 'menuItem:favorite' | 'menuItem:share:facebook' | 'menuItem:share:QZone' | 'menuItem:editTag' | 'menuItem:delete' | 'menuItem:copyUrl' | 'menuItem:originPage' | 'menuItem:readMode' | 'menuItem:openWithQQBrowser' | 'menuItem:openWithSafari' | 'menuItem:share:email' | 'menuItem:share:brand';

/**
 * @public
 */
export declare interface WechatOpenLocationParams {
    /**
     * 纬度，浮点数，范围为 90 ~ -90。
     */
    latitude: number;
    /**
     * 经度，浮点数，范围为 180 ~ -180。
     */
    longitude: number;
    /**
     * 位置名。
     */
    name: string;
    /**
     * 地址详情说明。
     */
    address?: string;
    /**
     * 地图缩放级别，整形值，范围从 1 ~ 28。
     *
     * @default 28
     */
    scale?: number;
    /**
     * 在查看位置界面底部显示的超链接，可点击跳转。
     */
    infoUrl?: string;
}

/**
 * @public
 */
export declare interface WechatPreviewImageParams {
    /**
     * 当前显示图片的链接。
     *
     * @default urls[0]
     */
    current?: string;
    /**
     * 需要预览的图片链接列表。
     */
    urls: string[];
}

export declare interface WechatRequestPaymentParams {
    /**
     * 支付签名时间戳。
     */
    timestamp: number;
    /**
     * 支付签名随机串。
     */
    nonceStr: string;
    /**
     * 统一支付接口返回的 prepay_id 参数值，如：`prepay_id=xxx`。
     */
    package: string;
    /**
     * 签名方式。
     */
    signType: string;
    /**
     * 支付签名。
     */
    paySign: string;
}

/**
 * @public
 */
export declare interface WechatUpdateShareDataParams {
    /** 分享标题 */
    title?: string | (() => string);
    /** 分享描述 */
    desc?: string | (() => string);
    /** 分享链接，该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致 */
    link?: string | (() => string);
    /** 分享图标地址 */
    imgUrl?: string | (() => string);
}

/**
 * @public
 */
export declare interface WechatUploadImageParams {
    /**
     * 需要上传的图片的本地 ID，由 chooseImage 接口获得。
     */
    localId: string;
    /**
     * 是否显示进度提示。
     *
     * @default false
     */
    isShowProgressTips?: boolean;
}

/**
 * @public
 */
export declare interface WechatUploadImageResult {
    /**
     * 图片的服务器 ID，即临时素材 ID。
     */
    serverId: string;
}

/**
 Split a string (almost) like Lodash's `_.words()` function.

 - Split on each word that begins with a capital letter.
 - Split on each {@link WordSeparators}.
 - Split on numeric sequence.

 @example
 ```
 import type {Words} from 'type-fest';

 type Words0 = Words<'helloWorld'>;
 //=> ['hello', 'World']

 type Words1 = Words<'helloWORLD'>;
 //=> ['hello', 'WORLD']

 type Words2 = Words<'hello-world'>;
 //=> ['hello', 'world']

 type Words3 = Words<'--hello the_world'>;
 //=> ['hello', 'the', 'world']

 type Words4 = Words<'lifeIs42'>;
 //=> ['life', 'Is', '42']
 ```

 @category Change case
 @category Template literal
 */
declare type Words<
	Sentence extends string,
	LastCharacter extends string = '',
	CurrentWord extends string = '',
> = Sentence extends `${infer FirstCharacter}${infer RemainingCharacters}`
	? FirstCharacter extends WordSeparators
		// Skip word separator
		? [...SkipEmptyWord<CurrentWord>, ...Words<RemainingCharacters>]
		: LastCharacter extends ''
			// Fist char of word
			? Words<RemainingCharacters, FirstCharacter, FirstCharacter>
			// Case change: non-numeric to numeric, push word
			: [false, true] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>]
				? [...SkipEmptyWord<CurrentWord>, ...Words<RemainingCharacters, FirstCharacter, FirstCharacter>]
				// Case change: numeric to non-numeric, push word
				: [true, false] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>]
					? [...SkipEmptyWord<CurrentWord>, ...Words<RemainingCharacters, FirstCharacter, FirstCharacter>]
					// No case change: concat word
					: [true, true] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>]
						? Words<RemainingCharacters, FirstCharacter, `${CurrentWord}${FirstCharacter}`>
					// Case change: lower to upper, push word
						: [true, true] extends [IsLowerCase<LastCharacter>, IsUpperCase<FirstCharacter>]
							? [...SkipEmptyWord<CurrentWord>, ...Words<RemainingCharacters, FirstCharacter, FirstCharacter>]
						// Case change: upper to lower, brings back the last character, push word
							: [true, true] extends [IsUpperCase<LastCharacter>, IsLowerCase<FirstCharacter>]
								? [...RemoveLastCharacter<CurrentWord, LastCharacter>, ...Words<RemainingCharacters, FirstCharacter, `${LastCharacter}${FirstCharacter}`>]
							// No case change: concat word
								: Words<RemainingCharacters, FirstCharacter, `${CurrentWord}${FirstCharacter}`>
	: [...SkipEmptyWord<CurrentWord>];


export * from "lodash-uni";

export { }
