const [reset, registerReset] = (() => {
	const resets: Function[] = [];

	return [
		() => {
			for (const fn of resets) {
				fn();
			}
		},
		(fn: Function) => resets.push(fn),
	];
})(),
registerSimple = <O extends Object, T extends keyof O>(obj: O, fnName: T) => {
	const fn = obj[fnName];

	if (fn instanceof Function) {
		const values: unknown[] = [];

		let pos = 0;

		registerReset(() => pos = 0);

		Object.defineProperty(obj, fnName, {"value": () => {
			if (pos >= values.length) {
				values.push(fn.call(obj)());
			}

			const v = values[pos];

			pos++;

			return v;
		}});
	}
},
originalDate = Date,
newDate: DateConstructor = function(this: any, ...args: any[]) {
	if (!(this instanceof Date)) {
		return new originalDate(Date.now()).toString();
	}

	if (args.length) {
		return new (originalDate as any)(...args);
	}

	return new originalDate(Date.now());
} as any;

(newDate as any).prototype = originalDate.prototype;
newDate.parse = originalDate.parse;
newDate.UTC = originalDate.UTC;
newDate.now = originalDate.now;
globalThis.Date = newDate;

registerSimple(Math, "random");
registerSimple(originalDate, "now");
registerSimple(crypto, "randomUUID");
