Code:
	let maxIndex = -1;
	let gl;
	let program;
	let textureManager;

	const vertices = new Float32Array([
		-1,1,0.0, 
		-1,-1,0.0,
		1,-1,0.0,
		-1,1,0.0, 
		1,-1,0.0,
		1,1,0.0,
	]);

	let imgIndex = 0;
	async function addTexture(url) {
		const anim = await textureManager.addTexture({url: `${url}?${imgIndex++}`});
		console.log(anim, "slotcount:", textureManager.slotAllocator.slots.size);
//			await pressSpace();
		if (anim.index > maxIndex) {
			maxIndex = anim.index;
			setupButton(maxIndex);
		}
		selectTexture(anim.index, {
			x: anim.x,
			y: anim.y,
			width: anim.spriteSheetWidth,
			height: anim.spriteSheetHeight,
		});
	}

	document.addEventListener("DOMContentLoaded", async () => {
		const vertexShaderCode = document.getElementById("vertex-shader").textContent.trim();
		const fragmentShaderCode = document.getElementById("fragment-shader").textContent.trim();
		const canvas = document.getElementById("canvas");
		gl = canvas.getContext("webgl2");
		program = gl.createProgram();
		const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderCode);
		const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderCode);
		gl.attachShader(program, vertexShader);
		gl.attachShader(program, fragmentShader);
		gl.linkProgram(program);
		gl.detachShader(program, vertexShader);
		gl.detachShader(program, fragmentShader);
		gl.deleteShader(vertexShader);
		gl.deleteShader(fragmentShader);
		gl.useProgram(program);		

		gl.viewport(0,0,canvas.width,canvas.height);
		gl.clearColor(1, 1, 1, 1);
		gl.clear(gl.COLOR_BUFFER_BIT);

		const vertexBuf = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuf);
		gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

		const coord = gl.getAttribLocation(program, "vertexPosition");
		gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
		gl.enableVertexAttribArray(coord);

		const textureLocation = gl.getUniformLocation(program, "uTextures");
		textureManager = new TextureManager(gl, textureLocation, null, null, {autoMipMap: true, delayMipMap: 300});
		await textureManager.init();
		const images = [
			"https://jacklehamster.github.io/art/Random/minok2.jpeg",
			"https://jacklehamster.github.io/art/Random/snake.jpeg",
			"https://jacklehamster.github.io/art/Random/duckrun.jpeg",
			"https://jacklehamster.github.io/art/Random/eye.png",
			"https://jacklehamster.github.io/art/public/12400579.png",
			"https://jacklehamster.github.io/art/Random/tomato.jpeg",
			"https://jacklehamster.github.io/art/Random/santa.png",
			"https://jacklehamster.github.io/art/Random/minok-valentine.jpeg",
			"https://jacklehamster.github.io/art/icon.png",
			"https://jacklehamster.github.io/art/Random/baby-hitler-title%20(3)%20(2).png",
		];

		const imageDivs = document.getElementById("images");
		for (let url of images) {
			const image = imageDivs.appendChild(document.createElement("img"));
			setupImage(image, url);
		}

		textureManager.addMipMapListener(() => {
			gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);
		});

		selectTexture(0);
		window.textureManager = textureManager;
	});