Commit 5b6f469574c29a7c120c057b13a362e2f1765146

Commits
[COMMIT BEGIN]
commit 5b6f469574c29a7c120c057b13a362e2f1765146
Author: 0x4248 <[email protected]>
Date:   Sun Mar 1 17:42:14 2026 +0000

    nova: init [testing]

diff --git a/lab/nova/Makefile b/lab/nova/Makefile
new file mode 100644
index 0000000..a4f1099
--- /dev/null
+++ b/lab/nova/Makefile
@@ -0,0 +1,12 @@
+.PHONY: all build run clean
+
+all: build run
+
+build:
+	mvn -q package
+
+run:
+	java -jar target/nova-1.0-SNAPSHOT.jar
+
+clean:
+	mvn -q clean
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/BIOS.java b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/BIOS.java
new file mode 100644
index 0000000..ecbef49
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/BIOS.java
@@ -0,0 +1,237 @@
+package com.github._0x4248.nova.BIOS;
+
+import com.github._0x4248.nova.BIOS.machines.Machine;
+import com.github._0x4248.nova.BIOS.machines.StandardMachine;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class BIOS {
+	private static volatile BiosRuntime activeRuntime;
+	private static final int LOG_FOREGROUND = 15;
+	private static final int LOG_BACKGROUND = 1;
+	private static final int HEADER_FOREGROUND = 14;
+	private static final DateTimeFormatter CLOCK_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss");
+
+	private final Machine machine;
+	private final BiosRuntime runtime;
+	private final List<String> logLines;
+	private final int maxLogLines;
+
+	public BIOS() {
+		this(new StandardMachine());
+	}
+
+	public BIOS(Machine machine) {
+		this.machine = machine;
+		this.runtime = new BiosRuntime(machine);
+		activeRuntime = this.runtime;
+		this.logLines = new ArrayList<>();
+		this.maxLogLines = 22;
+
+		initializeScreen();
+	}
+
+	public static BiosRuntime getRuntime() {
+		return activeRuntime;
+	}
+
+	public boolean bootApplication(Path applicationJarPath, String[] applicationArgs) {
+		if (applicationJarPath == null) {
+			log("Boot failed: no application path provided.");
+			return false;
+		}
+
+		if (!Files.exists(applicationJarPath) || !Files.isRegularFile(applicationJarPath)) {
+			log("Boot failed: application not found at " + applicationJarPath.toAbsolutePath());
+			return false;
+		}
+
+		log("Boot device detected: " + applicationJarPath.getFileName());
+
+		String mainClassName;
+		try {
+			mainClassName = resolveMainClass(applicationJarPath);
+		} catch (IOException e) {
+			log("Boot failed: cannot read application jar metadata.");
+			return false;
+		}
+
+		if (mainClassName == null || mainClassName.isBlank()) {
+			log("Boot failed: no boot entry found (manifest Main-Class, Boot, or Main).");
+			return false;
+		}
+
+		log("Entrypoint: " + mainClassName);
+		log("Handing off control to application...");
+		runtime.beep(70, 720);
+
+		URL jarUrl;
+		try {
+			jarUrl = applicationJarPath.toUri().toURL();
+		} catch (IOException e) {
+			log("Boot failed: invalid application jar URL.");
+			return false;
+		}
+
+		try (URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl}, BIOS.class.getClassLoader())) {
+			invokeMainClass(mainClassName, classLoader, applicationArgs);
+			System.out.println("[BIOS] Application exited.");
+			return true;
+		} catch (ClassNotFoundException e) {
+			log("Boot failed: main class not found: " + mainClassName);
+			return false;
+		} catch (NoSuchMethodException e) {
+			log("Boot failed: class has no main(String[] args): " + mainClassName);
+			return false;
+		} catch (IllegalAccessException e) {
+			log("Boot failed: cannot access main method: " + mainClassName);
+			return false;
+		} catch (InvocationTargetException e) {
+			log("Application crashed: " + e.getTargetException());
+			return false;
+		} catch (IOException e) {
+			log("Boot failed: cannot open classloader.");
+			return false;
+		}
+	}
+
+	public boolean bootInternalApplication(String className, String[] applicationArgs) {
+		if (className == null || className.isBlank()) {
+			log("Boot failed: no internal class name provided.");
+			return false;
+		}
+
+		log("Boot source: internal ROM application");
+		log("Entrypoint: " + className);
+		log("Handing off control to application...");
+		runtime.beep(70, 720);
+
+		try {
+			invokeMainClass(className, BIOS.class.getClassLoader(), applicationArgs);
+			System.out.println("[BIOS] Application exited.");
+			return true;
+		} catch (ClassNotFoundException e) {
+			log("Boot failed: main class not found: " + className);
+			return false;
+		} catch (NoSuchMethodException e) {
+			log("Boot failed: class has no main(String[] args): " + className);
+			return false;
+		} catch (IllegalAccessException e) {
+			log("Boot failed: cannot access main method: " + className);
+			return false;
+		} catch (InvocationTargetException e) {
+			log("Application crashed: " + e.getTargetException());
+			return false;
+		}
+	}
+
+	private void initializeScreen() {
+		runtime.clear(LOG_BACKGROUND);
+		runtime.drawText(8, 8, machine.biosLabel, HEADER_FOREGROUND, LOG_BACKGROUND, false);
+		runtime.drawText(8, 20, "Boot sequence start", LOG_FOREGROUND, LOG_BACKGROUND, false);
+		present();
+		runtime.beep(60, 520);
+	}
+
+	private void log(String message) {
+		String timestamp = LocalTime.now().format(CLOCK_FORMAT);
+		String line = "[" + timestamp + "] " + message;
+		System.out.println("[BIOS] " + message);
+
+		logLines.add(line);
+		if (logLines.size() > maxLogLines) {
+			logLines.remove(0);
+		}
+
+		renderLogScreen();
+		present();
+	}
+
+	private void renderLogScreen() {
+		runtime.clear(LOG_BACKGROUND);
+		runtime.drawText(8, 8, machine.biosLabel, HEADER_FOREGROUND, LOG_BACKGROUND, false);
+		runtime.drawText(8, 20, "Boot log", HEADER_FOREGROUND, LOG_BACKGROUND, false);
+
+		int y = 36;
+		int maxCharsPerLine = Math.max(1, runtime.getTextColumns() - 2);
+		for (String line : logLines) {
+			String clipped = line.length() > maxCharsPerLine ? line.substring(0, maxCharsPerLine) : line;
+			runtime.drawText(8, y, clipped, LOG_FOREGROUND, LOG_BACKGROUND, false);
+			y += 8;
+		}
+	}
+
+	private void present() {
+		runtime.present();
+	}
+
+	private void invokeMainClass(String className, ClassLoader classLoader, String[] applicationArgs)
+			throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+		Class<?> mainClass = Class.forName(className, true, classLoader);
+		Method mainMethod = mainClass.getMethod("main", String[].class);
+
+		int modifiers = mainMethod.getModifiers();
+		if (!Modifier.isPublic(modifiers) || !Modifier.isStatic(modifiers)) {
+			throw new IllegalAccessException("main method must be public static");
+		}
+
+		mainMethod.invoke(null, (Object) (applicationArgs == null ? new String[0] : applicationArgs));
+	}
+
+	private String resolveMainClass(Path applicationJarPath) throws IOException {
+		try (JarFile jarFile = new JarFile(applicationJarPath.toFile())) {
+			if (jarFile.getManifest() != null) {
+				Attributes mainAttributes = jarFile.getManifest().getMainAttributes();
+				String manifestMainClass = mainAttributes.getValue(Attributes.Name.MAIN_CLASS);
+				if (manifestMainClass != null && !manifestMainClass.isBlank()) {
+					return manifestMainClass.trim();
+				}
+			}
+
+			String bootClass = null;
+			String mainClass = null;
+
+			Enumeration<JarEntry> entries = jarFile.entries();
+			while (entries.hasMoreElements()) {
+				JarEntry entry = entries.nextElement();
+				String name = entry.getName();
+				if (!name.endsWith(".class") || name.contains("$") || name.startsWith("META-INF/")) {
+					continue;
+				}
+
+				String className = name.substring(0, name.length() - 6).replace('/', '.');
+				String simpleName = className.substring(className.lastIndexOf('.') + 1);
+
+				if (simpleName.equalsIgnoreCase("Boot")) {
+					bootClass = className;
+					break;
+				}
+
+				if (mainClass == null && simpleName.equalsIgnoreCase("Main")) {
+					mainClass = className;
+				}
+			}
+
+			if (bootClass != null) {
+				return bootClass;
+			}
+
+			return mainClass;
+		}
+	}
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/BiosRuntime.java b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/BiosRuntime.java
new file mode 100644
index 0000000..fae6889
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/BiosRuntime.java
@@ -0,0 +1,71 @@
+package com.github._0x4248.nova.BIOS;
+
+import com.github._0x4248.nova.BIOS.VGA.VGA;
+import com.github._0x4248.nova.BIOS.machines.Machine;
+import com.github._0x4248.nova.Core.Gui;
+
+public class BiosRuntime {
+
+    private final Machine machine;
+    private final VGA vga;
+    private final Gui screen;
+
+    public BiosRuntime(Machine machine) {
+        this.machine = machine;
+        this.vga = new VGA();
+        this.screen = new Gui(vga.getWidth() * machine.screenScale, vga.getHeight() * machine.screenScale);
+    }
+
+    public Machine getMachine() {
+        return machine;
+    }
+
+    public int getWidth() {
+        return vga.getWidth();
+    }
+
+    public int getHeight() {
+        return vga.getHeight();
+    }
+
+    public int getTextColumns() {
+        return getWidth() / 8;
+    }
+
+    public void clear(int colorIndex) {
+        vga.clear(colorIndex);
+    }
+
+    public void drawText(int x, int y, String text, int foregroundColor, int backgroundColor, boolean transparentBackground) {
+        vga.drawText(x, y, text, foregroundColor, backgroundColor, transparentBackground);
+    }
+
+    public void setPixel(int x, int y, int colorIndex) {
+        vga.setPixel(x, y, colorIndex);
+    }
+
+    public void present() {
+        vga.blitToGui(screen, machine.screenScale);
+    }
+
+    public void beep(int lengthMs, int pitchHz) {
+        if (!machine.supportsSound) {
+            return;
+        }
+        screen.biosBeep(lengthMs, pitchHz);
+    }
+
+    public boolean hasKeyPress() {
+        if (!machine.supportsKeyboard) {
+            return false;
+        }
+        return screen.hasKeyPress();
+    }
+
+    public Integer pollKeyCode() {
+        if (!machine.supportsKeyboard) {
+            return null;
+        }
+        return screen.pollKeyCode();
+    }
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/VGA/VGA.java b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/VGA/VGA.java
new file mode 100644
index 0000000..cfa996d
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/VGA/VGA.java
@@ -0,0 +1,193 @@
+package com.github._0x4248.nova.BIOS.VGA;
+
+import com.github._0x4248.nova.Core.Gui;
+
+import java.awt.image.BufferedImage;
+import java.util.Arrays;
+
+public class VGA {
+
+	public static final int MODE13H_WIDTH = 320;
+	public static final int MODE13H_HEIGHT = 200;
+
+	private final int width;
+	private final int height;
+	private final byte[] framebuffer;
+	private final int[] palette;
+
+	public VGA() {
+		this(MODE13H_WIDTH, MODE13H_HEIGHT);
+	}
+
+	public VGA(int width, int height) {
+		if (width <= 0 || height <= 0) {
+			throw new IllegalArgumentException("Width and height must be positive");
+		}
+
+		this.width = width;
+		this.height = height;
+		this.framebuffer = new byte[width * height];
+		this.palette = new int[256];
+
+		initializeDefaultPalette();
+	}
+
+	public int getWidth() {
+		return width;
+	}
+
+	public int getHeight() {
+		return height;
+	}
+
+	public void clear(int colorIndex) {
+		Arrays.fill(framebuffer, toPaletteIndex(colorIndex));
+	}
+
+	public void setPixel(int x, int y, int colorIndex) {
+		if (x < 0 || y < 0 || x >= width || y >= height) {
+			return;
+		}
+
+		framebuffer[y * width + x] = toPaletteIndex(colorIndex);
+	}
+
+	public int getPixel(int x, int y) {
+		if (x < 0 || y < 0 || x >= width || y >= height) {
+			return 0;
+		}
+
+		return framebuffer[y * width + x] & 0xFF;
+	}
+
+	public void drawChar(int x, int y, char character, int foregroundColor, int backgroundColor, boolean transparentBackground) {
+		int glyphIndex = character & 0x7F;
+		if (glyphIndex >= VGAFonts.LATIN8x8.length) {
+			glyphIndex = '?';
+		}
+
+		byte[] glyph = VGAFonts.LATIN8x8[glyphIndex];
+
+		for (int row = 0; row < 8; row++) {
+			int rowBits = glyph[row] & 0xFF;
+
+			for (int col = 0; col < 8; col++) {
+				boolean on = ((rowBits >> col) & 1) == 1;
+				if (on) {
+					setPixel(x + col, y + row, foregroundColor);
+				} else if (!transparentBackground) {
+					setPixel(x + col, y + row, backgroundColor);
+				}
+			}
+		}
+	}
+
+	public void drawText(int x, int y, String text, int foregroundColor, int backgroundColor, boolean transparentBackground) {
+		int cursorX = x;
+		int cursorY = y;
+
+		for (int i = 0; i < text.length(); i++) {
+			char character = text.charAt(i);
+
+			if (character == '\n') {
+				cursorX = x;
+				cursorY += 8;
+				continue;
+			}
+
+			drawChar(cursorX, cursorY, character, foregroundColor, backgroundColor, transparentBackground);
+			cursorX += 8;
+		}
+	}
+
+	public void setPaletteEntry(int index, int r, int g, int b) {
+		if (index < 0 || index > 255) {
+			return;
+		}
+
+		int red = clamp8(r);
+		int green = clamp8(g);
+		int blue = clamp8(b);
+		palette[index] = (red << 16) | (green << 8) | blue;
+	}
+
+	public int getPaletteEntry(int index) {
+		if (index < 0 || index > 255) {
+			return 0;
+		}
+
+		return palette[index];
+	}
+
+	public int[] toRgbBuffer() {
+		int[] rgb = new int[framebuffer.length];
+		for (int i = 0; i < framebuffer.length; i++) {
+			rgb[i] = palette[framebuffer[i] & 0xFF];
+		}
+		return rgb;
+	}
+
+	public BufferedImage toBufferedImage() {
+		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+		image.setRGB(0, 0, width, height, toRgbBuffer(), 0, width);
+		return image;
+	}
+
+	public void blitToGui(Gui gui, int scale) {
+		if (gui == null || scale <= 0) {
+			return;
+		}
+                try {
+            Thread.sleep(1);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+		int[] rgb = toRgbBuffer();
+
+		for (int y = 0; y < height; y++) {
+			for (int x = 0; x < width; x++) {
+				int color = rgb[y * width + x];
+				int r = (color >> 16) & 0xFF;
+				int g = (color >> 8) & 0xFF;
+				int b = color & 0xFF;
+
+				int baseX = x * scale;
+				int baseY = y * scale;
+
+				for (int sy = 0; sy < scale; sy++) {
+					for (int sx = 0; sx < scale; sx++) {
+						gui.putPixel(baseX + sx, baseY + sy, r, g, b);
+					}
+				}
+			}
+		}
+	}
+
+	public void blitToGui(Gui gui) {
+		blitToGui(gui, 1);
+	}
+
+	private byte toPaletteIndex(int colorIndex) {
+		return (byte) (colorIndex & 0xFF);
+	}
+
+	private int clamp8(int value) {
+		return Math.max(0, Math.min(255, value));
+	}
+
+	private void initializeDefaultPalette() {
+		int[] ega16 = {
+				0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
+				0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
+				0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
+				0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
+		};
+
+		System.arraycopy(ega16, 0, palette, 0, ega16.length);
+
+		for (int i = 16; i < 256; i++) {
+			int gray = (int) Math.round(((i - 16) / 239.0) * 255.0);
+			palette[i] = (gray << 16) | (gray << 8) | gray;
+		}
+	}
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/VGA/VGAFonts.java b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/VGA/VGAFonts.java
new file mode 100644
index 0000000..de366a8
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/VGA/VGAFonts.java
@@ -0,0 +1,135 @@
+package com.github._0x4248.nova.BIOS.VGA;
+
+public class VGAFonts {
+    public static final byte[][] LATIN8x8 = {
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0000 (nul)
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0001
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0002
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0003
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0004
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0005
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0006
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0007
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0008
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0009
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000A
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000B
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000C
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000D
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000E
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000F
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0010
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0011
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0012
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0013
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0014
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0015
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0016
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0017
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0018
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0019
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001A
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001B
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001C
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001D
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001E
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001F
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0020 (space)
+    { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},   // U+0021 (!)
+    { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0022 (")
+    { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},   // U+0023 (#)
+    { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},   // U+0024 ($)
+    { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},   // U+0025 (%)
+    { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},   // U+0026 (&)
+    { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0027 (')
+    { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},   // U+0028 (()
+    { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},   // U+0029 ())
+    { 0x00, 0x66, 0x3C, (byte) 0xFF, 0x3C, 0x66, 0x00, 0x00},   // U+002A (*)
+    { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},   // U+002B (+)
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+002C (,)
+    { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},   // U+002D (-)
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+002E (.)
+    { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},   // U+002F (/)
+    { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},   // U+0030 (0)
+    { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},   // U+0031 (1)
+    { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},   // U+0032 (2)
+    { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},   // U+0033 (3)
+    { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},   // U+0034 (4)
+    { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},   // U+0035 (5)
+    { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},   // U+0036 (6)
+    { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},   // U+0037 (7)
+    { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},   // U+0038 (8)
+    { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},   // U+0039 (9)
+    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+003A (:)
+    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+003B (;)
+    { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},   // U+003C (<)
+    { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},   // U+003D (=)
+    { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},   // U+003E (>)
+    { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},   // U+003F (?)
+    { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},   // U+0040 (@)
+    { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},   // U+0041 (A)
+    { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},   // U+0042 (B)
+    { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},   // U+0043 (C)
+    { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},   // U+0044 (D)
+    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},   // U+0045 (E)
+    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},   // U+0046 (F)
+    { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},   // U+0047 (G)
+    { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},   // U+0048 (H)
+    { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0049 (I)
+    { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},   // U+004A (J)
+    { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},   // U+004B (K)
+    { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},   // U+004C (L)
+    { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},   // U+004D (M)
+    { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},   // U+004E (N)
+    { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},   // U+004F (O)
+    { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},   // U+0050 (P)
+    { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},   // U+0051 (Q)
+    { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},   // U+0052 (R)
+    { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},   // U+0053 (S)
+    { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0054 (T)
+    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},   // U+0055 (U)
+    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0056 (V)
+    { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},   // U+0057 (W)
+    { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},   // U+0058 (X)
+    { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},   // U+0059 (Y)
+    { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},   // U+005A (Z)
+    { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},   // U+005B ([)
+    { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},   // U+005C (\)
+    { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},   // U+005D (])
+    { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},   // U+005E (^)
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xFF},   // U+005F (_)
+    { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0060 (`)
+    { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},   // U+0061 (a)
+    { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},   // U+0062 (b)
+    { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},   // U+0063 (c)
+    { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},   // U+0064 (d)
+    { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},   // U+0065 (e)
+    { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},   // U+0066 (f)
+    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0067 (g)
+    { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},   // U+0068 (h)
+    { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0069 (i)
+    { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},   // U+006A (j)
+    { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},   // U+006B (k)
+    { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+006C (l)
+    { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},   // U+006D (m)
+    { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},   // U+006E (n)
+    { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},   // U+006F (o)
+    { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},   // U+0070 (p)
+    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},   // U+0071 (q)
+    { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00},   // U+0072 (r)
+    { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},   // U+0073 (s)
+    { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},   // U+0074 (t)
+    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},   // U+0075 (u)
+    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0076 (v)
+    { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00},   // U+0077 (w)
+    { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},   // U+0078 (x)
+    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0079 (y)
+    { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},   // U+007A (z)
+    { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},   // U+007B ({)
+    { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},   // U+007C (|)
+    { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},   // U+007D (})
+    { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+007E (~)
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}    // U+007F
+    };
+    
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/machines/Machine.java b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/machines/Machine.java
new file mode 100644
index 0000000..7113e3a
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/machines/Machine.java
@@ -0,0 +1,18 @@
+package com.github._0x4248.nova.BIOS.machines;
+
+public class Machine {
+
+    public final String id;
+    public final String biosLabel;
+    public final int screenScale;
+    public final boolean supportsSound;
+    public final boolean supportsKeyboard;
+
+    public Machine(String id, String biosLabel, int screenScale, boolean supportsSound, boolean supportsKeyboard) {
+        this.id = id;
+        this.biosLabel = biosLabel;
+        this.screenScale = screenScale;
+        this.supportsSound = supportsSound;
+        this.supportsKeyboard = supportsKeyboard;
+    }
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/machines/StandardMachine.java b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/machines/StandardMachine.java
new file mode 100644
index 0000000..3b327d1
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/BIOS/machines/StandardMachine.java
@@ -0,0 +1,8 @@
+package com.github._0x4248.nova.BIOS.machines;
+
+public class StandardMachine extends Machine {
+
+    public StandardMachine() {
+        super("STANDARD", "NOVA BIOS v0.1", 4, true, true);
+    }
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Gui.java b/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Gui.java
new file mode 100644
index 0000000..3a58aff
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Gui.java
@@ -0,0 +1,84 @@
+package com.github._0x4248.nova.Core;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.event.*;
+
+public class Gui extends JPanel implements KeyListener {
+
+    private final BufferedImage framebuffer;
+    private final int framebufferWidth;
+    private final int framebufferHeight;
+    private final Keyboard keyboard;
+    private final Sound sound;
+
+    public Gui(int width, int height) {
+        framebufferWidth = width;
+        framebufferHeight = height;
+        framebuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        keyboard = new Keyboard();
+        sound = new Sound();
+
+        JFrame frame = new JFrame("NovaEngine");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        frame.setSize(width, height);
+        frame.add(this);
+        setBackground(Color.BLACK);
+        frame.setVisible(true);
+        frame.addKeyListener(this);
+    }
+
+    // Draw pixel
+    public void putPixel(int x, int y, int r, int g, int b) {
+        int color = (r << 16) | (g << 8) | b;
+        framebuffer.setRGB(x, y, color);
+        repaint();
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        super.paintComponent(g);
+
+        int panelWidth = getWidth();
+        int panelHeight = getHeight();
+
+        double scale = Math.min(
+                (double) panelWidth / framebufferWidth,
+                (double) panelHeight / framebufferHeight
+        );
+
+        int drawWidth = (int) Math.round(framebufferWidth * scale);
+        int drawHeight = (int) Math.round(framebufferHeight * scale);
+        int x = (panelWidth - drawWidth) / 2;
+        int y = (panelHeight - drawHeight) / 2;
+
+        g.drawImage(framebuffer, x, y, drawWidth, drawHeight, null);
+    }
+
+    public boolean hasKeyPress() {
+        return keyboard.hasKeyPress();
+    }
+
+    public Integer pollKeyCode() {
+        return keyboard.pollKeyCode();
+    }
+
+    public void biosBeep(int lengthMs, int pitchHz) {
+        sound.biosBeep(lengthMs, pitchHz);
+    }
+
+    @Override
+    public void keyTyped(KeyEvent e) {
+    }
+
+    @Override
+    public void keyPressed(KeyEvent e) {
+        keyboard.onKeyPressed(e);
+    }
+
+    @Override
+    public void keyReleased(KeyEvent e) {
+    }
+
+}
\ No newline at end of file
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Keyboard.java b/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Keyboard.java
new file mode 100644
index 0000000..040ba8f
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Keyboard.java
@@ -0,0 +1,21 @@
+package com.github._0x4248.nova.Core;
+
+import java.awt.event.KeyEvent;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class Keyboard {
+
+    private final ConcurrentLinkedQueue<Integer> keyQueue = new ConcurrentLinkedQueue<>();
+
+    public boolean hasKeyPress() {
+        return !keyQueue.isEmpty();
+    }
+
+    public Integer pollKeyCode() {
+        return keyQueue.poll();
+    }
+
+    public void onKeyPressed(KeyEvent event) {
+        keyQueue.offer(event.getKeyCode());
+    }
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Sound.java b/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Sound.java
new file mode 100644
index 0000000..d82387d
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/Core/Sound.java
@@ -0,0 +1,75 @@
+package com.github._0x4248.nova.Core;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import java.awt.Toolkit;
+
+public class Sound {
+
+    private static final float BEEP_SAMPLE_RATE = 44100.0f;
+    private static final int BEEP_VOLUME = 64;
+
+    public void biosBeep(int lengthMs, int pitchHz) {
+        if (lengthMs <= 0 || pitchHz <= 0) {
+            return;
+        }
+
+        Thread beepThread = new Thread(() -> playBeep(lengthMs, pitchHz), "bios-beep");
+        beepThread.setDaemon(true);
+        beepThread.start();
+    }
+
+    private void playBeep(int lengthMs, int pitchHz) {
+        AudioFormat[] formats = {
+                new AudioFormat(BEEP_SAMPLE_RATE, 8, 1, true, false),
+                new AudioFormat(BEEP_SAMPLE_RATE, 16, 1, true, false),
+                new AudioFormat(22050.0f, 16, 1, true, false)
+        };
+
+        for (AudioFormat format : formats) {
+            DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class, format);
+            if (!AudioSystem.isLineSupported(lineInfo)) {
+                continue;
+            }
+
+            try (SourceDataLine line = (SourceDataLine) AudioSystem.getLine(lineInfo)) {
+                line.open(format);
+                line.start();
+
+                byte[] buffer = createSquareWaveBuffer(lengthMs, pitchHz, format);
+                line.write(buffer, 0, buffer.length);
+                line.drain();
+                return;
+            } catch (LineUnavailableException | IllegalArgumentException ignored) {
+            }
+        }
+
+        Toolkit.getDefaultToolkit().beep();
+    }
+
+    private byte[] createSquareWaveBuffer(int lengthMs, int pitchHz, AudioFormat format) {
+        int sampleCount = (int) ((format.getSampleRate() * lengthMs) / 1000);
+        int periodSamples = Math.max(1, (int) (format.getSampleRate() / pitchHz));
+
+        if (format.getSampleSizeInBits() == 8) {
+            byte[] buffer = new byte[sampleCount];
+            for (int i = 0; i < sampleCount; i++) {
+                buffer[i] = (byte) ((i % periodSamples) < (periodSamples / 2) ? BEEP_VOLUME : -BEEP_VOLUME);
+            }
+            return buffer;
+        }
+
+        byte[] buffer = new byte[sampleCount * 2];
+        short amplitude = 12000;
+        for (int i = 0; i < sampleCount; i++) {
+            short value = (short) (((i % periodSamples) < (periodSamples / 2)) ? amplitude : -amplitude);
+            int offset = i * 2;
+            buffer[offset] = (byte) (value & 0xFF);
+            buffer[offset + 1] = (byte) ((value >> 8) & 0xFF);
+        }
+        return buffer;
+    }
+}
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova/Main.java b/lab/nova/src/main/java/com/github/_0x4248/nova/Main.java
new file mode 100644
index 0000000..56f99e6
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova/Main.java
@@ -0,0 +1,27 @@
+package com.github._0x4248.nova;
+
+import com.github._0x4248.nova.BIOS.BIOS;
+import com.github._0x4248.nova.BIOS.machines.StandardMachine;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class Main {
+    private static final String DEFAULT_INTERNAL_APP = "com.github._0x4248.nova_examples.ExampleXYZ";
+
+    public static void main(String[] args) {
+        BIOS bios = new BIOS(new StandardMachine());
+        Path applicationJar = Paths.get("Application.jar");
+
+        boolean booted;
+        if (java.nio.file.Files.exists(applicationJar)) {
+            booted = bios.bootApplication(applicationJar, args);
+        } else {
+            booted = bios.bootInternalApplication(DEFAULT_INTERNAL_APP, args);
+        }
+
+        if (!booted) {
+            System.exit(1);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lab/nova/src/main/java/com/github/_0x4248/nova_examples/ExampleXYZ.java b/lab/nova/src/main/java/com/github/_0x4248/nova_examples/ExampleXYZ.java
new file mode 100644
index 0000000..b15add9
--- /dev/null
+++ b/lab/nova/src/main/java/com/github/_0x4248/nova_examples/ExampleXYZ.java
@@ -0,0 +1,49 @@
+package com.github._0x4248.nova_examples;
+
+import com.github._0x4248.nova.BIOS.BIOS;
+import com.github._0x4248.nova.BIOS.BiosRuntime;
+import com.github._0x4248.nova.BIOS.machines.StandardMachine;
+
+public class ExampleXYZ {
+    public static final int BOOTFLAG = 1;
+
+    public static void main(String[] args) {
+        System.out.println("Launching Example XYZ...");
+        BiosRuntime bios = BIOS.getRuntime();
+        if (bios == null) {
+            bios = new BiosRuntime(new StandardMachine());
+        }
+
+        bios.clear(1);
+        bios.drawText(24, 32, "HELLO WORLD", 15, 1, false);
+        bios.drawText(24, 48, "NOVA EXAMPLE XYZ", 14, 1, false);
+
+        if (!bios.getMachine().supportsSound) {
+            bios.drawText(24, 64, "NO SOUND DEVICE", 12, 1, false);
+        }
+
+        bios.present();
+        try{
+            Thread.sleep(2500);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        while (true) {
+                bios.clear(0);
+                bios.beep(200, 440);
+                bios.present();
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                bios.drawText(0, 0, "This is just an example", 15, 0, false);
+                bios.present();
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+        }
+    }
+}
diff --git a/lab/nova/target/site/css/maven-base.css b/lab/nova/target/site/css/maven-base.css
new file mode 100644
index 0000000..742a735
--- /dev/null
+++ b/lab/nova/target/site/css/maven-base.css
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+body {
+  margin: 0px;
+  padding: 0px;
+}
+table {
+  padding:0px;
+  width: 100%;
+  margin-left: -2px;
+  margin-right: -2px;
+}
+acronym {
+  cursor: help;
+  border-bottom: 1px dotted #feb;
+}
+table.bodyTable th, table.bodyTable td {
+  padding: 2px 4px 2px 4px;
+  vertical-align: top;
+}
+div.clear {
+  clear:both;
+  visibility: hidden;
+}
+div.clear hr {
+  display: none;
+}
+#bannerLeft, #bannerRight {
+  font-size: xx-large;
+  font-weight: bold;
+}
+#bannerLeft img, #bannerRight img {
+  margin: 0px;
+}
+.xleft, #bannerLeft img {
+  float:left;
+}
+.xright, #bannerRight {
+  float:right;
+}
+#banner {
+  padding: 0px;
+}
+#breadcrumbs {
+  padding: 3px 10px 3px 10px;
+}
+#leftColumn {
+ width: 170px;
+ float:left;
+ overflow: auto;
+}
+#bodyColumn {
+  margin-right: 1.5em;
+  margin-left: 197px;
+}
+#legend {
+  padding: 8px 0 8px 0;
+}
+#navcolumn {
+  padding: 8px 4px 0 8px;
+}
+#navcolumn h5 {
+  margin: 0;
+  padding: 0;
+  font-size: small;
+}
+#navcolumn ul {
+  margin: 0;
+  padding: 0;
+  font-size: small;
+}
+#navcolumn li {
+  list-style-type: none;
+  background-image: none;
+  background-repeat: no-repeat;
+  background-position: 0 0.4em;
+  padding-left: 16px;
+  list-style-position: outside;
+  line-height: 1.2em;
+  font-size: smaller;
+}
+#navcolumn li.expanded {
+  background-image: url(../images/expanded.gif);
+}
+#navcolumn li.collapsed {
+  background-image: url(../images/collapsed.gif);
+}
+#navcolumn li.none {
+  text-indent: -1em;
+  margin-left: 1em;
+}
+#poweredBy {
+  text-align: center;
+}
+#navcolumn img {
+  margin-top: 10px;
+  margin-bottom: 3px;
+}
+#poweredBy img {
+  display:block;
+  margin: 20px 0 20px 17px;
+}
+#search img {
+    margin: 0px;
+    display: block;
+}
+#search #q, #search #btnG {
+    border: 1px solid #999;
+    margin-bottom:10px;
+}
+#search form {
+    margin: 0px;
+}
+#lastPublished {
+  font-size: x-small;
+}
+.navSection {
+  margin-bottom: 2px;
+  padding: 8px;
+}
+.navSectionHead {
+  font-weight: bold;
+  font-size: x-small;
+}
+.section {
+  padding: 4px;
+}
+#footer {
+  padding: 3px 10px 3px 10px;
+  font-size: x-small;
+}
+#breadcrumbs {
+  font-size: x-small;
+  margin: 0pt;
+}
+.source {
+  padding: 12px;
+  margin: 1em 7px 1em 7px;
+}
+.source pre {
+  margin: 0px;
+  padding: 0px;
+}
+#navcolumn img.imageLink, .imageLink {
+  padding-left: 0px;
+  padding-bottom: 0px;
+  padding-top: 0px;
+  padding-right: 2px;
+  border: 0px;
+  margin: 0px;
+}
diff --git a/lab/nova/target/site/css/maven-theme.css b/lab/nova/target/site/css/maven-theme.css
new file mode 100644
index 0000000..4e2bdfb
--- /dev/null
+++ b/lab/nova/target/site/css/maven-theme.css
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+body {
+  padding: 0px 0px 10px 0px;
+}
+body, td, select, input, li{
+  font-family: Verdana, Helvetica, Arial, sans-serif;
+  font-size: 13px;
+}
+code{
+  font-family: Courier, monospace;
+  font-size: 13px;
+}
+a {
+  text-decoration: none;
+}
+a:link {
+  color:#36a;
+}
+a:visited  {
+  color:#47a;
+}
+a:active, a:hover {
+  color:#69c;
+}
+#legend li.externalLink {
+  background: url(../images/external.png) left top no-repeat;
+  padding-left: 18px;
+}
+a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
+  background: url(../images/external.png) right center no-repeat;
+  padding-right: 18px;
+}
+#legend li.newWindow {
+  background: url(../images/newwindow.png) left top no-repeat;
+  padding-left: 18px;
+}
+a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover {
+  background: url(../images/newwindow.png) right center no-repeat;
+  padding-right: 18px;
+}
+h2 {
+  padding: 4px 4px 4px 6px;
+  border: 1px solid #999;
+  color: #900;
+  background-color: #ddd;
+  font-weight:900;
+  font-size: x-large;
+}
+h3 {
+  padding: 4px 4px 4px 6px;
+  border: 1px solid #aaa;
+  color: #900;
+  background-color: #eee;
+  font-weight: normal;
+  font-size: large;
+}
+h4 {
+  padding: 4px 4px 4px 6px;
+  border: 1px solid #bbb;
+  color: #900;
+  background-color: #fff;
+  font-weight: normal;
+  font-size: large;
+}
+h5 {
+  padding: 4px 4px 4px 6px;
+  color: #900;
+  font-size: medium;
+}
+p {
+  line-height: 1.3em;
+  font-size: small;
+}
+#breadcrumbs {
+  border-top: 1px solid #aaa;
+  border-bottom: 1px solid #aaa;
+  background-color: #ccc;
+}
+#leftColumn {
+  margin: 10px 0 0 5px;
+  border: 1px solid #999;
+  background-color: #eee;
+  padding-bottom: 3px; /* IE-9 scrollbar-fix */
+}
+#navcolumn h5 {
+  font-size: smaller;
+  border-bottom: 1px solid #aaaaaa;
+  padding-top: 2px;
+  color: #000;
+}
+
+table.bodyTable th {
+  color: white;
+  background-color: #bbb;
+  text-align: left;
+  font-weight: bold;
+}
+
+table.bodyTable th, table.bodyTable td {
+  font-size: 1em;
+}
+
+table.bodyTable tr.a {
+  background-color: #ddd;
+}
+
+table.bodyTable tr.b {
+  background-color: #eee;
+}
+
+.source {
+  border: 1px solid #999;
+}
+dl {
+  padding: 4px 4px 4px 6px;
+  border: 1px solid #aaa;
+  background-color: #ffc;
+}
+dt {
+  color: #900;
+}
+#organizationLogo img, #projectLogo img, #projectLogo span{
+  margin: 8px;
+}
+#banner {
+  border-bottom: 1px solid #fff;
+}
+.errormark, .warningmark, .donemark, .infomark {
+  background: url(../images/icon_error_sml.gif) no-repeat;
+}
+
+.warningmark {
+  background-image: url(../images/icon_warning_sml.gif);
+}
+
+.donemark {
+  background-image: url(../images/icon_success_sml.gif);
+}
+
+.infomark {
+  background-image: url(../images/icon_info_sml.gif);
+}
+
diff --git a/lab/nova/target/site/css/print.css b/lab/nova/target/site/css/print.css
new file mode 100644
index 0000000..97be85f
--- /dev/null
+++ b/lab/nova/target/site/css/print.css
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn {
+	display: none !important;
+}
+#bodyColumn, body.docs div.docs {
+	margin: 0 !important;
+	border: none !important
+}
diff --git a/lab/nova/target/site/css/site.css b/lab/nova/target/site/css/site.css
new file mode 100644
index 0000000..055e7e2
--- /dev/null
+++ b/lab/nova/target/site/css/site.css
@@ -0,0 +1 @@
+/* You can override this file with your own styles */
\ No newline at end of file
diff --git a/lab/nova/target/site/dependency-info.html b/lab/nova/target/site/dependency-info.html
new file mode 100644
index 0000000..31a56a8
--- /dev/null
+++ b/lab/nova/target/site/dependency-info.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<!--
+ | Generated by Apache Maven Doxia Site Renderer 1.11.1 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.6.1:dependency-info at 2026-02-21
+
+ | Rendered using Apache Maven Default Skin
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="generator" content="Apache Maven Doxia Site Renderer 1.11.1" />
+    <title>nova &#x2013; Maven Coordinates</title>
+    <link rel="stylesheet" href="./css/maven-base.css" />
+    <link rel="stylesheet" href="./css/maven-theme.css" />
+    <link rel="stylesheet" href="./css/site.css" />
+    <link rel="stylesheet" href="./css/print.css" media="print" />
+  </head>
+  <body class="composite">
+    <div id="banner">
+<div id="bannerLeft">nova
+</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      <div class="xleft">
+        <span id="publishDate">Last Published: 2026-02-21</span>
+           | <span id="projectVersion">Version: 1.0-SNAPSHOT</span>
+      </div>
+      <div class="xright"><a href="./" title="nova">nova</a>      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       <h5>Project Documentation</h5>
+    <ul>
+     <li class="expanded"><a href="project-info.html" title="Project Information">Project Information</a>
+      <ul>
+       <li class="none"><strong>Maven Coordinates</strong></li>
+       <li class="none"><a href="index.html" title="About">About</a></li>
+       <li class="none"><a href="plugin-management.html" title="Plugin Management">Plugin Management</a></li>
+       <li class="none"><a href="plugins.html" title="Plugins">Plugins</a></li>
+       <li class="none"><a href="summary.html" title="Summary">Summary</a></li>
+      </ul></li>
+    </ul>
+      <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
+        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
+      </a>
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+<section>
+<h2><a name="Maven_Coordinates"></a>Maven Coordinates</h2><a name="Maven_Coordinates"></a><section>
+<h3><a name="Apache_Maven"></a>Apache Maven</h3><a name="Apache_Maven"></a>
+<div>
+<pre>&lt;dependency&gt;
+  &lt;groupId&gt;com.github._0x4248&lt;/groupId&gt;
+  &lt;artifactId&gt;nova&lt;/artifactId&gt;
+  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
+&lt;/dependency&gt;</pre></div></section><section>
+<h3><a name="Apache_Ivy"></a>Apache Ivy</h3><a name="Apache_Ivy"></a>
+<div>
+<pre>&lt;dependency org=&quot;com.github._0x4248&quot; name=&quot;nova&quot; rev=&quot;1.0-SNAPSHOT&quot;&gt;
+  &lt;artifact name=&quot;nova&quot; type=&quot;jar&quot; /&gt;
+&lt;/dependency&gt;</pre></div></section><section>
+<h3><a name="Groovy_Grape"></a>Groovy Grape</h3><a name="Groovy_Grape"></a>
+<div>
+<pre>@Grapes(
+@Grab(group='com.github._0x4248', module='nova', version='1.0-SNAPSHOT')
+)</pre></div></section><section>
+<h3><a name="Gradle.2FGrails"></a>Gradle/Grails</h3><a name="Gradle.2FGrails"></a>
+<div>
+<pre>implementation 'com.github._0x4248:nova:1.0-SNAPSHOT'</pre></div></section><section>
+<h3><a name="Scala_SBT"></a>Scala SBT</h3><a name="Scala_SBT"></a>
+<div>
+<pre>libraryDependencies += &quot;com.github._0x4248&quot; % &quot;nova&quot; % &quot;1.0-SNAPSHOT&quot;</pre></div></section><section>
+<h3><a name="Leiningen"></a>Leiningen</h3><a name="Leiningen"></a>
+<div>
+<pre>[com.github._0x4248/nova &quot;1.0-SNAPSHOT&quot;]</pre></div></section></section>
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">
+        Copyright &#169;      2026..      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/lab/nova/target/site/index.html b/lab/nova/target/site/index.html
new file mode 100644
index 0000000..9ca40b4
--- /dev/null
+++ b/lab/nova/target/site/index.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<!--
+ | Generated by Apache Maven Doxia Site Renderer 1.11.1 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.6.1:index at 2026-02-21
+
+ | Rendered using Apache Maven Default Skin
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="generator" content="Apache Maven Doxia Site Renderer 1.11.1" />
+    <title>nova &#x2013; About</title>
+    <link rel="stylesheet" href="./css/maven-base.css" />
+    <link rel="stylesheet" href="./css/maven-theme.css" />
+    <link rel="stylesheet" href="./css/site.css" />
+    <link rel="stylesheet" href="./css/print.css" media="print" />
+  </head>
+  <body class="composite">
+    <div id="banner">
+<div id="bannerLeft">nova
+</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      <div class="xleft">
+        <span id="publishDate">Last Published: 2026-02-21</span>
+           | <span id="projectVersion">Version: 1.0-SNAPSHOT</span>
+      </div>
+      <div class="xright"><a href="./" title="nova">nova</a>      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       <h5>Project Documentation</h5>
+    <ul>
+     <li class="expanded"><a href="project-info.html" title="Project Information">Project Information</a>
+      <ul>
+       <li class="none"><a href="dependency-info.html" title="Maven Coordinates">Maven Coordinates</a></li>
+       <li class="none"><strong>About</strong></li>
+       <li class="none"><a href="plugin-management.html" title="Plugin Management">Plugin Management</a></li>
+       <li class="none"><a href="plugins.html" title="Plugins">Plugins</a></li>
+       <li class="none"><a href="summary.html" title="Summary">Summary</a></li>
+      </ul></li>
+    </ul>
+      <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
+        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
+      </a>
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+<section>
+<h2><a name="About_nova"></a>About nova</h2><a name="About_nova"></a>
+<p>There is currently no description associated with this project.</p></section>
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">
+        Copyright &#169;      2026..      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/lab/nova/target/site/plugin-management.html b/lab/nova/target/site/plugin-management.html
new file mode 100644
index 0000000..0d079ab
--- /dev/null
+++ b/lab/nova/target/site/plugin-management.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<!--
+ | Generated by Apache Maven Doxia Site Renderer 1.11.1 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.6.1:plugin-management at 2026-02-21
+
+ | Rendered using Apache Maven Default Skin
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="generator" content="Apache Maven Doxia Site Renderer 1.11.1" />
+    <title>nova &#x2013; Project Plugin Management</title>
+    <link rel="stylesheet" href="./css/maven-base.css" />
+    <link rel="stylesheet" href="./css/maven-theme.css" />
+    <link rel="stylesheet" href="./css/site.css" />
+    <link rel="stylesheet" href="./css/print.css" media="print" />
+  </head>
+  <body class="composite">
+    <div id="banner">
+<div id="bannerLeft">nova
+</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      <div class="xleft">
+        <span id="publishDate">Last Published: 2026-02-21</span>
+           | <span id="projectVersion">Version: 1.0-SNAPSHOT</span>
+      </div>
+      <div class="xright"><a href="./" title="nova">nova</a>      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       <h5>Project Documentation</h5>
+    <ul>
+     <li class="expanded"><a href="project-info.html" title="Project Information">Project Information</a>
+      <ul>
+       <li class="none"><a href="dependency-info.html" title="Maven Coordinates">Maven Coordinates</a></li>
+       <li class="none"><a href="index.html" title="About">About</a></li>
+       <li class="none"><strong>Plugin Management</strong></li>
+       <li class="none"><a href="plugins.html" title="Plugins">Plugins</a></li>
+       <li class="none"><a href="summary.html" title="Summary">Summary</a></li>
+      </ul></li>
+    </ul>
+      <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
+        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
+      </a>
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+<section>
+<h2><a name="Project_Plugin_Management"></a>Project Plugin Management</h2><a name="Project_Plugin_Management"></a>
+<table border="0" class="bodyTable">
+<tr class="a">
+<th>GroupId</th>
+<th>ArtifactId</th>
+<th>Version</th></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-antrun-plugin/">maven-antrun-plugin</a></td>
+<td>3.1.0</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-assembly-plugin/">maven-assembly-plugin</a></td>
+<td>3.7.1</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-clean-plugin/">maven-clean-plugin</a></td>
+<td>3.4.0</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-compiler-plugin/">maven-compiler-plugin</a></td>
+<td>3.13.0</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-dependency-plugin/">maven-dependency-plugin</a></td>
+<td>3.7.0</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-deploy-plugin/">maven-deploy-plugin</a></td>
+<td>3.1.2</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-install-plugin/">maven-install-plugin</a></td>
+<td>3.1.2</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-jar-plugin/">maven-jar-plugin</a></td>
+<td>3.4.2</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-project-info-reports-plugin/">maven-project-info-reports-plugin</a></td>
+<td>3.6.1</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/maven-release/maven-release-plugin/">maven-release-plugin</a></td>
+<td>3.0.1</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-resources-plugin/">maven-resources-plugin</a></td>
+<td>3.3.1</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-site-plugin/">maven-site-plugin</a></td>
+<td>3.12.1</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/surefire/maven-surefire-plugin/">maven-surefire-plugin</a></td>
+<td>3.3.0</td></tr></table></section>
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">
+        Copyright &#169;      2026..      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/lab/nova/target/site/plugins.html b/lab/nova/target/site/plugins.html
new file mode 100644
index 0000000..b8b2d83
--- /dev/null
+++ b/lab/nova/target/site/plugins.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<!--
+ | Generated by Apache Maven Doxia Site Renderer 1.11.1 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.6.1:plugins at 2026-02-21
+
+ | Rendered using Apache Maven Default Skin
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="generator" content="Apache Maven Doxia Site Renderer 1.11.1" />
+    <title>nova &#x2013; Project Plugins</title>
+    <link rel="stylesheet" href="./css/maven-base.css" />
+    <link rel="stylesheet" href="./css/maven-theme.css" />
+    <link rel="stylesheet" href="./css/site.css" />
+    <link rel="stylesheet" href="./css/print.css" media="print" />
+  </head>
+  <body class="composite">
+    <div id="banner">
+<div id="bannerLeft">nova
+</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      <div class="xleft">
+        <span id="publishDate">Last Published: 2026-02-21</span>
+           | <span id="projectVersion">Version: 1.0-SNAPSHOT</span>
+      </div>
+      <div class="xright"><a href="./" title="nova">nova</a>      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       <h5>Project Documentation</h5>
+    <ul>
+     <li class="expanded"><a href="project-info.html" title="Project Information">Project Information</a>
+      <ul>
+       <li class="none"><a href="dependency-info.html" title="Maven Coordinates">Maven Coordinates</a></li>
+       <li class="none"><a href="index.html" title="About">About</a></li>
+       <li class="none"><a href="plugin-management.html" title="Plugin Management">Plugin Management</a></li>
+       <li class="none"><strong>Plugins</strong></li>
+       <li class="none"><a href="summary.html" title="Summary">Summary</a></li>
+      </ul></li>
+    </ul>
+      <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
+        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
+      </a>
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+<section>
+<h2><a name="Project_Build_Plugins"></a>Project Build Plugins</h2><a name="Project_Build_Plugins"></a>
+<table border="0" class="bodyTable">
+<tr class="a">
+<th>GroupId</th>
+<th>ArtifactId</th>
+<th>Version</th></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-clean-plugin/">maven-clean-plugin</a></td>
+<td>3.4.0</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-compiler-plugin/">maven-compiler-plugin</a></td>
+<td>3.13.0</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-deploy-plugin/">maven-deploy-plugin</a></td>
+<td>3.1.2</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-install-plugin/">maven-install-plugin</a></td>
+<td>3.1.2</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-jar-plugin/">maven-jar-plugin</a></td>
+<td>3.4.2</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-resources-plugin/">maven-resources-plugin</a></td>
+<td>3.3.1</td></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-site-plugin/">maven-site-plugin</a></td>
+<td>3.12.1</td></tr>
+<tr class="a">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/surefire/maven-surefire-plugin/">maven-surefire-plugin</a></td>
+<td>3.3.0</td></tr></table></section><section>
+<h2><a name="Project_Report_Plugins"></a>Project Report Plugins</h2><a name="Project_Report_Plugins"></a>
+<table border="0" class="bodyTable">
+<tr class="a">
+<th>GroupId</th>
+<th>ArtifactId</th>
+<th>Version</th></tr>
+<tr class="b">
+<td align="left">org.apache.maven.plugins</td>
+<td><a class="externalLink" href="https://maven.apache.org/plugins/maven-project-info-reports-plugin/">maven-project-info-reports-plugin</a></td>
+<td>3.6.1</td></tr></table></section>
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">
+        Copyright &#169;      2026..      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/lab/nova/target/site/project-info.html b/lab/nova/target/site/project-info.html
new file mode 100644
index 0000000..6f470b6
--- /dev/null
+++ b/lab/nova/target/site/project-info.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<!--
+ | Generated by Apache Maven Doxia Site Renderer 1.11.1 from org.apache.maven.plugins:maven-site-plugin:3.12.1:CategorySummaryDocumentRenderer at 2026-02-21
+
+ | Rendered using Apache Maven Default Skin
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="generator" content="Apache Maven Doxia Site Renderer 1.11.1" />
+    <title>nova &#x2013; Project Information</title>
+    <link rel="stylesheet" href="./css/maven-base.css" />
+    <link rel="stylesheet" href="./css/maven-theme.css" />
+    <link rel="stylesheet" href="./css/site.css" />
+    <link rel="stylesheet" href="./css/print.css" media="print" />
+  </head>
+  <body class="composite">
+    <div id="banner">
+<div id="bannerLeft">nova
+</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      <div class="xleft">
+        <span id="publishDate">Last Published: 2026-02-21</span>
+           | <span id="projectVersion">Version: 1.0-SNAPSHOT</span>
+      </div>
+      <div class="xright"><a href="./" title="nova">nova</a>      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       <h5>Project Documentation</h5>
+    <ul>
+     <li class="expanded"><strong>Project Information</strong>
+      <ul>
+       <li class="none"><a href="dependency-info.html" title="Maven Coordinates">Maven Coordinates</a></li>
+       <li class="none"><a href="index.html" title="About">About</a></li>
+       <li class="none"><a href="plugin-management.html" title="Plugin Management">Plugin Management</a></li>
+       <li class="none"><a href="plugins.html" title="Plugins">Plugins</a></li>
+       <li class="none"><a href="summary.html" title="Summary">Summary</a></li>
+      </ul></li>
+    </ul>
+      <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
+        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
+      </a>
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+<section>
+<h2><a name="Project_Information"></a>Project Information</h2>
+<p>This document provides an overview of the various documents and links that are part of this project's general information. All of this content is automatically generated by <a class="externalLink" href="http://maven.apache.org">Maven</a> on behalf of the project.</p><section>
+<h3><a name="Overview"></a>Overview</h3>
+<table border="0" class="bodyTable">
+<tr class="a">
+<th>Document</th>
+<th>Description</th></tr>
+<tr class="b">
+<td align="left"><a href="dependency-info.html">Maven Coordinates</a></td>
+<td align="left">This document describes how to include this project as a dependency using various dependency management tools.</td></tr>
+<tr class="a">
+<td align="left"><a href="index.html">About</a></td>
+<td align="left">There is currently no description associated with this project.</td></tr>
+<tr class="b">
+<td align="left"><a href="plugin-management.html">Plugin Management</a></td>
+<td align="left">This document lists the plugins that are defined through pluginManagement.</td></tr>
+<tr class="a">
+<td align="left"><a href="plugins.html">Plugins</a></td>
+<td align="left">This document lists the build plugins and the report plugins used by this project.</td></tr>
+<tr class="b">
+<td align="left"><a href="summary.html">Summary</a></td>
+<td align="left">This document lists other related information of this project</td></tr></table></section></section>
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">
+        Copyright &#169;      2026..      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/lab/nova/target/site/summary.html b/lab/nova/target/site/summary.html
new file mode 100644
index 0000000..6a9d3d7
--- /dev/null
+++ b/lab/nova/target/site/summary.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<!--
+ | Generated by Apache Maven Doxia Site Renderer 1.11.1 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.6.1:summary at 2026-02-21
+
+ | Rendered using Apache Maven Default Skin
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="generator" content="Apache Maven Doxia Site Renderer 1.11.1" />
+    <title>nova &#x2013; Project Summary</title>
+    <link rel="stylesheet" href="./css/maven-base.css" />
+    <link rel="stylesheet" href="./css/maven-theme.css" />
+    <link rel="stylesheet" href="./css/site.css" />
+    <link rel="stylesheet" href="./css/print.css" media="print" />
+  </head>
+  <body class="composite">
+    <div id="banner">
+<div id="bannerLeft">nova
+</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      <div class="xleft">
+        <span id="publishDate">Last Published: 2026-02-21</span>
+           | <span id="projectVersion">Version: 1.0-SNAPSHOT</span>
+      </div>
+      <div class="xright"><a href="./" title="nova">nova</a>      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       <h5>Project Documentation</h5>
+    <ul>
+     <li class="expanded"><a href="project-info.html" title="Project Information">Project Information</a>
+      <ul>
+       <li class="none"><a href="dependency-info.html" title="Maven Coordinates">Maven Coordinates</a></li>
+       <li class="none"><a href="index.html" title="About">About</a></li>
+       <li class="none"><a href="plugin-management.html" title="Plugin Management">Plugin Management</a></li>
+       <li class="none"><a href="plugins.html" title="Plugins">Plugins</a></li>
+       <li class="none"><strong>Summary</strong></li>
+      </ul></li>
+    </ul>
+      <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
+        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
+      </a>
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+<section>
+<h2><a name="Project_Summary"></a>Project Summary</h2><a name="Project_Summary"></a><section>
+<h3><a name="Project_Information"></a>Project Information</h3><a name="Project_Information"></a>
+<table border="0" class="bodyTable">
+<tr class="a">
+<th>Field</th>
+<th>Value</th></tr>
+<tr class="b">
+<td align="left">Name</td>
+<td>nova</td></tr>
+<tr class="a">
+<td align="left">Description</td>
+<td>-</td></tr>
+<tr class="b">
+<td align="left">Homepage</td>
+<td><a class="externalLink" href="http://www.example.com">http://www.example.com</a></td></tr></table></section><section>
+<h3><a name="Project_Organization"></a>Project Organization</h3><a name="Project_Organization"></a>
+<p>This project does not belong to an organization.</p></section><section>
+<h3><a name="Build_Information"></a>Build Information</h3><a name="Build_Information"></a>
+<table border="0" class="bodyTable">
+<tr class="a">
+<th>Field</th>
+<th>Value</th></tr>
+<tr class="b">
+<td align="left">GroupId</td>
+<td>com.github._0x4248</td></tr>
+<tr class="a">
+<td align="left">ArtifactId</td>
+<td>nova</td></tr>
+<tr class="b">
+<td align="left">Version</td>
+<td>1.0-SNAPSHOT</td></tr>
+<tr class="a">
+<td align="left">Type</td>
+<td>jar</td></tr>
+<tr class="b">
+<td align="left">Java Version</td>
+<td>-</td></tr></table></section></section>
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">
+        Copyright &#169;      2026..      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
[COMMIT END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.