/**
 * Creates a new function with the given name, arguments, body, scope and values.
 *
 * * If only one argument is provided and it is a function, returns a new function with the same code.
 * * If only one argument is provided and it is not a function, returns a new empty function with the given name.
 * * If multiple arguments are provided, creates a new function with the given name, arguments and body.
 *
 * @param {string|Function} name The name of the function or the function itself.
 * @param {string[]} [aArgs] An array of argument names for the function.
 * @param {string} [body] The body of the function.
 * @param {object} [scope] The scope for the function.
 * @param {object} [values] The values to apply to the scope.
 * @returns {Function} A new function with the given name, arguments, body, scope and values.
 * @example
 * var add1 = newFunction(`function add(a,b) {return a+b}`);
 * var add = newFunction('add', ['a', 'b'], 'return a + b;');
 * var result = add(1, 2); // result is 3
 * var greet = newFunction('greet', ['name'], 'console.log("Hello, " + name + "!");');
 * greet('John'); // Output: Hello, John!
 * const sleep = newFunction('sleep', ['ms'], 'return new Promise(resolve => setTimeout(resolve, ms));');
 * const wait1Second = newFunction('async wait1Second', [], `await sleep(1000);`, {sleep});
 * await wait1Second()
 * var fn = newFunction('yourFuncName', ['arg1', 'arg2'], 'return log(arg1+arg2);', {log:console.log});
 * function sub(a,b) {
 *   log(a-b);
 *   return a-b;
 * }
 * var subWithLog=newFunction(sub, {log:console.log})
 * subWithLog(5,2); // print 3
 */
export function newFunction(name: string | Function, aArgs?: string[], body?: string, scope?: object, values?: object, ...args: any[]): Function;
export default newFunction;
