function infer_namespace(namespace, parent, nodes) {
	if (parent.type === 'RegularElement' && parent.name === 'foreignObject') {
		return 'html';
	}

	if (parent.type === 'RegularElement' || parent.type === 'SvelteElement') {
		if (parent.metadata.svg) {
			return 'svg';
		}
		return parent.metadata.mathml ? 'mathml' : 'html';
	}

	// Re-evaluate the namespace inside slot nodes that reset the namespace
	if (
		parent.type === 'Fragment' ||
		parent.type === 'Root' ||
		parent.type === 'Component' ||
		parent.type === 'SvelteComponent' ||
		parent.type === 'SvelteFragment' ||
		parent.type === 'SnippetBlock' ||
		parent.type === 'SlotElement'
	) {
		const new_namespace = check_nodes_for_namespace(nodes, 'keep');
		if (new_namespace !== 'keep' && new_namespace !== 'maybe_html') {
			return new_namespace;
		}
	}

	/** @type {Namespace | null} */
	let new_namespace = null;

	// Check the elements within the fragment and look for consistent namespaces.
	// If we have no namespaces or they are mixed, then fallback to existing namespace
	for (const node of nodes) {
		if (node.type !== 'RegularElement') continue;

		if (node.metadata.mathml) {
			new_namespace = new_namespace === null || new_namespace === 'mathml' ? 'mathml' : 'html';
		} else if (node.metadata.svg) {
			new_namespace = new_namespace === null || new_namespace === 'svg' ? 'svg' : 'html';
		} else {
			return 'html';
		}
	}

	return new_namespace ?? namespace;
}
Infers the namespace for the children of a node that should be used when creating the fragment
@param {Namespace} namespace
@param {AST.SvelteNode} parent
@param {AST.SvelteNode[]} nodes