| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | interface ServerChatRoomMessage { | 
					
						
							|  |  |  | 	MBCHC_ID?: number | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | namespace BCE { | 
					
						
							|  |  |  | 	interface Matcher { | 
					
						
							|  |  |  | 		Tester: RegExp | 
					
						
							|  |  |  | 		Criteria?: { | 
					
						
							|  |  |  | 			TargetIsPlayer?: boolean | 
					
						
							|  |  |  | 			SenderIsPlayer?: boolean | 
					
						
							|  |  |  | 			DictionaryMatchers?: Array<OBJ<string>> | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	interface Trigger { | 
					
						
							|  |  |  | 		Event: string | 
					
						
							|  |  |  | 		Type: 'Emote' | 'Activity' | 'Action' | 
					
						
							|  |  |  | 		Matchers: Matcher[] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	interface Patcher { | 
					
						
							|  |  |  | 		timer: number | undefined | 
					
						
							|  |  |  | 		patches: Array<[RegExp, string]> | 
					
						
							|  |  |  | 		cfs: {[k in 'anim' | 'pose']: () => Iterable<string>} | 
					
						
							|  |  |  | 		gen: (comp_func: () => Iterable<string>) => (this: Optional<ICommand, 'Tag'>) => undefined | 
					
						
							|  |  |  | 		copy(t: Trigger): Trigger | 
					
						
							|  |  |  | 		patch(): true | undefined | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type SUBCOMMANDS = { | 
					
						
							|  |  |  | 	[k: string]: { | 
					
						
							|  |  |  | 		desc: string | 
					
						
							|  |  |  | 		args?: {[n: string]: OBJ} | 
					
						
							|  |  |  | 		cb: (mbchc: Window['MBCHC'], args: string[], __: unknown, ___?: unknown) => void | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | interface Window { | 
					
						
							|  |  |  | 	MBCHC: { | 
					
						
							|  |  |  | 		loader: () => void | 
					
						
							|  |  |  | 		DO_DATA: { | 
					
						
							|  |  |  | 			zones: OBJ<string> | 
					
						
							|  |  |  | 			verbs: { | 
					
						
							|  |  |  | 				[verb: string]: { | 
					
						
							|  |  |  | 					[zone: string]: { | 
					
						
							|  |  |  | 						self: string[] | 
					
						
							|  |  |  | 						others: string[] | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | 		MAP_ACTIONS: { | 
					
						
							|  |  |  | 			[verb: string]: { | 
					
						
							|  |  |  | 				[zones: string]: { | 
					
						
							|  |  |  | 					all?: string | 
					
						
							|  |  |  | 					self?: string | 
					
						
							|  |  |  | 					others?: string | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		MAP_ZONES: {[zone: string]: string[]} | 
					
						
							|  |  |  | 		LOADED: boolean | 
					
						
							|  |  |  | 		NEXT_MESSAGE: number | 
					
						
							|  |  |  | 		LOG_MESSAGES: boolean | 
					
						
							|  |  |  | 		LAST_HACKED: number | undefined | 
					
						
							|  |  |  | 		version: string | 
					
						
							|  |  |  | 		VERSION: string | 
					
						
							|  |  |  | 		Settings: Settings.Methods | 
					
						
							|  |  |  | 		TZ: TZ_Cache | 
					
						
							|  |  |  | 		SUBCOMMANDS_MBCHC: SUBCOMMANDS | 
					
						
							|  |  |  | 		H: InputHistory | 
					
						
							|  |  |  | 		U: Utils | 
					
						
							|  |  |  | 		AUTOHACK_ENABLED: boolean | 
					
						
							|  |  |  | 		RE_PREF_ACTIVITY_ME: RegExp | 
					
						
							|  |  |  | 		RE_PREF_ACTIVITY: RegExp | 
					
						
							|  |  |  | 		RE_ACT_CIDS: RegExp | 
					
						
							|  |  |  | 		RE_LAST_WORD: RegExp | 
					
						
							|  |  |  | 		RE_LAST_LETTER: RegExp | 
					
						
							|  |  |  | 		RE_ACTIVITY: RegExp | 
					
						
							|  |  |  | 		UTC_OFFSET: number | 
					
						
							|  |  |  | 		calculate_maps(): void | 
					
						
							|  |  |  | 		normalise_message(text: string, options?: OBJ<boolean>): string | 
					
						
							|  |  |  | 		donate_data(target: string): void | 
					
						
							|  |  |  | 		run_activity(char: Character, ag: AssetGroupItemName, action: ActivityName): void | 
					
						
							|  |  |  | 		send_activity(message: string): void | 
					
						
							|  |  |  | 		set_timezone(args: string[]): number | undefined | 
					
						
							|  |  |  | 		command_mbchc(this: Optional<ICommand, 'Tag'>, args: string, msg: string, parsed: string[]): undefined | 
					
						
							|  |  |  | 		command_activity(this: Optional<ICommand, 'Tag'>, args: string, msg: string, parsed: string[]): undefined | 
					
						
							|  |  |  | 		command_do(this: Optional<ICommand, 'Tag'>, args: string, msg: string, parsed: string[]): undefined | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | 	bcModSdk?: import('./node_modules/bondage-club-mod-sdk/dist/bcmodsdk.d.ts').ModSDKGlobalAPI; | 
					
						
							|  |  |  | 	FBC_VERSION?: string | 
					
						
							|  |  |  | 	bce_ActivityTriggers?: BCE.Trigger[] | 
					
						
							|  |  |  | 	bce_EventExpressions?: OBJ | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | type OBJ<T = unknown> = Record<string, T>; | 
					
						
							|  |  |  | type FUN = (...args: never[]) => unknown; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Stands for "Value or Function". Not remotely ideal, but the best I can come up with. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | type VOF<F extends FUN> = undefined | boolean | number | bigint | string | symbol | OBJ | Set<unknown> | Map<unknown, unknown> | FP.Interval | F; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * I can write Haskell in every language. | 
					
						
							|  |  |  |  * I was unbelievably tempted to go with emojis here, but I'm not a monster of this caliber. | 
					
						
							|  |  |  |  * @see https://8fw.me/hell/a8aaaefcb6e30ec4b2e398c70d49b72a6b53232f.png
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | namespace FP { | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 	interface Interval { | 
					
						
							|  |  |  | 		proxy: object // eslint-disable-line @typescript-eslint/ban-types
 | 
					
						
							|  |  |  | 		min: number | 
					
						
							|  |  |  | 		max: number | 
					
						
							|  |  |  | 		mini: boolean | 
					
						
							|  |  |  | 		maxi: boolean | 
					
						
							|  |  |  | 		has(_: unknown, x: string): boolean | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | 	interface Pipeline<T> { | 
					
						
							|  |  |  | 		proxy: PipelineProxy<T> | 
					
						
							|  |  |  | 		me<N>(iterable: Iterable<N>): PipelineProxy<N> | 
					
						
							|  |  |  | 		[Symbol.iterator](): Iterator<T> | 
					
						
							|  |  |  | 		rdc<R>(initial: R, func: (accumulator: R, value: T) => R): R | 
					
						
							|  |  |  | 		any(func: (v: T) => boolean): boolean | 
					
						
							|  |  |  | 		all(func: (v: T) => boolean): boolean | 
					
						
							|  |  |  | 		map<R>(func: (value: T) => R): PipelineProxy<R> | 
					
						
							|  |  |  | 		sel(func: (value: T) => boolean): PipelineProxy<T> | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	interface PipelineProxy<T> extends Pipeline<T> { | 
					
						
							|  |  |  | 		[i: number]: T | undefined | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Creates an iteration pipeline. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type P = <T>(iterable: Iterable<T>) => PipelineProxy<T>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * A silly helper to kinda c[au]rry values. Basically equivalent to: | 
					
						
							|  |  |  | 	 * `const a = value; return func(a)` | 
					
						
							|  |  |  | 	 * Stands for "Carry, Use, Return". | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type cur = <T, R>(value: T, func: (value: T) => R) => R; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Convert `null` to `undefined`. | 
					
						
							|  |  |  | 	 */ // eslint-disable-next-line @typescript-eslint/ban-types | 
					
						
							|  |  |  | 	type n2u = <T>(value: T | undefined | null) => T | undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Enumerate keys of an object. Type-safe, also shorter. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type enu = <O extends OBJ>(object: O) => Array<keyof O>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Like `carry()` but does nothing if `value` is `null` or `undefined`. | 
					
						
							|  |  |  | 	 * Something like an `Option<>` when you want to just pass `undefined` along, but | 
					
						
							|  |  |  | 	 * run a function on actual values. Also coverts `null` to `undefined`. | 
					
						
							|  |  |  | 	 */ // eslint-disable-next-line @typescript-eslint/ban-types | 
					
						
							|  |  |  | 	type val = <T, R>(value: T | null | undefined, func: (value: T) => R) => R | undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `+` as a function | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type add = (x: number, y: number) => number; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `-` as a function | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type sub = (x: number, y: number) => number; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `>` as a function | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type cgt = (x: number, y: number) => boolean; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `>=` as a function | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type cge = (x: number, y: number) => boolean; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `<` as a function | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type clt = (x: number, y: number) => boolean; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `<=` as a function | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type cle = (x: number, y: number) => boolean; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Converts a string into a base 10 integer. Not only is it shorter than `Number.parseInt`, | 
					
						
							|  |  |  | 	 * it also converts `NaN` to `undefined`, because I find it much easier to only have | 
					
						
							|  |  |  | 	 * one nil value for everything. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type int = (text: string) => number | undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * This is a type assertion helper for Typescript. Probably not very useful in general. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type fun = <F extends FUN>(func: unknown) => func is F; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Takes anything, ignores non-functions, calls functions with supplied parameters. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type run = <F extends FUN>(functions_or_values: Array<VOF<F>>, ...args: Parameters<F>) => true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Takes anything, ignores non-functions, calls functions with `undefined` as a single parameter. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type yes = (...args: Array<VOF<(_: undefined) => unknown>>) => true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Takes anything, ignores non-functions, calls functions with a single provided parameter. | 
					
						
							|  |  |  | 	 * Always returns the parameter itself. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type mut = <T>(value: T, ...args: Array<VOF<(value: T) => unknown>>) => T; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `delete` as a function | 
					
						
							|  |  |  | 	 */ // eslint-disable-next-line @typescript-eslint/ban-types | 
					
						
							|  |  |  | 	type del = <T extends object>(object: T, property: keyof T) => T; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Short for `assert`. Throws, if value is `undefined`, or if `condition(value)` is false. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type ass = <T>(error: string, value: T | undefined, condition?: (value: T) => boolean) => T | never; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Casts value as a given prototype or returns undefined. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type asa = <T>(prototype: new () => T, value: unknown) => T | undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `catch` as a function. Short for `rescue`. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type rsc = (operation: (_: undefined) => unknown, exception_handler: (error: unknown) => unknown) => true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Returns a proxy for `in` operator. | 
					
						
							|  |  |  | 	 * Use it like `2 in rng(0, 4)`. | 
					
						
							|  |  |  | 	 */ // eslint-disable-next-line @typescript-eslint/ban-types | 
					
						
							|  |  |  | 	type rng = (min: number, max: number, min_inclusive?: boolean, max_inclusive?: boolean) => object; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Something slightly better than `Boolean()`. | 
					
						
							|  |  |  | 	 * True is `null`, `undefined`, `false`, empty strings, sets, maps, arrays and objects. | 
					
						
							|  |  |  | 	 * Short for "empty". | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type m_t = (value: unknown) => boolean; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * `while()` as a function. Executes the second callback while the first one is true. | 
					
						
							|  |  |  | 	 * Always bound by max number of iterations. | 
					
						
							|  |  |  | 	 * Returns the last value from the action or undefined if the action never ran. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type loo = <T>(max: number, condition: (_: undefined) => boolean, action: (_: undefined) => T) => T | undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace SDK { | 
					
						
							|  |  |  | 	type GDPT<F> = import('./node_modules/bondage-club-mod-sdk/dist/bcmodsdk.d.ts').GetDotedPathType<typeof globalThis, F>; | 
					
						
							|  |  |  | 	type Void<F extends FUN> = (...args: Parameters<F>) => unknown; | 
					
						
							|  |  |  | 	type Hook = <F extends string>(name: F, hook: Void<GDPT<F>>) => () => unknown; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Cons { | 
					
						
							|  |  |  | 	type MS = {w: 'warn', i: 'info', d: 'debug', l: 'log'}; | 
					
						
							|  |  |  | 	type E = (error: unknown) => true; | 
					
						
							|  |  |  | 	type F = (message: string) => true; | 
					
						
							|  |  |  | 	interface Wrap { | 
					
						
							|  |  |  | 		readonly ms: MS | 
					
						
							|  |  |  | 		e: E | 
					
						
							|  |  |  | 		w: F | 
					
						
							|  |  |  | 		i: F | 
					
						
							|  |  |  | 		d: F | 
					
						
							|  |  |  | 		l: F | 
					
						
							|  |  |  | 		gen: (m: keyof MS) => F | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Settings { | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * The whole `Player.OnlineSettings`. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	type V0 = PlayerOnlineSettings & {MBCHC?: {timezones?: Record<number, number>}}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Specifically `MBCHC` inside `Player.ExtensionSettings`. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	interface V1 { | 
					
						
							|  |  |  | 		TZ: Record<number, number> | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | 	interface Methods { | 
					
						
							|  |  |  | 		migrate_0_1(v0: V0): true | 
					
						
							|  |  |  | 		save(func?: (v1: V1) => unknown): true | 
					
						
							|  |  |  | 		replace(new_v1: V1): true | 
					
						
							|  |  |  | 		'purge!'(): true | 
					
						
							|  |  |  | 		get v0(): V0 | undefined | 
					
						
							|  |  |  | 		get v1(): V1 | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * We need a place to cache the timezones instead of the `Character` object itself. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | interface TZ_Cache { | 
					
						
							|  |  |  | 	map: Map<number, number> | 
					
						
							|  |  |  | 	RE: RegExp | 
					
						
							|  |  |  | 	parse(description: string | undefined): number | undefined | 
					
						
							|  |  |  | 	memo(member_number: number, description?: string | undefined): number | undefined | 
					
						
							|  |  |  | 	lookup(character: Character): number | undefined | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | interface Utils { | 
					
						
							|  |  |  | 	remove_loader_hook: (() => unknown) | undefined | 
					
						
							|  |  |  | 	RE: {SPACES: RegExp, REL: {L: RegExp, R: RegExp}, '@': [RegExp, RegExp]} | 
					
						
							|  |  |  | 	RGB: {Polly: string, Mute: string} | 
					
						
							|  |  |  | 	ACT: string, | 
					
						
							|  |  |  | 	get crc(): Character[] | 
					
						
							|  |  |  | 	get ic(): HTMLTextAreaElement | undefined | 
					
						
							|  |  |  | 	cid(character: Character): number | undefined | 
					
						
							|  |  |  | 	dn(character: Character): string | 
					
						
							|  |  |  | 	current(): string | 
					
						
							|  |  |  | 	style<T>(query: string, func: (s: CSSStyleDeclaration) => T): T | undefined | 
					
						
							|  |  |  | 	inform(html: string): true | 
					
						
							|  |  |  | 	report(error: unknown): true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Splits a string into words by continuous whitespace sequences. Some examples: | 
					
						
							|  |  |  | 	 * ```
 | 
					
						
							|  |  |  | 	 * ""      => [""] | 
					
						
							|  |  |  | 	 * " "     => ["", ""] | 
					
						
							|  |  |  | 	 * "f   g" => ["f", "g"] | 
					
						
							|  |  |  | 	 * " f g " => ["", "f", "g", ""] | 
					
						
							|  |  |  | 	 * ```
 | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	split(text: string): string[] | 
					
						
							|  |  |  | 	abs2char(index: number): Character | 
					
						
							|  |  |  | 	rel2char(target: string): Character | 
					
						
							|  |  |  | 	cid2char(cid: number): Character | 
					
						
							|  |  |  | 	target2char(target: string): Character | 
					
						
							|  |  |  | 	mkdiv(html?: string): HTMLDivElement | 
					
						
							|  |  |  | 	bell(): true | 
					
						
							|  |  |  | 	targets(me2?: boolean, check_perms?: boolean): Set<string> | 
					
						
							|  |  |  | 	complete_mbchc(this: Optional<ICommand, 'Tag'>): undefined | 
					
						
							|  |  |  | 	complete_do_target(actions: {self: unknown, others: unknown}): Set<string> | 
					
						
							|  |  |  | 	complete_do(this: Optional<ICommand, 'Tag'>): undefined | 
					
						
							|  |  |  | 	replace_me(_match: string, _offset: number, whole: string): string | 
					
						
							|  |  |  | 	pad_chat(chat: HTMLDivElement): undefined | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | interface Complete { | 
					
						
							|  |  |  | 	S_OPTS: {behavior: 'instant'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * The suggestions panel. | 
					
						
							|  |  |  | 	 * Its structure is (outer div) -> (container div) -> (multiple suggestion divs) | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	e: HTMLDivElement | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * The container div. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	get div(): Element | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Longest common prefix, or an empty string for an empty set. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	lcp(candidates: Set<string>): string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * !WARNING! Mutate the given set in accordance with the input. | 
					
						
							|  |  |  | 	 * Returns the input with completion done and removes all failed candidates. | 
					
						
							|  |  |  | 	 * If the set is empty, the completion failed and the result is the unmodified input. | 
					
						
							|  |  |  | 	 * If the set has more than one value, these are all new candidates, and the input was completed with the lcp. | 
					
						
							|  |  |  | 	 * Otherwise, the only successful candidate will remain in the set and the input was completed to it. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	complete_word(input: string, candidates: Set<string>, ignore_case?: boolean | undefined): string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Show the suggestions to the user. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	hint(candidates: Set<string>): true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Returns false if the suggestion panel is visible. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	get hidden(): boolean | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Makes the suggestions panel disappear. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	hide(): true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * The whole deal. Will read and modify the chat input window. | 
					
						
							|  |  |  | 	 * Takes a callback that will receive current input split into words | 
					
						
							|  |  |  | 	 * and should return all possible candidates for the word being completed. | 
					
						
							|  |  |  | 	 * Note: if the input ends with whitespace, the last word will be empty. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	complete(func: (words: string[]) => Set<string>, ignore_case?: boolean | undefined): true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Case-insensitive complete. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	icomplete(func: (words: string[]) => Set<string>): true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * So, this is what happens. We have two modes: input mode and history mode. In the history mode the element is read-only. | 
					
						
							|  |  |  |  * In the input mode: | 
					
						
							|  |  |  |  *   If the input is empty, we just scroll the history as usual | 
					
						
							|  |  |  |  *   Otherwise, we build a history set using the input as prefix | 
					
						
							|  |  |  |  *     The history set filters through the history, keeping only unique lines that start with the prefix along with indices | 
					
						
							|  |  |  |  *     But we exclude lines that match the input exactly | 
					
						
							|  |  |  |  *     It keeps the original input in a separate place too | 
					
						
							|  |  |  |  *   If the set is empty, we bell out | 
					
						
							|  |  |  |  *   Otherwise, we enter the history mode and invoke the first search | 
					
						
							|  |  |  |  * In the history mode: | 
					
						
							|  |  |  |  *   We search up or down, using the index as a starting point for the next match, treating the set as a ring | 
					
						
							|  |  |  |  *   If the found line is the same as the current line, we bell out | 
					
						
							|  |  |  |  *   Upon finding a next match, we replace the input with its text and set the index appropriately | 
					
						
							|  |  |  |  * We exit the history mode using the inputchat keydown handler, on Tab, Escape or Enter | 
					
						
							|  |  |  |  * Escape restores the saved input, discarding the history line | 
					
						
							|  |  |  |  * Tab keeps the current text and unlocks the element, allowing it to be edited | 
					
						
							|  |  |  |  * Enter keeps the current text and sends it as the message as usual | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | interface InputHistory { | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Whether the chat log is scrolled to the end when we enter history mode. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	bottom: boolean | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * The initial user input when we enter the history mode. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	input: string | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * The indices of the lines that match the prefix. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	ids: Set<number> | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Enter the history mode. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	enter(textarea: HTMLTextAreaElement, input: string, bottom: boolean, ids: Set<number>): true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Exit the history mode and optionally restore original input. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	exit(textarea: HTMLTextAreaElement, restore_input: boolean): true | 
					
						
							| 
									
										
										
										
											2024-07-13 21:55:45 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-18 01:12:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // FIXME spread around readonlys where appropriate
 |