//Priority: 100
/**
  
  █▀▄▀█ █▀█ █▄░█ █░█ █▀▄▀█ █▀▀ █▄░█ ▀█▀ ▄▀█ █░░   █▀▀ ▀▄▀ █▀█ █▀▀ █▀█ █ █▀▀ █▄░█ █▀▀ █▀▀
  █░▀░█ █▄█ █░▀█ █▄█ █░▀░█ ██▄ █░▀█ ░█░ █▀█ █▄▄   ██▄ █░█ █▀▀ ██▄ █▀▄ █ ██▄ █░▀█ █▄▄ ██▄

  ☻/  * @file Global scripts
  /▌  * @copyright KnightDexx's Modded Minecraft World & ModernGamingWorld
  /▌  * Modified by @Cyn-SolveroftheAbsoluteGremlins on Discord
  /\

//Priority: 100
/**
 * Full AU + AllTheOres Master Unifier (with Dusts, Gears, Ingots, Nuggets, Plates, Rods, Raw Materials, Storage Blocks, and Wires)
 */

/* #region Helper functions */
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {string} outP - Item output
 */
function boilRec(e, outP, ingO) {
    /*let recTypes = [
        'bloodmagic:arc',
        'tconstruct:melting'
    ]*/
    let boil = []
    if (Item.exists(`alltheores:${outP}_crystal`)) {
        boil.push(
            { output: `alltheores:${outP}_crystal`, type1: 'mekanism:crystallizing' },
            { output: `alltheores:${outP}_shard`, type1: 'mekanism:injecting', type2: 'create:filling', type3: 'immersiveengineering:bottling_machine' },
            { output: `alltheores:${outP}_clump`, type1: 'mekanism:purifying' },
            { output: `alltheores:dirty_${outP}_dust`, type1: 'mekanism:crushing', type2: 'create:crushing' }
        )
    }
    if (Item.exists(`allthemodium:${outP}_crystal`)) {
        boil.push(
            { output: `allthemodium:${outP}_crystal`, type1: 'mekanism:crystallizing' },
            { output: `allthemodium:${outP}_shard`, type1: 'mekanism:injecting', type2: 'create:filling', type3: 'immersiveengineering:bottling_machine' },
            { output: `allthemodium:${outP}_clump`, type1: 'mekanism:purifying' },
            { output: `allthemodium:dirty_${outP}_dust`, type1: 'mekanism:crushing', type2: 'create:crushing' }
        )
    }
    if (Item.exists(`create:crushed_raw_${outP}`)) {
        boil.push({ output: `create:crushed_raw_${outP}`, type1: 'create:crushing' })
    }
    if (Item.exists(`mekanism:crystal_${outP}`)) {
        boil.push(
            { output: `mekanism:crystal_${outP}`, type1: 'mekanism:crystallizing' },
            { output: `mekanism:shard_${outP}`, type1: 'mekanism:injecting', type2: 'create:filling', type3: 'immersiveengineering:bottling_machine' },
            { output: `mekanism:clump_${outP}`, type1: 'mekanism:purifying' },
            { output: `mekanism:dirty_dust_${outP}`, type1: 'mekanism:crushing', type2: 'create:crushing' }
        )
    }
    if (Item.exists(`moremekanismprocessing:crystal_${outP}`)) {
        boil.push(
            { output: `moremekanismprocessing:crystal_${outP}`, type1: 'mekanism:crystallizing' },
            { output: `moremekanismprocessing:shard_${outP}`, type1: 'mekanism:injecting', type2: 'create:filling', type3: 'immersiveengineering:bottling_machine' },
            { output: `moremekanismprocessing:clump_${outP}`, type1: 'mekanism:purifying' },
            { output: `moremekanismprocessing:dirty_dust_${outP}`, type1: 'mekanism:crushing', type2: 'create:crushing' }
        )
    }
    if (Item.exists(`moremekanismprocessing:dust_${outP}`)) {
        boil.push({ output: `moremekanismprocessing:dust_${outP}`, type1: 'mekanism:enriching', type2: 'create:splashing', type3: 'botania:mana_infusion', type4: 'mekanism:crushing', type5: 'immersiveengineering:crusher', type6: 'occultism:crushing', type7: 'immersiveengineering:hammer_crushing' })
    }
    if (Item.exists(`thermal:dust_${outP}`)) {
        boil.push({ output: `thermal:${outP}_dust`, type1: 'mekanism:enriching', type2: 'create:splashing', type3: 'botania:mana_infusion', type4: 'mekanism:crushing', type5: 'immersiveengineering:crusher', type6: 'occultism:crushing', type7: 'immersiveengineering:hammer_crushing' })
    }
    if (Item.exists(`alltheores:${outP}_dust`)) {
        boil.push({ output: `alltheores:${outP}_dust`, type1: 'mekanism:enriching', type2: 'create:splashing', type3: 'botania:mana_infusion', type4: 'mekanism:crushing', type5: 'immersiveengineering:crusher', type6: 'occultism:crushing', type7: 'immersiveengineering:hammer_crushing' })
    }
    if (Item.exists(`moremekanismprocessing:gem_${outP}`)) {
        boil.push({ output: `moremekanismprocessing:gem_${outP}`, type1: 'mekanism:enriching' })
    }
    boil.forEach(rec => {
        e.forEachRecipe({ type: rec.type1, output: rec.output, not: { mod: 'kubejs' } }, recipe => {
            e.remove({ id: recipe.getId() })
        })
        if (rec.type2 != undefined) {
            e.forEachRecipe({ type: rec.type2, output: rec.output, not: { mod: 'kubejs' } }, recipe => {
                e.remove({ id: recipe.getId() })
            })
        }
        if (rec.type3 != undefined) {
            e.forEachRecipe({ type: rec.type3, output: rec.output, not: { mod: 'kubejs' } }, recipe => {
                e.remove({ id: recipe.getId() })
            })
        }
        if (rec.type4 != undefined) {
            e.forEachRecipe({ type: rec.type4, output: rec.output, not: { mod: 'kubejs' } }, recipe => {
                e.remove({ id: recipe.getId() })
            })
        }
        if (rec.type5 != undefined) {
            e.forEachRecipe({ type: rec.type5, output: rec.output, not: { mod: 'kubejs' } }, recipe => {
                e.remove({ id: recipe.getId() })
            })
        }
        if (rec.type6 != undefined) {
            e.forEachRecipe({ type: rec.type6, output: rec.output, not: { mod: 'kubejs' } }, recipe => {
                e.remove({ id: recipe.getId() })
            })
        }
        if (rec.type7 != undefined) {
            e.forEachRecipe({ type: rec.type7, output: rec.output, not: { mod: 'kubejs' } }, recipe => {
                e.remove({ id: recipe.getId() })
            })
        }
    })
    e.forEachRecipe({ type: 'minecraft:smelting', output: ingO, not: { mod: 'kubejs' } }, recipe => {
        e.remove({ id: recipe.getId() })
    })
    e.forEachRecipe({ type: 'minecraft:blasting', output: ingO, not: { mod: 'kubejs' } }, recipe => {
        e.remove({ id: recipe.getId() })
    })
    e.forEachRecipe({ type: 'forbidden_arcanus:clibano_combustion', output: ingO, not: { mod: 'kubejs' } }, recipe => {
        e.remove({ id: recipe.getId() })
    })
    e.forEachRecipe({ type: 'immersiveengineering:arc_furnace', output: ingO, not: { mod: 'kubejs' } }, recipe => {
        e.remove({ id: recipe.getId() })
    })
    removeRecipeByID(e, [
        `bloodmagic:arc/dustsfrom_raw_${outP}`,
        `bloodmagic:arc/dustsfrom_gravel_${outP}`,
        `bloodmagic:arc/dustsfrom_ore_${outP}`,
        `bloodmagic:arc/dustsfrom_ingot_${outP}`,
        `alltheores:mek_processing/${outP}/slurry/dirty_from_raw`,
        `alltheores:mek_processing/${outP}/slurry/from_raw_ore`,
        `alltheores:mek_processing/${outP}/slurry/dirty/from_raw_block`,
        `alltheores:mek_processing/${outP}/slurry/dirty`,
        `moremekanismprocessing:processing/${outP}/slurry/dirty/ore`,
        `moremekanismprocessing:processing/${outP}/slurry/dirty/raw_ore`,
        `moremekanismprocessing:processing/${outP}/slurry/dirty/raw_storage_blocks`,
        `allthemodium:mek_processing/${outP}/slurry/dirty/from_raw_block`,
        `allthemodium:mek_processing/${outP}/slurry/dirty`,
        `allthemodium:mek_processing/${outP}/slurry/from_raw_ore`,
        `mekanism:processing/${outP}/slurry/dirty/from_raw_ore`,
        `mekanism:processing/${outP}/slurry/dirty/from_raw_block`,
        `mekanism:processing/${outP}/slurry/dirty/from_ore`,
        `alltheores:mek_processing/${outP}/slurry/clean`,
        `moremekanismprocessing:processing/${outP}/slurry/clean`,
        `allthemodium:mek_processing/${outP}/slurry/clean`,
        `mekanism:processing/${outP}/slurry/clean`,
        `mekanism:processing/${outP}/slurry/dirty/from_ore`,
    ])
}
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {string} inP  - Tag input
 * @param {int} chemAmount - Chemical amount, optional, defaults to 1
 * @param {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 1
 */
function mekPur(e, inP, chemAmount, outP, outputAmount) {
    if (chemAmount == undefined) {
        chemAmount = 1
    }
    if (outputAmount == undefined) {
        outputAmount = 1
    }

    e.custom({
        "type": "mekanism:purifying",
        "item_input": { "tag": inP },
        "chemical_input": { "amount": chemAmount, "chemical": "mekanism:oxygen" },
        "output": { "id": outP, "count": outputAmount },
        "per_tick_usage": false
    }).id('kubejs:mekanism/purifying/' + outP.split("_")[0].split(':')[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
}
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {string} inP - Tag input
 * @param {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 1
*/
function mekEnrich(e, inP, outP, outputAmount) {
    if (outputAmount == undefined) {
        outputAmount = 1
    }

    e.custom({
        "type": "mekanism:enriching",
        "input": { "tag": inP },
        "output": { "id": outP, "count": outputAmount }
    }).id('kubejs:mekanism/enriching/' + outP.split("_")[0].split(':')[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
}
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {int} chemAmount - Chemical amount, optional, defaults to 1
 * @param {string} inP - Tag input
 * @param {int} inputAmount - Input amount, optional, defaults to 1
 * @param {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 1
 */
function mekInjecting(e, chemAmount, inP, inputAmount, outP, outputAmount) {
    if (chemAmount == undefined) {
        chemAmount = 1
    }
    if (inputAmount == undefined) {
        inputAmount = 1
    }
    if (outputAmount == undefined) {
        outputAmount = 1
    }

    e.custom({
        "type": "mekanism:injecting",
        "item_input": { "tag": inP },
        "chemical_input": { "amount": chemAmount, "chemical": "mekanism:hydrogen_chloride" },
        "output": { "id": outP, "count": outputAmount },
        "per_tick_usage": false
    }).id('kubejs:mekanism/injecting/' + outP.split("_")[0].split(':')[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
}
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {int} chemAmount - Chemical amount, optional, defaults to 1
 * @param {string} inP - Tag input
 * @param {int} inputAmount - Input amount, optional, defaults to 1
 * @param {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 1000
 * @param {string} chemType - Output type. Defaults to slurry for ore processing
 */
function mekDissolution(e, chemAmount, inP, inputAmount, outP, outputAmount) {
    if (chemAmount == undefined) {
        chemAmount = 1
    }
    if (inputAmount == undefined) {
        inputAmount = 1
    }
    if (outputAmount == undefined) {
        outputAmount = 1000
    }
    e.custom({
        "type": "mekanism:dissolution",
        "item_input": { "tag": inP },
        "chemical_input": { "amount": chemAmount, "chemical": "mekanism:sulfuric_acid" },
        "output": { "id": outP, "amount": outputAmount },
        "per_tick_usage": false
    }).id('kubejs:mekanism/dissolutioning/' + outP.split("_")[0].split(':')[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
}
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {int} chemAmount - Chemical amount, optional, defaults to 300
 * @param {string} inP - Tag input
 * @param {int} inputAmount - Input amount, optional, defaults to 1
 * @param {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 1
 */
function creFill(e, chemAmount, inP, inputAmount, outP, outputAmount) {
    if (chemAmount == undefined) {
        chemAmount = 300
    }
    if (inputAmount == undefined) {
        inputAmount = 1
    }
    if (outputAmount == undefined) {
        outputAmount = 1
    }

    e.custom({
        "type": "create:filling",
        "ingredients": [
            {
                "tag": inP,
                "count": inputAmount
            },
            {
                "type": "neoforge:tag",
                "tag": "c:hydrogen_chloride",
                "amount": chemAmount
            }
        ],
        "results": [
            {
                "id": outP,
                "count": outputAmount
            }
        ]
    }).id('kubejs:create/filling/' + outP.split("_")[0].split(':')[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
}
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {string} inP - Tag input
 * @param {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 1
 * @param {int} extraChance - Chance of experience nugget, optional, defaults to 0.75 (75%)
 */
function creCrush(e, inP, outP, outputAmount, extraChance) {
    if (outputAmount == undefined) {
        outputAmount = 1
    }
    if (extraChance == undefined) {
        extraChance = 0.75
    }
    if (outP.includes("create:crushed_raw_")) {
        if (extraChance == 0) {
            e.custom({
                "type": "create:crushing",
                "ingredients": [
                    {
                        "tag": inP
                    }
                ],
                "processingTime": 400,
                "results": [
                    {
                        "count": outputAmount,
                        "id": outP
                    }
                ]
            }).id('kubejs:create/crushing/' + outP.split('raw_')[1] + '/crushed_raw/from_' + inP.split('/')[0].split(":")[1])
        } else {
            e.custom({
                "type": "create:crushing",
                "ingredients": [
                    {
                        "tag": inP
                    }
                ],
                "processingTime": 400,
                "results": [
                    {
                        "count": outputAmount,
                        "id": outP
                    },
                    {
                        "chance": extraChance,
                        "count": outputAmount,
                        "id": "create:experience_nugget"
                    }
                ]
            }).id('kubejs:create/crushing/' + outP.split('raw_')[1] + '/crushed_raw/from_' + inP.split('/')[0].split(":")[1])
        }
    } else {
        if (extraChance == 0) {
            e.custom({
                "type": "create:crushing",
                "ingredients": [
                    {
                        "tag": inP
                    }
                ],
                "processingTime": 400,
                "results": [
                    {
                        "count": outputAmount,
                        "id": outP
                    }
                ]
            }).id('kubejs:create/crushing/' + inP.split(":")[1].split('/')[1] + '/' + outP.split(":")[1].split("t_")[0] + 't/from_' + inP.split('/')[0].split(":")[1])
        } else {
            e.custom({
                "type": "create:crushing",
                "ingredients": [
                    {
                        "tag": inP
                    }
                ],
                "processingTime": 400,
                "results": [
                    {
                        "count": outputAmount,
                        "id": outP
                    },
                    {
                        "chance": extraChance,
                        "count": outputAmount,
                        "id": "create:experience_nugget"
                    }
                ]
            }).id('kubejs:create/crushing/' + inP.split(":")[1].split('/')[1] + '/' + outP.split(":")[1].split("t_")[0] + 't/from_' + inP.split('/')[0].split(":")[1])
        }
    }
}
/**
 * @param {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param {string} inP - Tag input
 * @param {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 2
 */
function occultCrush(e, inP, outP, outputAmount) {
    if (outputAmount == undefined) {
        outputAmount = 2
    }
    e.custom({
        "type": "occultism:crushing",
        "crushing_time": 200,
        "ignore_crushing_multiplier": false,
        "ingredient": {
            "tag": inP
        },
        "result": {
            "type": "occultism:tag",
            "tag": "c:dusts/" + outP.split(':')[1].split('_')[0],
            "count": outputAmount
        }
    }).id('kubejs:occultism/crushing/' + outP.split("_")[0].split(':')[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
}
/**
 * @param  {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param  {int} energy - Energy used in the recipe, optional, defaults to 6000
 * @param  {string} inP - Tag input
 * @param  {boolean} chance - True enables it, optional, defaults to false/disabled
 * @param  {string} outP - Item output
 * @param {int} outputAmount - Output amount, optional, defaults to 1
 */
function immersiveCrush(e, energy, inP, chance, outP, outputAmount) {
    if (energy == undefined) {
        energy = 6000
    }
    if (chance == true) {
        chance = 0.33333334
    }
    if (chance == undefined) {
        chance = 0
    }
    if (outputAmount == undefined) {
        outputAmount = 1
    }
    e.custom({
        "type": "immersiveengineering:crusher",
        "energy": energy,
        "input": {
            "tag": inP
        },
        "result": {
            "item": outP,
            "count": outputAmount
        },
        "secondaries": [
            {
                "chance": chance,
                "output": {
                    "item": outP
                }
            }
        ]
    }).id('kubejs:immersive_engineering/crushing/' + outP.split(':')[1].split("_")[0] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
}
/**
 * @param  {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param  {int} energy - Energy used in the recipe, optional, defaults to 6000
 * @param  {string} inP - Filter for the recipe
 * @param  {string} mat - Actual input
 */
function immersiveArc(e, inP, mat, outP) {
    if (inP.includes("c:raw_materials/")) {
        e.custom({
            "type": "immersiveengineering:arc_furnace",
            "additives": [],
            "energy": 25600,
            "input": {
                "tag": `c:raw_materials/${mat}`
            },
            "results": [
                {
                    "tag": `c:ingots/${mat}`
                }
            ],
            "secondaries": [
                {
                    "chance": 0.5,
                    "output": {
                        "id": outP
                    }
                }
            ],
            "time": 100
        }).id(`kubejs:immersive_engineering/arc_furnace/${mat}/` + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
    }
    if (inP.includes("c:storage_blocks/raw_")) {
        e.custom({
            "type": "immersiveengineering:arc_furnace",
            "additives": [],
            "energy": 230400,
            "input": {
                "tag": `c:storage_blocks/raw_${mat}`
            },
            "results": [
                {
                    "id": outP,
                    "count": 13
                }
            ],
            "secondaries": [
                {
                    "chance": 0.5,
                    "output": {
                        "id": outP
                    }
                }
            ],
            "time": 900
        }).id(`kubejs:immersive_engineering/arc_furnace/${mat}/` + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
    }
    if (inP.includes("c:ores/")) {
        e.custom({
            "type": "immersiveengineering:arc_furnace",
            "additives": [],
            "energy": 102400,
            "input": {
                "tag": `c:ores/${mat}`
            },
            "results": [
                {
                    "id": outP,
                    "count": 2
                }
            ],
            "slag": {
                "tag": "c:slag"
            },
            "time": 200
        }).id(`kubejs:immersive_engineering/arc_furnace/${mat}/` + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
    }
    if (inP.includes("c:dusts/")) {
        e.custom({
            "type": "immersiveengineering:arc_furnace",
            "additives": [],
            "energy": 51200,
            "input": {
                "tag": `c:dusts/${mat}`
            },
            "results": [
                {
                    "id": outP
                }
            ],
            "time": 100
        }).id(`kubejs:immersive_engineering/arc_furnace/${mat}/` + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
    }
}
/**
 * @param  {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param  {string} inP - Tag input
 * @param  {string} outP - Item output
 */
function forbiddenCombustion(e, inP, outP) {
    if (!Platform.isLoaded('forbidden_arcanus')) return
    if (inP.includes("dust")) {
        e.custom({
            "type": "forbidden_arcanus:clibano_combustion",
            "cooking_time": 100,
            "experience": 0.35,
            "ingredients": [{
                "tag": inP
            }],
            "result": { "id": outP }
        }).id('kubejs:forbidden_arcanus/clibano_combustion/' + inP.split("/")[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
    } else if (inP.includes("create:crushed_raw_")) {
        e.custom({
            "type": "forbidden_arcanus:clibano_combustion",
            "cooking_time": 100,
            "experience": 0.35,
            "ingredients": [{
                "item": inP
            }],
            "result": { "id": outP }
        }).id('kubejs:forbidden_arcanus/clibano_combustion/' + inP.split("/")[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
    } else {
        // Note: residue and combine_residues recipe formats changed/removed in 1.21.1
        // Using simple clibano_combustion without residue byproduct
        e.custom({
            "type": "forbidden_arcanus:clibano_combustion",
            "cooking_time": 100,
            "experience": 0.35,
            "ingredients": [{
                "tag": inP
            }],
            "result": { "id": outP }
        }).id('kubejs:forbidden_arcanus/clibano_combustion/' + inP.split("/")[1] + '/' + outP.split(':')[1].split('_')[1] + '/from_' + inP.split('/')[0].split(":")[1])
    }
}
/**
 * @param  {string} e - Whatever is being used as event in "ServerEvents.recipes(event => {"
 * @param  {string} inP - Tag input
 * @param  {string} outP - Item output
 * @param  {string} outputAmount - Output amount, optional, defaults to 1
 * @param  {string} fluid - Tag input for which modifier is used, defaults to "bloodmagic:arc/cuttingfluid"
 * @param  {boolean} extra - Check for if there's a secondary output
 */
function bloodmagicArc(e, inP, outP, outputAmount, fluid, extra) {
    if (fluid == undefined) {
        fluid = "bloodmagic:arc/cuttingfluid"
    }
    if (outputAmount == undefined) {
        outputAmount = 1
    }
    if (extra == undefined) {
        e.custom({
            "type": "bloodmagic:arc",
            "consumeingredient": false,
            "input": {
                "tag": inP
            },
            "inputsize": 1,
            "mainoutputchance": 0.0,
            "output": {
                "count": outputAmount,
                "item": outP
            },
            "tool": {
                "tag": fluid
            }
        }).id('kubejs:bloodmagic/arc/' + inP.split("/")[1] + '/dust/from_' + inP.split('/')[0].split(":")[1])
    } else if (extra == true && inP.includes('bloodmagic:gravels/')) {
        e.custom({
            "type": "bloodmagic:arc",
            "addedoutput": [
                {
                    "type": {
                        "item": outP
                    },
                    "chance": 0.25,
                    "mainchance": 0.0
                }
            ],
            "consumeingredient": false,
            "input": {
                "tag": inP
            },
            "inputsize": 1,
            "mainoutputchance": 0.0,
            "output": {
                "count": 2,
                "item": outP
            },
            "tool": {
                "tag": fluid
            }
        }).id('kubejs:bloodmagic/arc/gravel/' + outP.split(':')[1].split("_")[0] + '/from_' + outP.split("_")[0].split(":")[1])
    } else {
        e.custom({
            "type": "bloodmagic:arc",
            "addedoutput": [
                {
                    "type": {
                        "item": outP
                    },
                    "chance": 0.17,
                    "mainchance": 0.33
                }
            ],
            "consumeingredient": false,
            "input": {
                "tag": inP
            },
            "inputsize": 1,
            "mainoutputchance": 0.0,
            "output": {
                "item": outP
            },
            "tool": {
                "tag": fluid
            }
        }).id('kubejs:bloodmagic/arc/' + inP.split("/")[1] + '/dust/from_' + inP.split('/')[0].split(":")[1])
    }
}
/* #endregion */

ServerEvents.recipes(event => {

    // ── INITIALIZATION (ported from global.js — all in one place for 1.21.1) ─
    const auTags = {
        dusts: [], gears: [], ingots: [], nuggets: [], plates: [],
        raw_materials: [], rods: [], storage_blocks: [], wires: []
    }

    const loaded = {
        ATO_Loaded: Platform.isLoaded('alltheores'),
        Allthemodium_Loaded: Platform.isLoaded('allthemodium'),
        AdAstra_Loaded: Platform.isLoaded('ad_astra'),
        Ae2_Loaded: Platform.isLoaded('ae2'),
        BigReactors_Loaded: Platform.isLoaded('bigreactors'),
        Botania_Loaded: Platform.isLoaded('botania'),
        Blue_Skies_Loaded: Platform.isLoaded('blue_skies'),
        Create_Loaded: Platform.isLoaded('create'),
        CreateAdd_Loaded: Platform.isLoaded('createaddition'),
        Eidolon_Loaded: Platform.isLoaded('eidolon'),
        Forestry_Loaded: Platform.isLoaded('forestry'),
        IE_Loaded: Platform.isLoaded('immersiveengineering'),
        IF_Loaded: Platform.isLoaded('industrialforegoing'),
        Mek_Loaded: Platform.isLoaded('mekanism'),
        Occult_Loaded: Platform.isLoaded('occultism'),
        Pneumaticcraft_Loaded: Platform.isLoaded('pneumaticcraft'),
        Thermal_Loaded: Platform.isLoaded('thermal'),
        CCR_Loaded: Platform.isLoaded('createchromaticreturn'),
        Tinkers_Loaded: Platform.isLoaded('tconstruct'),
        Undergarden_Loaded: Platform.isLoaded('undergarden'),
        BM_Loaded: Platform.isLoaded('bloodmagic'),
        FA_Loaded: Platform.isLoaded('forbidden_arcanus')
    }

    const itemFromTag = function (type, material) {
        // AlmostUnified.getPreferredItemForTag API changed in 1.21.1.
        // Use Ingredient resolution — AU unifies outputs automatically anyway.
        const ing = Ingredient.of(`#c:${type}/${material}`)
        if (ing && !ing.isEmpty()) return ing.getFirst()
        return null
    }

    // Populate auTags from AlmostUnified tag list
    try {
        AlmostUnified.getTags().forEach(tag => {
            const tagString = tag.toString()
            const match = /c:(dusts|gears|ingots|nuggets|plates|raw_materials|rods|storage_blocks|wires)\/(.+?)$/.exec(tagString)
            if (match && !auTags[match[1]].includes(match[2])) {
                auTags[match[1]].push(match[2])
            }
        })
    } catch (e) { console.warn('[AU] getTags unavailable: ' + e) }
    // ── END INITIALIZATION ────────────────────────────────────────────────

    // Helper: convert ItemStack to recipe result JSON for 1.21.1
    // item.toJson() produces {"id":"...","count":N} but most recipes need {"item":"...","count":N}
    const itemJson = (item) => ({ item: item.id, count: item.count ?? 1 })
    // Helper: convert Ingredient to ingredient JSON for 1.21.1
    const ingJson = (ing) => {
        if (!ing || ing.isEmpty()) return null
        const ids = ing.itemIds
        if (ing.toString().startsWith('#') || ing.toString().includes('tag')) {
            // It's a tag ingredient - extract the tag name
            const str = ing.toString()
            const tag = str.replace(/^#/, '')
            return { tag: tag }
        }
        return ids.length > 0 ? { item: ids[0].toString() } : null
    }


    /* ============================
       COUNTERS
    ============================ */

    const recipeCounts = {
        dusts: 0,
        gears: 0,
        ingots: 0,
        nuggets: 0,
        plates: 0,
        rods: 0,
        raw_materials: 0,
        storage_blocks: 0,
        wires: 0
    }

    /* ============================
       SAFETY HELPERS
    ============================ */

    const validItem = (type, material) => {
        const item = itemFromTag(type, material)
        return item && !item.isEmpty()
    }

    const filterExisting = (tags, type) =>
        tags.filter(material => validItem(type, material))

    const recipeExists = (outputItem) => {
        if (!outputItem || outputItem.isEmpty()) return false
        let exists = false

        event.recipeStream({}).forEach(r => {
            const res = r.json?.result
            if (!res) return

            if (Array.isArray(res)) {
                res.forEach(e => {
                    if (!e) return
                    const item = Item.of(e)
                    if (item && !item.isEmpty() && outputItem.equalsIgnoringCount(item)) {
                        exists = true
                    }
                })
            } else {
                const item = Item.of(res)
                if (item && !item.isEmpty() && outputItem.equalsIgnoringCount(item)) {
                    exists = true
                }
            }
        })

        return exists
    }

    /* ============================
       DUSTS (Occultism)
    ============================ */

    /*if (loaded.Occult_Loaded) {
        filterExisting(auTags.dusts, 'dusts').forEach(material => {
            const dust = itemFromTag('dusts', material)
            if (!dust || dust.isEmpty()) return

            const ingotTag = Ingredient.of(`#c:ingots/${material}`)
            const oreTag = Ingredient.of(`#c:ores/${material}`)
            const rawTag = Ingredient.of(`#c:raw_materials/${material}`)

            let crush = { ingot: false, ore: false, raw: false }

            event.forEachRecipe({ type: "occultism:crushing" }, r => {
                if (!r.json?.result) return
                // Result is either {type:"occultism:tag", tag:"c:dusts/x"} or {item:"x", count:N}
                const res = r.json.result
                const resultMatchesDust = (
                    (res.tag && res.tag === `c:dusts/${material}`) ||
                    (res.item && res.item === dust.id)
                )
                if (!resultMatchesDust) return
                const input = Ingredient.of(r.json.ingredient)
                if (ingotTag.test(input)) crush.ingot = true
                if (oreTag.test(input)) crush.ore = true
                if (rawTag.test(input)) crush.raw = true
            })

            if (!ingotTag.isEmpty() && !crush.ingot) {
                event.custom({
                    type: "occultism:crushing",
                    ingredient: { tag: `c:ingots/${material}` },
                    result: { type: "occultism:tag", tag: `c:dusts/${material}`, count: 1 },
                    crushing_time: 200,
                    ignore_crushing_multiplier: true
                })
                recipeCounts.dusts++
            }

            if (!rawTag.isEmpty() && !crush.raw) {
                event.custom({
                    type: "occultism:crushing",
                    ingredient: { tag: `c:raw_materials/${material}` },
                    result: { type: "occultism:tag", tag: `c:dusts/${material}`, count: 2 },
                    crushing_time: 200
                })
                recipeCounts.dusts++
            }

            if (!oreTag.isEmpty() && !crush.ore) {
                event.custom({
                    type: "occultism:crushing",
                    ingredient: { tag: `c:ores/${material}` },
                    result: { type: "occultism:tag", tag: `c:dusts/${material}`, count: 2 },
                    crushing_time: 300
                })
                recipeCounts.dusts++
            }
        })
    }*/

    /* ============================
       GEARS
    ============================ */

    if (loaded.IE_Loaded || loaded.Thermal_Loaded) {
        filterExisting(auTags.gears, 'gears').forEach(material => {
            if (material == 'diamond') return
            const gear = itemFromTag('gears', material)
            if (!gear || gear.isEmpty()) return

            const ingotTag = Ingredient.of(`#c:ingots/${material}`)
            if (ingotTag.isEmpty()) return

            if (loaded.IE_Loaded && !recipeExists(gear)) {
                event.custom({
                    type: "immersiveengineering:metal_press",
                    mold: "immersiveengineering:mold_gear",
                    input: { basePredicate: { tag: `c:ingots/${material}` }, count: 4 },
                    result: { tag: `c:gears/${material}` },
                    energy: 2400
                })
                recipeCounts.gears++
            }

            if (loaded.Thermal_Loaded && !recipeExists(gear)) {
                event.custom({
                    type: "thermal:press",
                    ingredients: [
                        { tag: `c:ingots/${material}`, count: 4 },
                        { item: "thermal:press_gear_die" }
                    ],
                    result: [{ item: gear.id, count: 1 }]
                })
                recipeCounts.gears++
            }
        })
    }

    /* ============================
       WIRES
    ============================ */

    filterExisting(auTags.wires, 'wires').forEach(material => {
        const wire = itemFromTag('wires', material)
        if (!wire || wire.isEmpty() || recipeExists(wire)) return

        if (loaded.CreateAdd_Loaded) {
            const plate = itemFromTag('plates', material)
            if (plate && !plate.isEmpty()) {
                event.custom({
                    type: 'createaddition:rolling',
                    ingredients: [{ tag: `c:plates/${material}` }],
                    results: [{ id: wire.id, count: 2 }]
                })
            }
        }

        if (loaded.IE_Loaded) {
            const ingot = itemFromTag('ingots', material)
            if (ingot && !ingot.isEmpty()) {
                event.custom({
                    type: 'immersiveengineering:metal_press',
                    mold: 'immersiveengineering:mold_wire',
                    input: { basePredicate: { tag: `c:ingots/${material}` }, count: 1 },
                    result: { tag: `c:wires/${material}` },
                    energy: 2400
                })
            }
        }
    })

    /* ============================
       MISC CLEANUP / FIXES
    ============================ */
    event.remove({ input: '#c:ores', type: 'cyclic:crusher' })
    let ore = [
        { mat: 'copper', modAdd: 'mekanism', orE: 'minecraft' },
        { mat: 'gold', modAdd: 'mekanism', orE: 'minecraft' },
        { mat: 'iron', modAdd: 'mekanism', orE: 'minecraft' },
        { mat: 'osmium', modAdd: 'mekanism', orE: 'alltheores' },
        { mat: 'tin', modAdd: 'mekanism', orE: 'alltheores' },
        { mat: 'uranium', modAdd: 'mekanism', orE: 'alltheores' },
        { mat: 'allthemodium', modAdd: 'allthemodium', orE: 'allthemodium' },
        { mat: 'unobtainium', modAdd: 'allthemodium', orE: 'allthemodium' },
        { mat: 'vibranium', modAdd: 'allthemodium', orE: 'allthemodium' },
        { mat: 'lead', modAdd: 'alltheores', orE: 'alltheores' },
        { mat: 'aluminum', modAdd: 'alltheores', orE: 'alltheores' },
        { mat: 'iridium', modAdd: 'alltheores', orE: 'alltheores' },
        { mat: 'silver', modAdd: 'alltheores', orE: 'alltheores' },
        { mat: 'platinum', modAdd: 'moremekanismprocessing', orE: 'alltheores' },
        { mat: 'zinc', modAdd: 'moremekanismprocessing', orE: 'alltheores' },
        { mat: 'nickel', modAdd: 'moremekanismprocessing', orE: 'alltheores' },
        { mat: 'desh', modAdd: 'moremekanismprocessing', orE: 'ad_astra' },
        { mat: 'ostrum', modAdd: 'moremekanismprocessing', orE: 'ad_astra' },
        { mat: 'calorite', modAdd: 'moremekanismprocessing', orE: 'ad_astra' },
        { mat: 'cobalt', modAdd: 'moremekanismprocessing', orE: 'tconstruct' },
        { mat: 'sapphire', modAdd: 'moremekanismprocessing', orE: 'alltheores', type: 'gem' },
        { mat: 'ruby', modAdd: 'moremekanismprocessing', orE: 'alltheores', type: 'gem' },
        { mat: 'peridot', modAdd: 'moremekanismprocessing', orE: 'alltheores', type: 'gem' },
        { mat: 'sulfur', modAdd: 'moremekanismprocessing', orE: 'thermal', type: 'gem' },
        { mat: 'apatite', modAdd: 'moremekanismprocessing', orE: 'thermal', type: 'gem' },
        { mat: 'cinnabar', modAdd: 'moremekanismprocessing', orE: 'thermal', type: 'gem' },
        { mat: 'niter', modAdd: 'moremekanismprocessing', orE: 'thermal', type: 'gem' },
    ]
    ore.forEach(o => {
        // Skip entire entry if the source mod isn't loaded
        if (o.orE == 'ad_astra' && !loaded.AdAstra_Loaded) return
        if (o.orE == 'tconstruct' && !loaded.Tinkers_Loaded) return
        if (o.orE == 'thermal' && !loaded.Thermal_Loaded) return

        let cleanSlurry = `${o.modAdd}:clean_${o.mat}`
        let dirtySlurry = `${o.modAdd}:dirty_${o.mat}`
        let crystal = 'N/A'
        let shard = 'N/A'
        let clump = 'N/A'
        let dirtyDust = 'N/A'
        let dust = 'N/A'
        let out = 'N/A'
        let erroR = [{ errored: false, reason: 'N/A' }]

        if (o.modAdd != 'mekanism' && o.modAdd != 'moremekanismprocessing' && o.modAdd != 'allthemodium') {
            if (o.mat == 'lead') {
                cleanSlurry = `mekanism:clean_${o.mat}`
            } else {
                cleanSlurry = `alltheores:clean_${o.mat}`
            }
        }
        if (o.modAdd != 'mekanism' && o.modAdd != 'moremekanismprocessing' && o.modAdd != 'allthemodium') {
            if (o.mat == 'lead') {
                dirtySlurry = `mekanism:dirty_${o.mat}`
            } else {
                dirtySlurry = `alltheores:dirty_${o.mat}`
            }
        }

        if (o.modAdd == 'moremekanismprocessing' || o.modAdd == 'mekanism') {
            crystal = `${o.modAdd}:crystal_${o.mat}`
            shard = `${o.modAdd}:shard_${o.mat}`
            clump = `${o.modAdd}:clump_${o.mat}`
            dirtyDust = `${o.modAdd}:dirty_dust_${o.mat}`
        } else {
            crystal = `${o.modAdd}:${o.mat}_crystal`
            shard = `${o.modAdd}:${o.mat}_shard`
            clump = `${o.modAdd}:${o.mat}_clump`
            dirtyDust = `${o.modAdd}:dirty_${o.mat}_dust`
        }

        if (o.orE == 'ad_astra' || o.orE == 'tconstruct') {
            dust = `moremekanismprocessing:dust_${o.mat}`
        } else if (o.orE == 'thermal') {
            dust = `thermal:${o.mat}_dust`
        } else if (o.orE == 'minecraft') {
            dust = `alltheores:${o.mat}_dust`
        } else {
            dust = `${o.orE}:${o.mat}_dust`
        }

        if (o.type == 'gem') {
            out = `${o.orE}:${o.mat}`
        } else {
            out = `${o.orE}:${o.mat}_ingot`
        }

        if (!erroR.errored) {
            if (loaded.BM_Loaded) {
                if (o.mat == 'iron' || o.mat == 'gold') {
                    event.remove({ id: `bloodmagic:alchemytable/sand_${o.mat}` })
                }
                if (o.mat != 'copper') {
                    event.custom({
                        "type": "bloodmagic:alchemytable",
                        "input": [
                            {
                                "tag": `c:ores/${o.mat}`
                            },
                            {
                                "tag": "bloodmagic:arc/cuttingfluid"
                            }
                        ],
                        "output": {
                            "count": 2,
                            "item": dust
                        },
                        "syphon": 400,
                        "ticks": 200,
                        "upgradeLevel": 1
                    }).id(`kubejs:bloodmagic/alchemytable/dust_${o.mat}`)
                } else {
                    event.custom({
                        "type": "bloodmagic:alchemytable",
                        "input": [
                            {
                                "tag": `c:ores/${o.mat}`
                            },
                            {
                                "tag": "bloodmagic:arc/cuttingfluid"
                            }
                        ],
                        "output": {
                            "count": 3,
                            "item": dust
                        },
                        "syphon": 400,
                        "ticks": 200,
                        "upgradeLevel": 1
                    }).id(`kubejs:bloodmagic/alchemytable/dust_${o.mat}`)
                }
                boilRec(event, o.mat, out)
            } // end BM_Loaded
            event.custom({
                "type": "mekanism:washing",
                "fluid_input": { "tag": "minecraft:water", "amount": 5 },
                "chemical_input": { "amount": 1, "chemical": dirtySlurry },
                "output": { "id": cleanSlurry, "amount": 1 }
            }).id('kubejs:mekanism/washing/' + cleanSlurry.split("_")[0].split(':')[1] + '/' + cleanSlurry.split('_')[1] + '/from_' + dirtySlurry.split('/')[0].split(":")[1])
            event.custom({
                "type": "mekanism:crystallizing",
                "input": { "amount": 200, "chemical": cleanSlurry },
                "output": { "id": crystal }
            }).id('kubejs:mekanism/crystallizing/' + cleanSlurry.split("_")[0].split(':')[1] + '/' + cleanSlurry.split('_')[1] + '/from_' + crystal.split('/')[0].split(":")[1])
            mekInjecting(event, _, `c:crystals/${o.mat}`, _, shard)
            creFill(event, _, `c:crystals/${o.mat}`, _, shard)
            event.custom({
                "type": "immersiveengineering:bottling_machine",
                "fluid": {
                    "amount": 300,
                    "tag": "c:hydrogen_chloride"
                },
                "input": {
                    "item": crystal
                },
                "results": [
                    {
                        "id": shard
                    }
                ]
            }).id('kubejs:immersive_engineering/bottling/' + crystal.split("_")[0].split(':')[1] + '/' + crystal.split('_')[1] + '/from_' + shard.split('/')[0].split(":")[1])
            mekPur(event, `c:shards/${o.mat}`, _, clump)
            mekPur(event, `c:ores/${o.mat}`, _, clump, 3)
            event.custom({
                "type": "mekanism:crushing",
                "input": { "item": clump },
                "output": { "id": dirtyDust }
            }).id('kubejs:mekanism/crushing/' + dirtyDust.split("_")[0].split(':')[1] + '/' + dirtyDust.split('_')[1] + '/from_' + clump.split('/')[0].split(":")[1])
            event.custom({
                "type": "mekanism:crushing",
                "input": { "item": out },
                "output": { "id": dust }
            }).id('kubejs:mekanism/crushing/' + dust.split("_")[0].split(':')[1] + '/' + dust.split('_')[1] + '/from_' + out.split('/')[0].split(":")[1])
            mekEnrich(event, `c:dirty_dusts/${o.mat}`, dust)
            if (loaded.Botania_Loaded) event.custom({
                "type": "botania:mana_infusion",
                "catalyst": {
                    "type": "block",
                    "block": "botania:alchemy_catalyst"
                },
                "group": "atc:dust_cycle",
                "input": {
                    "item": dirtyDust
                },
                "mana": 4000,
                "output": {
                    "item": dust
                }
            }).id('kubejs:botania/mana_infusion/' + dust.split("_")[0].split(':')[1] + '/' + dust.split('_')[1] + '/from_' + dirtyDust.split('/')[0].split(":")[1])
            event.custom({
                "type": "create:splashing",
                "ingredients": [
                    {
                        "item": dirtyDust
                    }
                ],
                "results": [
                    {
                        "id": dust,
                        "count": 1
                    }
                ]
            }).id('kubejs:create/splashing/' + dust.split("_")[0].split(':')[1] + '/' + dust.split('_')[1] + '/from_' + dirtyDust.split('/')[0].split(":")[1])
            mekInjecting(event, _, `c:ores/${o.mat}`, _, shard, 4)
            creCrush(event, `c:clumps/${o.mat}`, dirtyDust, _, 0)
            forbiddenCombustion(event, `c:ores/${o.mat}`, out)
            forbiddenCombustion(event, `c:dusts/${o.mat}`, out)
            immersiveArc(event, `c:ores/${o.mat}`, o.mat, out)
            immersiveArc(event, `c:dusts/${o.mat}`, o.mat, out)
            if (Item.exists(`create:crushed_raw_${o.mat}`)) {
                event.custom({
                    "type": "create:mixing",
                    "ingredients": [
                        {
                            "item": "minecraft:quartz"
                        },
                        {
                            "count": 16,
                            "item": `create:crushed_raw_${o.mat}`
                        }
                    ],
                    "results": [
                        {
                            "count": 32,
                            "id": out
                        }
                    ],
                    "heatRequirement": "heated"
                }).id(`kubejs:createchromatic/${o.mat}_doubling`)
                if (loaded.CCR_Loaded) event.custom({
                    "type": "create:mixing",
                    "ingredients": [
                        {
                            "item": "createchromaticreturn:fortunite_bar"
                        },
                        {
                            "item": "minecraft:quartz"
                        },
                        {
                            "count": 16,
                            "item": `create:crushed_raw_${o.mat}`
                        }
                    ],
                    "results": [
                        {
                            "count": 64,
                            "id": out
                        }
                    ],
                    "heatRequirement": "superheated"
                }).id(`kubejs:createchromatic/${o.mat}_fortunite`)
                event.remove({ id: `createchromaticreturn:${o.mat}_doubling` })
                event.remove({ id: `createchromaticreturn:${o.mat}_fortunite` })
                creCrush(event, `c:ores/${o.mat}`, `create:crushed_raw_${o.mat}`, 6)
                forbiddenCombustion(event, `create:crushed_raw_${o.mat}`, out)
            } else {
                creCrush(event, `c:ores/${o.mat}`, dirtyDust, 6)
            }
            if (Item.exists(`${o.orE}:raw_${o.mat}`)) {
                if (Item.exists(`create:crushed_raw_${o.mat}`)) {
                    creCrush(event, `c:raw_materials/${o.mat}`, `create:crushed_raw_${o.mat}`)
                } else {
                    creCrush(event, `c:raw_materials/${o.mat}`, dirtyDust)
                }
                if (loaded.BM_Loaded) bloodmagicArc(event, `c:raw_materials/${o.mat}`, dust, _, _, true)
                immersiveArc(event, `c:raw_materials/${o.mat}`, o.mat, out)
                forbiddenCombustion(event, `c:raw_materials/${o.mat}`, out)
                mekInjecting(event, _, `c:raw_materials/${o.mat}`, 3, shard)
                mekPur(event, `c:raw_materials/${o.mat}`, _, clump, 2)
                mekEnrich(event, `c:raw_materials/${o.mat}`, dust, 4)
                occultCrush(event, `c:raw_materials/${o.mat}`, dust)
                immersiveCrush(event, _, `c:raw_materials/${o.mat}`, true, dust)
                creFill(event, _, `c:raw_materials/${o.mat}`, 3, shard, 8)
                mekDissolution(event, _, `c:raw_materials/${o.mat}`, 3, dirtySlurry, 2000)
                event.custom({
                    "type": "minecraft:smelting",
                    "result": { "id": out },
                    "ingredient": {
                        "tag": `c:raw_materials/${o.mat}`
                    },
                    "cookingtime": 200,
                    "experience": 0.6
                }).id(`kubejs:minecraft/smelting/${o.mat}/ingot/from_raw_ore`)
                event.custom({
                    "type": "minecraft:blasting",
                    "result": { "id": out },
                    "ingredient": {
                        "tag": `c:raw_materials/${o.mat}`
                    },
                    "cookingtime": 100,
                    "experience": 0.6
                }).id(`kubejs:minecraft/blasting/${o.mat}/ingot/from_raw_ore`)
            }
            if (Item.exists(`${o.orE}:raw_${o.mat}_block`) || Item.exists(`${o.modAdd}:raw_${o.mat}_block`)) {
                if (Item.exists(`create:crushed_raw_${o.mat}`)) {
                    creCrush(event, `c:storage_blocks/raw_${o.mat}`, `create:crushed_raw_${o.mat}`, 9)
                } else {
                    creCrush(event, `c:storage_blocks/raw_${o.mat}`, dirtyDust, 9)
                }
                immersiveArc(event, `c:storage_blocks/raw_${o.mat}`, o.mat, out)
                mekInjecting(event, 2, `c:storage_blocks/raw_${o.mat}`, _, shard, 24)
                mekPur(event, `c:storage_blocks/raw_${o.mat}`, 2, clump, 18)
                mekEnrich(event, `c:storage_blocks/raw_${o.mat}`, dust, 12)
                occultCrush(event, `c:storage_blocks/raw_${o.mat}`, dust, 18)
                immersiveCrush(event, 54000, `c:storage_blocks/raw_${o.mat}`, _, dust, 12)
                creFill(event, 500, `c:storage_blocks/raw_${o.mat}`, _, shard, 24)
                mekDissolution(event, 2, `c:storage_blocks/raw_${o.mat}`, _, dirtySlurry, 6000)
            }
            if (loaded.BM_Loaded) bloodmagicArc(event, `c:ores/${o.mat}`, dust, 3)
            mekEnrich(event, `c:ores/${o.mat}`, dust, 2)
            occultCrush(event, `c:ores/${o.mat}`, dust)
            immersiveCrush(event, _, `c:ores/${o.mat}`, _, dust, 2)
            mekDissolution(event, _, `c:ores/${o.mat}`, _, dirtySlurry)
            creFill(event, _, `c:ores/${o.mat}`, _, shard, 4)
            if (loaded.Thermal_Loaded && Item.exists(`${o.orE}:${o.mat}_plate`)) {
                event.custom({
                    "type": "thermal:pulverizer",
                    "ingredient": {
                        "tag": `c:plates/${o.mat}`
                    },
                    "result": [
                        {
                            "id": dust,
                            "count": 1
                        }
                    ],
                    "energy_mod": 0.5
                }).id(`kubejs:thermal/pulverizer/${o.mat}/dust/from_plate`)
            }
            if (Item.exists(`${o.orE}:${o.mat}_ingot`)) {
                if (loaded.BM_Loaded) bloodmagicArc(event, `c:ingots/${o.mat}`, dust, _, 'bloodmagic:arc/explosive')
                immersiveCrush(event, _, `c:ingots/${o.mat}`, _, dust)
                occultCrush(event, `c:ingots/${o.mat}`, dust)
                if (loaded.Thermal_Loaded) event.custom({
                    "type": "thermal:pulverizer",
                    "ingredient": {
                        "tag": `c:ingots/${o.mat}`
                    },
                    "result": [
                        {
                            "id": dust,
                            "count": 1
                        }
                    ],
                    "energy_mod": 0.5
                }).id(`kubejs:thermal/pulverizer/${o.mat}/dust/from_ingot`)
            }
            if (loaded.BM_Loaded && Item.exists(`bloodmagic:${o.mat}gravel`)) {
                bloodmagicArc(event, `bloodmagic:gravels/${o.mat}`, dust)
            }
            event.remove({ id: `thermal:machines/pulverizer/pulverizer_${o.mat}_ingot_to_dust` })
            event.remove({ id: `thermal:machines/pulverizer/pulverizer_${o.mat}_plate_to_dust` })
            event.custom({
                "type": "minecraft:smelting",
                "result": { "id": out },
                "ingredient": {
                    "tag": `c:ores/${o.mat}`
                },
                "cookingtime": 200,
                "experience": 0.7
            }).id(`kubejs:minecraft/smelting/${o.mat}/ingot/from_ore`)
            event.custom({
                "type": "minecraft:blasting",
                "result": { "id": out },
                "ingredient": {
                    "tag": `c:ores/${o.mat}`
                },
                "cookingtime": 100,
                "experience": 0.7
            }).id(`kubejs:minecraft/blasting/${o.mat}/ingot/from_ore`)
            event.custom({
                "type": "minecraft:smelting",
                "result": { "id": out },
                "ingredient": {
                    "item": dust
                },
                "cookingtime": 200,
                "experience": 0.3
            }).id('kubejs:minecraft/smelting/' + dust.split(":")[1].split('_')[0] + '/' + dust.split(':')[1].split('_')[1] + '/from_ore')
            event.custom({
                "type": "minecraft:blasting",
                "result": { "id": out },
                "ingredient": {
                    "item": dust
                },
                "cookingtime": 100,
                "experience": 0.3
            }).id('kubejs:minecraft/blasting/' + dust.split(":")[1].split('_')[0] + '/' + dust.split(':')[1].split('_')[1] + '/from_dust')
            if (loaded.Thermal_Loaded && (o.mat == 'cobalt' || o.mat == 'nickel' || o.mat == 'lead' || o.mat == 'uranium' || o.mat == 'tin' || o.mat == 'osmium' || o.mat == 'copper')) {
                event.custom({
                    "type": "thermal:chiller",
                    "ingredients": [
                        {
                            "fluid": `tconstruct:molten_${o.mat}`,
                            "amount": 90
                        },
                        {
                            "item": "thermal:chiller_ingot_cast"
                        }
                    ],
                    "result": [
                        {
                            "item": out,
                            "count": 1
                        }
                    ],
                    "energy": 4800
                }).id(`kubejs:thermal/chilling/ingot/${o.mat}/from_molten`)
                event.custom({
                    "type": "tconstruct:melting",
                    "ingredient": {
                        "item": dust
                    },
                    "result": {
                        "fluid": `tconstruct:molten_${o.mat}`,
                        "amount": 90
                    },
                    "temperature": 975,
                    "time": 100,
                }).id(`kubejs:tconstruct/melting/molten/${o.mat}/from_dust`)
            } else if (loaded.Thermal_Loaded && o.orE == 'ad_astra') {
                event.custom({
                    "type": "thermal:chiller",
                    "ingredients": [
                        {
                            "fluid": `tcintegrations:molten_${o.mat}`,
                            "amount": 90
                        },
                        {
                            "item": "thermal:chiller_ingot_cast"
                        }
                    ],
                    "result": [
                        {
                            "item": out,
                            "count": 1
                        }
                    ],
                    "energy": 4800
                }).id(`kubejs:thermal/chilling/ingot/${o.mat}/from_molten`)
                event.custom({
                    "type": "tconstruct:melting",
                    "ingredient": {
                        "item": dust
                    },
                    "result": {
                        "fluid": `tcintegrations:molten_${o.mat}`,
                        "amount": 90
                    },
                    "temperature": 975,
                    "time": 100,
                }).id(`kubejs:tconstruct/melting/molten/${o.mat}/from_dust`)
            }
            event.remove({ id: `thermal:compat/tconstruct/chiller_tconstruct_${o.mat}_ingot` })
            if (Item.exists(`${o.orE}:${o.mat}_ingot`) && Item.exists(`${o.orE}:${o.mat}_nugget`)) {
                event.shaped(
                    Item.of(`${o.orE}:${o.mat}_ingot`),
                    [
                        'AAA',
                        'AAA',
                        'AAA'
                    ],
                    {
                        A: `#c:nuggets/${o.mat}`
                    }
                ).id(`kubejs:${o.mat}_ingot_from_nuggets`)
                event.shapeless(
                    Item.of(`${o.orE}:${o.mat}_nugget`, 9),
                    [
                        `#c:ingots/${o.mat}`
                    ]
                ).id(`kubejs:${o.mat}_nuggets_from_ingot`)
                event.forEachRecipe({ type: 'minecraft:crafting_shaped', input: `${o.orE}:${o.mat}_nugget`, output: `${o.orE}:${o.mat}_ingot` }, recipe => {
                    event.remove({ id: recipe.getId() })
                })
                event.forEachRecipe({ type: 'minecraft:crafting_shapeless', input: `${o.orE}:${o.mat}_ingot`, output: `${o.orE}:${o.mat}_nugget` }, recipe => {
                    event.remove({ id: recipe.getId() })
                })
            }
            if (Item.exists(`${o.orE}:${o.mat}_ingot`) && Item.exists(`${o.orE}:${o.mat}_block`)) {
                event.shaped(
                    Item.of(`${o.orE}:${o.mat}_block`),
                    [
                        'AAA',
                        'AAA',
                        'AAA'
                    ],
                    {
                        A: `#c:ingots/${o.mat}`
                    }
                ).id(`kubejs:${o.mat}_block_from_ingots`)
                event.shapeless(
                    Item.of(`${o.orE}:${o.mat}_ingot`, 9),
                    [
                        `#c:storage_blocks/${o.mat}`
                    ]
                ).id(`kubejs:${o.mat}_ingots_from_block`)
                event.forEachRecipe({ type: 'minecraft:crafting_shapeless', input: `#c:storage_blocks/${o.mat}`, output: `${o.orE}:${o.mat}_ingot` }, recipe => {
                    event.remove({ id: recipe.getId() })
                })
                event.forEachRecipe({ type: 'minecraft:crafting_shaped', input: `${o.orE}:${o.mat}_ingot`, output: `${o.orE}:${o.mat}_block` }, recipe => {
                    event.remove({ id: recipe.getId() })
                })
            }
            if (Item.exists(`${o.orE}:${o.mat}_ingot`) && Item.exists(`create:crushed_raw_${o.mat}`)) {
                event.custom({
                    "type": "minecraft:smelting",
                    "result": { "id": out },
                    "ingredient": {
                        "item": `create:crushed_raw_${o.mat}`
                    },
                    "cookingtime": 200,
                    "experience": 0.1
                }).id(`kubejs:minecraft/smelting/${o.mat}/ingot/from_crushed_ore`)
                event.custom({
                    "type": "minecraft:blasting",
                    "result": { "id": out },
                    "ingredient": {
                        "item": `create:crushed_raw_${o.mat}`
                    },
                    "cookingtime": 100,
                    "experience": 0.1
                }).id(`kubejs:minecraft/blasting/${o.mat}/ingot/from_crushed_ore`)
            }
        }
    })

    if (loaded.FA_Loaded) event.replaceInput({ input: 'forbidden_arcanus:ender_pearl_fragment' },
        'forbidden_arcanus:ender_pearl_fragment',
        '#c:nuggets/ender_pearl'
    )
    event.replaceInput({ input: 'inventorypets:nugget_ender' },
        'inventorypets:nugget_ender',
        '#c:nuggets/ender_pearl'
    )
    if (loaded.FA_Loaded) event.replaceOutput({ output: 'forbidden_arcanus:ender_pearl_fragment' },
        'forbidden_arcanus:ender_pearl_fragment',
        'inventorypets:nugget_ender'
    )
    let cull = [
        'azure_silver',
        'bismuth',
        'boron',
        'magnesium',
        'titanium',
        'tungsten',
        'thorium',
        'crimson_iron',
        'draconium'
    ]
    cull.forEach(mat => {
        event.remove({ output: `moremekanismprocessing:dirty_${mat}` })
        event.remove({ output: `moremekanismprocessing:clean_${mat}` })
        event.remove({ output: `moremekanismprocessing:crystal_${mat}` })
        event.remove({ output: `moremekanismprocessing:shard_${mat}` })
        event.remove({ output: `moremekanismprocessing:clump_${mat}` })
        event.remove({ output: `moremekanismprocessing:dirty_dust_${mat}` })
    })
    removeRecipeByID(event, [
        'tconstruct:smeltery/melting/metal/cobalt/dust',
        'immersiveengineering:crafting/plate_desh_hammering',
        'immersiveengineering:crafting/plate_calorite_hammering',
        'immersiveengineering:crafting/plate_ostrum_hammering',
    ])
    if (loaded.BM_Loaded) {
        removeRecipeByID(event, ['bloodmagic:alchemytable/corrupted_coal'])
    }
    event.custom({
        "type": "create:crushing",
        "ingredients": [
            {
                "tag": `create:stone_types/crimsite`
            }
        ],
        "processingTime": 400,
        "results": [
            {
                "chance": 0.40,
                "id": "create:crushed_raw_iron"
            },
            {
                "chance": 0.40,
                "id": "minecraft:iron_nugget"
            }
        ]
    }).id("kubejs:create/crushing/crimsite")
    event.custom({
        "type": "create:crushing",
        "ingredients": [
            {
                "tag": `create:stone_types/ochrum`
            }
        ],
        "processingTime": 400,
        "results": [
            {
                "chance": 0.20,
                "id": "create:crushed_raw_gold"
            },
            {
                "chance": 0.20,
                "id": "minecraft:gold_nugget"
            }
        ]
    }).id("kubejs:create/crushing/ochrum")
    event.custom({
        "type": "create:crushing",
        "ingredients": [
            {
                "tag": `create:stone_types/veridium`
            }
        ],
        "processingTime": 400,
        "results": [
            {
                "chance": 0.80,
                "id": "create:crushed_raw_copper"
            },
            {
                "chance": 0.80,
                "id": "alltheores:copper_nugget"
            }
        ]
    }).id("kubejs:create/crushing/veridium")
    event.custom({
        "type": "create:crushing",
        "ingredients": [
            {
                "tag": `create:stone_types/asurine`
            }
        ],
        "processingTime": 400,
        "results": [
            {
                "chance": 0.30,
                "id": "create:crushed_raw_zinc"
            },
            {
                "chance": 0.30,
                "id": "alltheores:zinc_nugget"
            }
        ]
    }).id("kubejs:create/crushing/asurine")
    event.replaceInput({ input: 'create:brass_sheet' },
        'create:brass_sheet',
        '#c:plates/brass'
    )
    event.replaceInput({ input: 'create:iron_sheet' },
        'create:iron_sheet',
        '#c:plates/iron'
    )
    event.replaceInput({ input: 'create:copper_sheet' },
        'create:copper_sheet',
        '#c:plates/copper'
    )
    event.shapeless(
        Item.of('minecraft:flint', 9),
        ['#c:storage_blocks/flint']
    ).id('kubejs:flint_unpacking')
    let moreMekBoil = [
        'aluminum',
        'azure_silver',
        'bismuth',
        'boron',
        'calorite',
        'cobalt',
        'crimson_iron',
        'desh',
        'draconium',
        'iridium',
        'lithium',
        'magnesium',
        'nickel',
        'ostrum',
        'platinum',
        'silver',
        'thorium',
        'titanium',
        'tungsten',
        'zinc'
    ]
    moreMekBoil.forEach(boils => {
        event.remove({ output: `moremekanismprocessing:${boils}_ingot` })
        event.remove({ id: `/enderio:smelting/moremekanismprocessing/processing/${boils}/ingot/from_dust_smelting/` })
    })

    removeRecipeByID(event, [
        'actuallyadditions:charcoal_to_tiny',
        'actuallyadditions:tiny_to_charcoal',
        'actuallyadditions:coal_to_tiny',
        'actuallyadditions:tiny_to_coal',
        'ad_astra:steel_rod',
        'ad_astra:iron_rod',
        'alexscaves:uranium_from_shard',
        'alexscaves:uranium_from_block',
        'alexscaves:uranium_shard_from_uranium',
        'alexscaves:block_of_uranium',
        'alltheores:raw_osmium_block',
        'bigreactors:crafting/raw_yellorium_component_to_storage',
        'buildersaddition:iron_rod',
        'compressedcreativity:mixing/memory_essence',
        'create:crafting/materials/copper_nugget',
        'createdeco:netherite_nugget_from_netherite_ingot',
        'createaddition:compat/immersiveengineering/crushing/coke_block',
        'cyclic:netherite_ingot',
        'eidolon:raw_silver_block',
        'eidolon:raw_lead_block',
        'eidolon:silver_block',
        'eidolon:lead_ingot',
        'enderio:iron_gear',
        'forbidden_arcanus:ender_pearl',
        'forbidden_arcanus:ender_pearl_fragment',
        'forestry:raw_tin_block',
        'forestry:resource_storage_bronze',
        'forestry:ingot_bronze_alloying',
        'forestry:gear_tin',
        `forestry:resource_storage_tin`,
        `forestry:resource_storage_bronze`,
        'immersiveengineering:crafting/raw_uranium_to_raw_block_uranium',
        'inventorypets:nugget_coal_alt',
        'inventorypets:nugget_diamond_alt',
        'inventorypets:nugget_emerald_alt',
        'inventorypets:nugget_obsidian_alt',
        'inventorypets:nugget_ender_alt',
        'ironcoals:charcoal_chunk',
        'ironcoals:charcoal',
        'ironcoals:base_coal_chunk',
        'ironcoals:coal',
        'mekanism:processing/lead/storage_blocks/from_ingots',
        `mekanism:processing/osmium/nugget/from_ingot`,
        `mekanism:processing/osmium/ingot/from_nuggets/`,
        `mekanism:processing/osmium/ingot/from_block/`,
        `mekanism:processing/osmium/storage_blocks/from_ingots/`,
        `mekanism:processing/tin/nugget/from_ingot`,
        `mekanism:processing/tin/ingot/from_nuggets/`,
        `mekanism:processing/tin/ingot/from_block/`,
        `mekanism:processing/tin/storage_blocks/from_ingots/`,
        `mekanism:processing/uranium/nugget/from_ingot`,
        `mekanism:processing/uranium/ingot/from_nuggets/`,
        `mekanism:processing/uranium/ingot/from_block/`,
        `mekanism:processing/uranium/storage_blocks/from_ingots/`,
        `mekanism:nuggets/bronze`,
        `mekanism:storage_blocks/bronze`,
        `mekanism:processing/bronze/ingot/from_block`,
        `mekanism:processing/bronze/ingot/from_nuggets`,
        `mekanism:nuggets/steel`,
        `mekanism:storage_blocks/steel`,
        `mekanism:processing/steel/ingot/from_block`,
        `mekanism:processing/steel/ingot/from_nuggets`,
        'supplementaries:flint_block',
        'thermal:storage/raw_tin_block',
        'thermal:enderium_dust_2',
        'thermal:storage/bronze_ingot_from_nuggets',
        'thermal:parts/copper_gear',
        'thermal:storage/bronze_block',

        //=== MoreMekanismProcessing ===
        `moremekanismprocessing:processing/draconium/slurry/dirty/ore`,
        `moremekanismprocessing:processing/lithium/dust/from_ingot`,
        `moremekanismprocessing:processing/lithium/dust/from_dirty_dust`,
        'moremekanismprocessing:processing/amethyst/gem/from_dust',
        `moremekanismprocessing:processing/aluminum/nugget/from_ingot`,
        `moremekanismprocessing:processing/aluminum/ingot/from_nugget`,
        `moremekanismprocessing:processing/calorite/nugget/from_ingot`,
        `moremekanismprocessing:processing/calorite/ingot/from_nugget`,
        `moremekanismprocessing:processing/iridium/nugget/from_ingot`,
        `moremekanismprocessing:processing/iridium/ingot/from_nugget`,
        `moremekanismprocessing:processing/nickel/nugget/from_ingot`,
        `moremekanismprocessing:processing/nickel/ingot/from_nugget`,
        `moremekanismprocessing:processing/platinum/nugget/from_ingot`,
        `moremekanismprocessing:processing/platinum/ingot/from_nugget`,
        `moremekanismprocessing:processing/zinc/nugget/from_ingot`,
        `moremekanismprocessing:processing/zinc/ingot/from_nugget`,
        `botanypots:mysticalagriculture/crop/titanium`,
        `botanypots:mysticalagriculture/crop/tungsten`,

        //=== Sky Exclusive ===
        'bygonenether:pressing/netherite_scrap_ingot',
        `exdeorum:cobblestone`,
        `exdeorum:cobbled_deepslate`,
        'opolisutilities:ender_pearl_fragments_from_ender_pearl',
        'opolisutilities:ender_pearl_from_ender_pearl_fragments',
        'opolisutilities:copper_ingot_from_nuggets',
        `strainers:cobbled_deepslate`,
        `strainers:cobblestone`
    ])

    event.custom({
        "type": "mekanism:crushing",
        "input": { "tag": "c:ingots/draconium" },
        "output": { "id": "draconicevolution:draconium_dust" }
    }).id('kubejs:processing/draconium/dust/from_ingot')
    mekEnrich(event, "c:ores/draconium", "draconicevolution:draconium_dust", 2)

    if (false) {
        console.log("AU + Sky Unifier applied safely:", recipeCounts)
    }

})