import assert from "node:assert/strict"; import fs from "node:fs"; const reader = fs.readFileSync(new URL("../../blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", import.meta.url), "utf8"); const registry = fs.readFileSync(new URL("../../blender-5.2.0/source/blender/modifiers/intern/MOD_util.cc", import.meta.url), "utf8"); const table = reader.match(/static const char \*const names\[\] = \{([\s\S]*?)\};\s*static_assert\(std::size\(names\) == NUM_MODIFIER_TYPES/); assert.ok(table, "modifier identity table is missing its NUM_MODIFIER_TYPES guard"); const names = [...table[1].matchAll(/"([A-Z0-9_]+)"/g)].map((match) => match[1]); assert.equal(names.length, 87, "Blender 5.2 modifier identity table must cover codes 0..86"); assert.equal(new Set(names).size, 87, "modifier identity names must be unique"); const webRegistry = registry.match(/#ifdef WITH_WEB([\s\S]*?)#else/); assert.ok(webRegistry, "WITH_WEB modifier registry is missing"); const enabledNames = new Set([...webRegistry[1].matchAll(/INIT_TYPE\(([A-Za-z0-9_]+)\)/g)].map((match) => match[1].toUpperCase())); const aliases = new Map([["NONE", "NONE"], ["SUBSURF", "SUBSURF"], ["SHAPE_KEY", "SHAPEKEY"], ["EDGE_SPLIT", "EDGESPLIT"], ["MESH_DEFORM", "MESHDEFORM"], ["SIMPLE_DEFORM", "SIMPLEDEFORM"], ["SURFACE_DEFORM", "SURFACEDEFORM"]]); const matrix = names.map((name, typeCode) => { const registryName = aliases.get(name) ?? name.replaceAll("_", ""); return { typeCode, name, evaluation: enabledNames.has(registryName) ? "NATIVE_WHITELIST" : "STRUCTURED_BLOCK" }; }); assert.ok(matrix.every((entry, index) => entry.typeCode === index)); assert.ok(matrix.filter((entry) => entry.evaluation === "NATIVE_WHITELIST").length >= 27); assert.ok(matrix.filter((entry) => entry.evaluation === "STRUCTURED_BLOCK").length > 0); assert.match(registry, /types\[type\] = &modifierType_None/, "non-whitelisted types must retain identity through the disabled sentinel"); assert.match(reader, /"UNKNOWN_" \+ std::to_string\(type\)/, "out-of-range types must remain explicit"); process.stdout.write(`modifier-capability-matrix-ok types=${matrix.length} native=${matrix.filter((entry) => entry.evaluation === "NATIVE_WHITELIST").length} blocked=${matrix.filter((entry) => entry.evaluation === "STRUCTURED_BLOCK").length}\n`);