// packs/data/modular_mc/_shared/particleEmitter.ts
import {
  system
} from "@minecraft/server";
var component = {
  onRandomTick(event, data) {
    const params = data.params;
    const particles = params.particles;
    if (!particles) return;
    particles.forEach((particle) => {
      event.block.dimension.spawnParticle(particle, event.block.location);
    });
  }
};
system.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:particle_emitter", component);
});

// packs/data/modular_mc/_shared/onConsumeEvent.ts
import {
  system as system2
} from "@minecraft/server";
var component2 = {
  onConsume: (event, args) => {
    const params = args.params;
    if (!params) return;
    if (params.clear_negative_effects === true) {
      clearNegativeEffects(event.source);
    }
    if (params.heal) {
      const hp = event.source.getComponent("minecraft:health");
      if (!hp) return;
      const clampedValue = Math.min(20, Math.max(0, hp.currentValue + params.heal));
      hp.setCurrentValue(clampedValue);
    }
    switch (params.effects) {
      case "mandrake_root":
        event.source.addEffect("speed", 20 * 60 * 3, {
          amplifier: 3,
          showParticles: true
        });
        event.source.addEffect("regeneration", 20 * 60 * 3, {
          amplifier: 3,
          showParticles: true
        });
        break;
    }
  }
};
system2.beforeEvents.startup.subscribe((init) => {
  init.itemComponentRegistry.registerCustomComponent("tsu_nat:on_consume_event", component2);
});
function clearNegativeEffects(entity) {
  entity.removeEffect("slowness");
  entity.removeEffect("weakness");
  entity.removeEffect("poison");
  entity.removeEffect("fatal_poison");
  entity.removeEffect("nausea");
  entity.removeEffect("blindness");
  entity.removeEffect("hunger");
  entity.removeEffect("mining_fatigue");
  entity.removeEffect("wither");
  entity.removeEffect("darkness");
  entity.removeEffect("infested");
}

// packs/data/modular_mc/_shared/customLadders.ts
import { system as system3, world } from "@minecraft/server";
function climb(player) {
  const block1 = player.dimension.getBlock(player.location);
  const block2 = block1?.above();
  if (!block1?.hasTag("tsu_nat:can_climb") && !block2?.hasTag("tsu_nat:can_climb")) return;
  const effect = player.isJumping ? "levitation" : "slow_falling";
  player.addEffect(effect, 5, {
    amplifier: 2,
    showParticles: false
  });
  if (player.isSneaking && !player.isJumping) {
    player.applyKnockback({ x: 0, z: 0 }, 0.02);
  }
}
system3.runInterval(() => {
  for (const player of world.getPlayers()) {
    climb(player);
  }
});

// packs/data/modular_mc/_shared/growingCrop.ts
import {
  EquipmentSlot,
  GameMode,
  system as system4
} from "@minecraft/server";
var randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
var component3 = {
  onRandomTick(event, data) {
    const params = data.params;
    const block = event.block;
    const growthState = params.growth_state;
    const moisturizedAmountBonus = (event.block.below()?.permutation.getState("moisturized_amount") || 0) * params.moisturized_amount_bonus;
    const growthChance = params.growth_chance + moisturizedAmountBonus;
    if (Math.random() > growthChance) return;
    const growth = block.permutation.getState(growthState);
    block.setPermutation(block.permutation.withState(growthState, growth + 1));
  },
  onPlayerInteract(event, data) {
    const params = data.params;
    const block = event.block;
    const dimension = event.dimension;
    const player = event.player;
    const growthState = params.growth_state;
    const maxGrowth = params.max_growth;
    if (!player) return;
    const equippable = player.getComponent("minecraft:equippable");
    if (!equippable) return;
    const mainhand = equippable.getEquipmentSlot(EquipmentSlot.Mainhand);
    const hasBoneMeal = mainhand.hasItem() && mainhand.typeId === "minecraft:bone_meal";
    if (!hasBoneMeal) return;
    if (player.getGameMode() === GameMode.Creative) {
      block.setPermutation(block.permutation.withState(growthState, maxGrowth));
    } else {
      let growth = block.permutation.getState(growthState);
      growth += randomInt(1, maxGrowth - growth);
      block.setPermutation(block.permutation.withState(growthState, growth));
      if (mainhand.amount > 1) mainhand.amount--;
      else mainhand.setItem(void 0);
    }
    const effectLocation = block.center();
    dimension.playSound("item.bone_meal.use", effectLocation);
    dimension.spawnParticle("minecraft:crop_growth_emitter", effectLocation);
  }
};
system4.beforeEvents.startup.subscribe(({ blockComponentRegistry }) => {
  blockComponentRegistry.registerCustomComponent("tsu_nat:growable", component3);
});

// packs/data/modular_mc/menu_system/EasyMenu.js
import { ActionFormData } from "@minecraft/server-ui";
var EasyMenu = class {
  constructor(menuData) {
    this.pages = menuData.pages;
    this.backButton = menuData.backButton;
  }
  showPage(player, pageId, history = []) {
    if (!this.pages[pageId]) {
      console.warn(`Page ${pageId} not found`);
      return;
    }
    const pageData = typeof this.pages[pageId] === "function" ? this.pages[pageId](player) : this.pages[pageId];
    const form = new ActionFormData();
    form.title(pageData.title);
    form.body(Array.isArray(pageData.body) ? pageData.body.join("\xA7r\n") : pageData.body);
    pageData.buttons?.forEach((button) => {
      form.button(
        Array.isArray(button.text) ? button.text.join("\xA7r\n") : button.text,
        button.image
      );
    });
    if (this.backButton?.enabled && history.length > 0) {
      form.button(this.backButton.text, this.backButton.image);
    }
    form.show(player).then((formData) => {
      const selection = formData.selection;
      if (formData.canceled || selection === void 0) {
        return;
      }
      const backButtonSelected = this.backButton.enabled && history.length > 0 && selection === (pageData.buttons?.length ?? 0);
      if (backButtonSelected) {
        this.goBack(player, history);
      } else if (pageData.buttons) {
        const selectedButton = pageData.buttons[selection];
        const nextPageId = selectedButton.link;
        if (typeof selectedButton.onClick === "function") {
          selectedButton.onClick(player);
        }
        if (nextPageId === "exit") {
          return;
        } else if (nextPageId === "back") {
          this.goBack(player, history);
        } else if (nextPageId) {
          if (pageId !== nextPageId) {
            history.push(pageId);
          }
          this.showPage(player, nextPageId, history);
        }
      }
    }).catch((error) => {
      player.sendMessage(`Failed to show menu: ${error}`);
    });
  }
  goBack(player, history) {
    const previousPage = history.pop();
    this.showPage(player, previousPage, history);
  }
};

// packs/data/modular_mc/menu_system/guidebook/guidebook.js
import { world as world2 } from "@minecraft/server";
var guidebook = new EasyMenu({
  backButton: {
    enabled: true,
    text: "Back",
    image: "textures/gui/controls/left",
    link: "back"
  },
  pages: {
    /* ----------------------------------- INTRODUCTION ----------------------------------- */
    start: {
      title: "Introduction",
      body: [
        `            \xA7vWelcome, wanderer`,
        "",
        "        \xA7e----  Into the Wild ----\xA7r",
        "",
        "\xA7vThis Add-On expands your experience",
        "with new biomes, creatures, foods, brews, blocks, structures and systems.",
        " ",
        "\xA7vEvery addition has a purpose:",
        "materials, crafting, and exploration all connect to create a richer and more rewarding adventure.",
        " ",
        "\xA7vExplore deeper, survive longer,",
        "and make the world truly feel alive.",
        " ",
        "\xA7vIf you enjoy this Add-On,",
        "please support us with a \xA7erating\xA7r on the Marketplace!",
        "\xA7v--------------------------------",
        "\xA7vChoose a topic to begin:"
      ],
      buttons: [
        {
          image: "textures/tsu/nat/guidebook/icons/fungal_grove",
          text: "Biomes",
          link: "biomes"
        },
        { image: "textures/tsu/nat/guidebook/icons/recipes", text: "Recipes", link: "recipes" },
        {
          image: "textures/tsu/nat/guidebook/icons/structures",
          text: "Structures",
          link: "extras"
        },
        { image: "textures/tsu/nat/guidebook/icons/info", text: "Info", link: "info" }
      ]
    },
    /* ------------------------------------ BIOME PAGES ----------------------------------- */
    biomes: {
      title: "Biomes",
      body: ["Choose a biome to learn what unique items and content it contains:"],
      buttons: [
        {
          text: "Fungal Grove",
          link: "fungal_grove"
        },
        {
          text: "Charred Forest",
          link: "charred_forest"
        },
        {
          text: "Maple Forest",
          link: "maple_forest"
        },
        {
          text: "Oasis",
          link: "oasis"
        },
        {
          text: "Salt flats",
          link: "salt_flats"
        }
      ]
    },
    fungal_grove: {
      title: "Fungal Grove",
      body: [
        "\xA77--------------------------------",
        "\xA7o\xA77Where roots hum songs",
        "\xA7o\xA77no man can hear,",
        "\xA7o\xA77Spores drift thick,",
        "\xA7o\xA77yet crystal clear.",
        "\xA7o\xA77The air itself begins to weave,",
        "\xA7o\xA77Illusions born of rot and leaves.",
        "",
        "\xA7o\xA77Dreams take root where reason dies",
        "\xA7o\xA77The Grove sees all",
        "\xA7o\xA77with half-closed eyes.",
        "\xA77--------------------------------",
        "",
        "Adventurers can harvest unique building blocks and even catch \xA7vFungus gnats\xA7r, which drop \xA7vWild Yeast\xA7r, a handy crafting ingredient.",
        "",
        "Hunt for \xA7vwild boars\xA7r and \xA7vcure\xA7r their meat",
        "",
        "Here you might also encounter \xA7vblooshrooms\xA7r, Feed them glowing mushrooms, then milk them with a bowl to obtain some \xA7vmushroom brew\xA7r",
        "",
        "On rare \xA7lfull moons\xA7r, mysterious \xA7vMandrake Roots\xA7r are ready to awake. Breaking one causes the Mandrake to leap up and flee - chase it quickly to claim the root!",
        "",
        "\xA7sFound near: [Taiga Forests]",
        "\xA7v--------------------------------",
        "\xA7vWhat you might find and craft here:"
      ],
      buttons: [
        { link: "wild_yeast", image: "textures/tsu/nat/items/wild_yeast", text: "Wild Yeast" },
        {
          link: "mandrake_root",
          image: "textures/tsu/nat/items/mandrake_root",
          text: "Mandrake Root"
        },
        { link: "kefir", image: "textures/tsu/nat/items/kefir", text: "Yoghurt" },
        { link: "kvass", image: "textures/tsu/nat/items/kvass", text: "Beetroot Soda" },
        { link: "kombucha", image: "textures/tsu/nat/items/kombucha", text: "Mushroom Brew" },
        { link: "root_brew", image: "textures/tsu/nat/items/root_brew", text: "Root Brew" },
        {
          link: "fungus_gnat",
          image: "textures/tsu/nat/guidebook/icons/firefly",
          text: "Fungus Gnat"
        },
        {
          link: "blooshroom",
          image: "textures/tsu/nat/guidebook/icons/blooshroom",
          text: "Blooshroom"
        },
        {
          link: "wild_boar",
          image: "textures/tsu/nat/guidebook/icons/boar",
          text: "Wild Boar"
        }
      ]
    },
    charred_forest: {
      title: "Charred Forest",
      body: [
        "\xA77--------------------------------",
        "\xA77\xA7oAsh drifts where leaves once danced,",
        "\xA77\xA7osmoke swirls in a ghostly trance.",
        "\xA77\xA7oThe wind still holds a cinder's light,",
        "\xA77\xA7oA faint glow in the night.",
        "\xA77--------------------------------",
        "",
        "The \xA7eCharred Forest\xA7r is all that",
        "remains of a once-lush woodland,",
        "now blackened by fire and smoke.",
        "",
        "Ash covers the ground here - ",
        "a vital resource for crafting both",
        "\xA7vGunpowder\xA7r and cleansing \xA7vSoap\xA7r.",
        "",
        "Amidst the ruin stand eerie,",
        "\xA7vCharred Trees\xA7r - haunting yet beautiful, prized as decorative wood.",
        "Harvest them for a chance to get some extra \xA7vcharcoal\xA7r!",
        "",
        "\xA7sFound near: [Temperate Forests]",
        "\xA7v--------------------------------",
        "\xA7vWhat you might find and craft here:"
      ],
      buttons: [
        { link: "ash", image: "textures/tsu/nat/items/ash", text: "Ash" },
        { link: "soap", image: "textures/tsu/nat/items/soap", text: "Soap" },
        { link: "gunpowder", image: "textures/items/gunpowder", text: "Gunpowder" }
      ]
    },
    maple_forest: {
      title: "Maple Forest",
      body: [
        "\xA77--------------------------------",
        "\xA7o\xA77Golden ichor in the veins of trees,",
        "\xA7o\xA77A scent rides the amber breeze.",
        "\xA7o\xA77Footsteps soft on carpet ground,",
        "\xA7o\xA77Sweet forest, autumn-bound.",
        "\xA77--------------------------------",
        "",
        "The \xA7eMaple Forest\xA7r glows with rich autumn colors, scarlet leaves and warm orange tones cover the land.",
        "",
        "Here you'll find the new \xA7vMaple Wood\xA7r, along with scattered \xA7vlog bundles\xA7r and \xA7vsmall fallen logs\xA7r to collect.",
        "",
        "Maple trees slowly ooze sweet \xA7vsap\xA7r.",
        "Craft a \xA7vSap Bucket\xA7r, attach it to an \xA7voozing maple log\xA7r, then wait patiently. Later, use a bottle to gather the \xA7vraw sap\xA7r - a valuable crafting ingredient.",
        "",
        "\xA7eBut beware!",
        "The scent of sap draws dangerous \xA7vSap Slimes\xA7r, notorious for guarding the forest's bounty.",
        "",
        "\xA7sFound near: [Birch and Flower Forests]",
        "\xA7v--------------------------------",
        "\xA7vWhat you might find and craft here:"
      ],
      buttons: [
        { link: "raw_sap", image: "textures/tsu/nat/items/raw_sap", text: "Raw Sap" },
        {
          link: "sap_bucket",
          image: "textures/tsu/nat/guidebook/icons/sap_bucket",
          text: "Sap Bucket"
        },
        {
          link: "maple_syrup",
          image: "textures/tsu/nat/items/maple_syrup",
          text: "Maple Syrup"
        },
        { link: "pancake", image: "textures/tsu/nat/items/pancake", text: "Pancake" },
        {
          link: "sap_slimes",
          image: "textures/tsu/nat/guidebook/icons/sap_slime",
          text: "Sap Slimes"
        }
      ]
    },
    salt_flats: {
      title: "Salt Flats",
      body: [
        "\xA77--------------------------------",
        "\xA7o\xA77White plains stretch",
        "\xA7o\xA77where oceans slept,",
        "\xA7o\xA77Their secrets crusted,",
        "\xA7o\xA77dry, and kept.",
        "\xA7o\xA77No wind, no wave, just endless gleam,",
        "\xA7o\xA77A ghost of tides, a sunlit dream.",
        "\xA77--------------------------------",
        "",
        "Vast and silent, the \xA7eSalt Flats\xA7r mark the bones of vanished seas.",
        "Crystals glint beneath the sun - remnants of an age long drowned.",
        "",
        "Break salt to gather it, or craft blocks to build or \xA7vcure meat with\xA7r.",
        "Smelt it into \xA7vNiter\xA7r to produce \xA7vGunpowder\xA7r - the desert's volatile gift.",
        "",
        "\xA7sFound near: [Deserts]",
        "\xA7v--------------------------------",
        "\xA7vWhat you might find and craft here:"
      ],
      buttons: [
        { link: "curing", image: "textures/tsu/nat/items/salt", text: "Curing" },
        { link: "salt", image: "textures/tsu/nat/items/salt", text: "Salt" },
        { link: "niter", image: "textures/tsu/nat/items/niter", text: "Niter" },
        {
          link: "tumbleweed",
          image: "textures/tsu/nat/guidebook/icons/tumbleweed",
          text: "Tumbleweed"
        }
      ]
    },
    oasis: {
      title: "Oasis",
      body: [
        "\xA77--------------------------------",
        "\xA7o\xA77Amid the dunes, a breath of green,",
        "\xA7o\xA77A mirror where the sky's been seen.",
        "\xA7o\xA77Cool water hums beneath the sand,",
        "\xA7o\xA77A gift the desert can't withstand.",
        "\xA77--------------------------------",
        "",
        "Scattered across the harsh deserts lie rare \xA7voases\xA7r,",
        "pockets of life where \xA7vpalm trees\xA7r rise, and \xA7valoe\xA7r soothes the weary.",
        "",
        "Near desert shores, \xA7vcattails\xA7r thrive, useful for \xA7vrope\xA7r and \xA7vfarming\xA7r.",
        "Travelers rest here, and so do many secrets.",
        "",
        "\xA7sFound near: [Deserts]",
        "\xA7v--------------------------------",
        "\xA7vWhat you might find and craft here:"
      ],
      buttons: [
        { link: "aloe", image: "textures/tsu/nat/items/aloe", text: "Aloe" },
        { link: "cattail", image: "textures/tsu/nat/items/cattail", text: "Cattail" },
        { link: "rope", image: "textures/tsu/nat/items/rope", text: "Rope" }
      ]
    },
    /* ----------------------------------- RECIPES PAGE ----------------------------------- */
    recipes: {
      title: "Recipes",
      body: [
        "Crafting goes beyond the basics - new recipes let you brew, cure, and process items in unique ways.",
        "",
        "\xA7v--------------------------------",
        "\xA7vBrowse the list below to see full crafting details:"
      ],
      buttons: [
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/guidebook",
          text: "Guidebook Recipe"
        },
        {
          link: "soap",
          image: "textures/tsu/nat/guidebook/recipes/soap",
          text: "Soap Recipe"
        },
        {
          link: "root_brew",
          image: "textures/tsu/nat/guidebook/recipes/root_brew",
          text: "Root Brew Recipe"
        },
        {
          link: "kefir",
          image: "textures/tsu/nat/guidebook/recipes/kefir",
          text: "Yoghurt Recipe"
        },
        {
          link: "kvass",
          image: "textures/tsu/nat/guidebook/recipes/kvass",
          text: "Beet Soda Recipe"
        },
        {
          link: "kombucha",
          image: "textures/tsu/nat/guidebook/recipes/kombucha",
          text: "Mushroom Brew Recipe"
        },
        {
          link: "maple_syrup",
          image: "textures/tsu/nat/guidebook/recipes/maple_syrup",
          text: "Maple Syrup Recipe"
        },
        {
          link: "pancake",
          image: "textures/tsu/nat/guidebook/recipes/pancake",
          text: "Pancake Recipe"
        },
        {
          link: "niter",
          image: "textures/tsu/nat/guidebook/recipes/niter",
          text: "Niter Recipe"
        },
        {
          link: "gunpowder",
          image: "textures/tsu/nat/guidebook/recipes/gunpowder",
          text: "Gunpowder Recipe"
        },
        {
          link: "salt",
          image: "textures/tsu/nat/guidebook/recipes/salt_block",
          text: "Block of Salt Recipe"
        },
        {
          link: "rope",
          image: "textures/tsu/nat/guidebook/recipes/rope",
          text: "Rope Recipe"
        },
        {
          link: "cattail",
          image: "textures/tsu/nat/guidebook/recipes/string",
          text: "String Recipe"
        },
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/scarecrow",
          text: "Scarecrow Recipe"
        },
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/ash_block",
          text: "Ash Block Recipe"
        },
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/ash_layer",
          text: "Ash Layer Recipe"
        },
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/wood_bundle",
          text: "Wood Bundle Recipe"
        },
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/small_log",
          text: "Small Log Recipe"
        },
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/small_log_to_log",
          text: "Log from Small Logs Recipe"
        },
        {
          link: "sap_bucket",
          image: "textures/tsu/nat/guidebook/recipes/sap_bucket",
          text: "Sap Bucket Recipe"
        },
        {
          link: "recipes",
          image: "textures/tsu/nat/guidebook/recipes/sugar",
          text: "Sugar Recipe"
        },
        {
          link: "wild_boar",
          image: "textures/tsu/nat/guidebook/recipes/smoked_gamey_meat",
          text: "Smoked Gamey Meat Recipe"
        },
        {
          link: "wild_boar",
          image: "textures/tsu/nat/guidebook/recipes/cooked_gamey_meat",
          text: "Cooked Gamey Meat Recipe"
        }
      ]
    },
    /* ----------------------------------- SINGLE ITEMS ----------------------------------- */
    curing: {
      title: "Curing",
      body: [
        "\xA7eTo create a salt curing station: ",
        "Lay a \xA7vBlock of Salt\xA7r down and surround it with blocks of salt on all sides except a front-facing window.",
        "(Bottom, top, both sides, and back.)",
        "",
        "Place \xA7vSmoked Gamey Meat\xA7r in the nieche of salt blocks you've just made.",
        "",
        "Wait a few minutes for it to become nutrient-dense \xA7vJerky\xA7r."
      ],
      buttons: [
        { link: "salt", image: "textures/tsu/nat/items/salt", text: "Salt" },
        {
          link: "wild_boar",
          image: "textures/tsu/nat/guidebook/icons/boar",
          text: "Wild Boar"
        }
      ]
    },
    ash: {
      title: "Ash",
      body: [
        "Ash gathers in thin layers on top of the ground. Break these blocks to obtain Ash which can be used in \xA7vSoap\xA7r and \xA7vGunpowder\xA7r recipes."
      ],
      buttons: [
        { link: "soap", image: "textures/tsu/nat/items/soap", text: "Soap" },
        { link: "gunpowder", image: "textures/items/gunpowder", text: "Gunpowder" }
      ]
    },
    rope: {
      title: "Rope",
      body: [
        "Place the rope block on the edge of a surface or ledge. This creates the main \xA7eknot\xA7r. Interact with the knot while holding more rope to grow it downward. You can keep adding rope until it reaches the ground.",
        "",
        "You can now climb the rope up and down freely by holding the \xA7e[jump]\xA7r key.",
        "",
        "When you're done, shoot the main knot with an arrow to break and drop the entire rope!",
        "",
        "\xA76Recipe:",
        "3 Leads arranged vertically"
      ],
      buttons: [{ link: "cattail", image: "textures/tsu/nat/items/cattail", text: "Cattail" }]
    },
    cattail: {
      title: "Cattail",
      body: [
        "Found where deserts meet rivers, and thriving in swamps and mangroves, cattails are hardy wetland plants that grow best in mud and farmland, though they can be farmed on most blocks.",
        "",
        "When fully grown, they produce fresh cattail pods which can be crafted into \xA7vseeds\xA7r or combined to make \xA7vstring\xA7r.",
        "",
        "\xA76Recipe:",
        "Cattail in a 2x2 pattern = 1 string."
      ],
      buttons: [{ link: "rope", image: "textures/tsu/nat/items/rope", text: "Rope" }]
    },
    soap: {
      title: "Soap",
      body: [
        "Unlike drinking milk - washing with soap will cleanse away only negative effects.",
        "",
        "\xA76Recipe:",
        "Aloe",
        "Ash",
        "Raw Sap"
      ]
    },
    gunpowder: {
      title: "Gunpowder",
      body: [
        "Now you can make \xA7vgunpowder\xA7r without waiting to encounter creepers.",
        "And with gunpowder, you can make TNT!",
        "",
        "\xA76Recipe:",
        "Niter",
        "Ash",
        "Coal",
        "Salt"
      ]
    },
    wild_yeast: {
      title: "Wild Yeast",
      body: [
        "This useful ingredient is required to craft many brews and functional fermented drinks.",
        "Harvest Wild Yeast in the Fungal Grove by hunting the glowing \xA7vFungus Gnats\xA7r that inhabit this biome."
      ],
      buttons: [
        {
          link: "fungus_gnat",
          image: "textures/tsu/nat/guidebook/icons/firefly",
          text: "Fungus Gnat"
        }
      ]
    },
    mandrake_root: {
      title: "Mandrake Root",
      body: [
        "This magical root can only be harvested in a \xA7vFungal Grove\xA7r on a full moon night (so don't try to harvest at any other time). Locate the pale blue, leafy plant and harvest on a full moon to reveal a living mandrake spirit.",
        "Chase it and strike fast to obtain a craftable \xA7vMandrake Root\xA7r to use in the magical \xA7vRoot Brew.\xA7r"
      ],
      buttons: [
        {
          link: "root_brew",
          image: "textures/tsu/nat/items/root_brew",
          text: "Root Brew"
        }
      ]
    },
    kefir: {
      title: "Yoghurt",
      body: [
        "This fermented milk beverage is a healthy food that offers benefits to hunger.",
        "",
        "\xA76Recipe:",
        "Wild Yeast x4",
        "Bucket of Milk",
        "Wooden Bowl"
      ],
      buttons: [
        {
          link: "wild_yeast",
          image: "textures/tsu/nat/items/wild_yeast",
          text: "Wild Yeast"
        }
      ]
    },
    kvass: {
      title: "Beetroot Soda",
      body: [
        "This fermented beet juice beverage is a healthy food that offers benefits to hunger.",
        "",
        "\xA76Recipe:",
        "Wild Yeast",
        "Beetroot",
        "Bread",
        "Wooden Bowl"
      ],
      buttons: [
        {
          link: "wild_yeast",
          image: "textures/tsu/nat/items/wild_yeast",
          text: "Wild Yeast"
        }
      ]
    },
    kombucha: {
      title: "Mushroom Brew",
      body: [
        "This fermented mushroom brew is a healthy food that offers benefits to hunger.",
        "",
        "\xA76Recipe:",
        "Wild Yeast",
        "Glowshroom",
        "Wooden Bowl"
      ],
      buttons: [
        {
          link: "wild_yeast",
          image: "textures/tsu/nat/items/wild_yeast",
          text: "Wild Yeast"
        }
      ]
    },
    root_brew: {
      title: "Root Brew",
      body: [
        "This fermented herbal root beverage is a healthy food that offers healing, speed, and benefits to hunger.",
        "",
        "\xA76Recipe:",
        "Wild Yeast",
        "Mandrake Root",
        "Wooden Bowl"
      ],
      buttons: [
        {
          link: "wild_yeast",
          image: "textures/tsu/nat/items/wild_yeast",
          text: "Wild Yeast"
        },
        {
          link: "mandrake_root",
          image: "textures/tsu/nat/items/mandrake_root",
          text: "Mandrake Root"
        }
      ]
    },
    fungus_gnat: {
      title: "Fungus Gnat",
      body: [
        "Fungus Gnat's can be found hovering around the \xA7vFungal Grove\xA7r.They glow like a firefly but are larger. If you hit one, it will drop \xA7vWild Yeast."
      ],
      buttons: [
        {
          link: "wild_yeast",
          image: "textures/tsu/nat/items/wild_yeast",
          text: "Wild Yeast"
        }
      ]
    },
    blooshroom: {
      title: "Blooshroom",
      body: [
        "A blue mooshroom with  \xA7vglowshrooms\xA7r growing on its back. Blooshrooms work similarly to mooshrooms.",
        "",
        "Feed it a \xA7vGlowshrooom\xA7r then milk it with a bowl to get \xA7vMushroom Brew\xA7r instantly. After that, milking a blooshroom will produce \xA7vMushroom Stew\xA7r until you feed it another Glowshroom.",
        "You can also shear the mooshroom to get the glowshrooms, but it will turn into a regular cow.",
        "Can be bred with \xA7vSporepuff."
      ],
      buttons: [
        {
          link: "kombucha",
          image: "textures/tsu/nat/items/kombucha",
          text: "Mushroom Brew"
        }
      ]
    },
    wild_boar: {
      title: "Wild Boar",
      body: [
        "Wild Boar roam freely around the Fungal Grove and drop \xA7vGamey Meat\xA7r.",
        "",
        "Gamey Meat can be prepared in several ways:",
        "\xA7vCooked Gamey\xA7r Meat is made in a Furnace.",
        "\xA7vSmoked Gamey\xA7r Meat is made in a Smoker.",
        "\xA7vJerky\xA7r is made from placing Smoked Gamey Meat on a salt block surrounded by salt blocks on all but 1 side.Wait for it to cure into Jerky: a dense and filling food."
      ]
    },
    raw_sap: {
      title: "Raw Sap",
      body: [
        "Maple trees slowly ooze sweet \xA7vsap\xA7r.",
        "Craft a \xA7vSap Bucket\xA7r, attach it to an",
        "\xA7voozing maple log\xA7r, then wait patiently. Later,",
        "use a bottle to gather the sap - ",
        "a valuable crafting ingredient to make",
        "Soap, Maple Syrup, and derivatives like Pancake and sugar."
      ],
      buttons: [
        {
          link: "sap_bucket",
          image: "textures/tsu/nat/guidebook/icons/sap_bucket",
          text: "Sap Bucket"
        }
      ]
    },
    sap_bucket: {
      title: "Sap Bucket",
      body: [
        "Craft a \xA7vSap Bucket\xA7r, attach it to an",
        "\xA7voozing maple log\xA7r, then wait patiently. Later,",
        "use 3 bottles to gather all the sap - ",
        "a valuable crafting ingredient.",
        "",
        "\xA76Recipe:",
        "Wooden Plank x5",
        "Stick x2",
        "Iron Ingot"
      ],
      buttons: [
        {
          link: "raw_sap",
          image: "textures/tsu/nat/items/raw_sap",
          text: "Raw Sap"
        }
      ]
    },
    maple_syrup: {
      title: "Maple Syrup",
      body: [
        "Sweet Maple Syrup is one of nature's sugary treats.",
        "You can drink it as a food or use it as an ingredient or cook it in a furnace gurther to make \xA7vSugar\xA7r.",
        "",
        "\xA76Recipe:",
        "In Furnace - 1 bottle of \xA7rRaw Sap"
      ],
      buttons: [
        {
          link: "raw_sap",
          image: "textures/tsu/nat/items/raw_sap",
          text: "Raw Sap"
        }
      ]
    },
    pancake: {
      title: "Pancake",
      body: [
        "Fluffy pancake smothered in sweet \xA7vMaple Syrup\xA7r are delicious food to stave off hunger.",
        "",
        "\xA76Recipe:",
        "Wheat",
        "Egg",
        "Maple Syrup"
      ],
      buttons: [
        {
          link: "maple_syrup",
          image: "textures/tsu/nat/items/maple_syrup",
          text: "Maple Syrup"
        }
      ]
    },
    sap_slimes: {
      title: "Sap Slimes",
      body: [
        "Sap Slimes are gelatinous cubes that are attracted to the scent of \xA7vraw maple sap\xA7r.",
        "",
        "\xA76Drops:",
        "Resin Clump"
      ],
      buttons: [
        {
          link: "raw_sap",
          image: "textures/tsu/nat/items/raw_sap",
          text: "Raw Sap"
        }
      ]
    },
    salt: {
      title: "Salt",
      body: [
        "Salt can be found in \xA7vSalt Flats\xA7r:",
        "The bright white salt regions found in some deserts.",
        "",
        "Break salt to gather it, or craft blocks to build and store. Salt can",
        "also be smelted into \xA7vNiter\xA7r, used to create valuable \xA7vGunpowder\xA7r.",
        "",
        "\xA7vSalt Block recipe:",
        "4 Salt"
      ],
      buttons: [
        {
          link: "niter",
          image: "textures/tsu/nat/items/niter",
          text: "Niter"
        },
        {
          link: "gunpowder",
          image: "textures/items/gunpowder",
          text: "Gunpowder"
        }
      ]
    },
    niter: {
      title: "Niter",
      body: [
        "Now you can make Gunpowder without waiting to encounter Creepers.",
        "And with Gunpowder, you can make TNT!",
        "",
        "\xA76Recipe:",
        "Smelt a Block of Salt in a Furnace"
      ],
      buttons: [
        {
          link: "gunpowder",
          image: "textures/items/gunpowder",
          text: "Gunpowder"
        }
      ]
    },
    aloe: {
      title: "Aloe",
      body: [
        "Aloe Vera is a medicinal plant that is good for the skin. Aloe plants can be found in deserts. Break to harvest the green leaf.",
        "Aloe is a key ingredient in \xA7vsoap."
      ],
      button: [{ link: "soap", image: "textures/tsu/nat/items/soap", text: "Soap" }]
    },
    tumbleweed: {
      title: "Tumbleweed",
      body: [
        "Tubleweeds blow around the deserts",
        "as if to punctuate the lonely, arid landscape."
      ]
    },
    scarecrow: {
      title: "Scarecrow",
      body: [
        "Scarecrows can be found in abandoned farms scattered around the world.",
        "Or you can make your own.",
        "",
        "Recipe: Carved Pumpkin, Hay Bale, 3x Sticks = 1 Scarecrow"
      ]
    },
    /* -------------------------------------- EXTRAS -------------------------------------- */
    extras: {
      title: "Structures",
      body: [
        "\xA7vNot all discoveries are bound to a single biome - some features can appear elsewhere in the world, bringing surprises and rewards.",
        "",
        "Each of these features offers unique materials, challenges, or opportunities.",
        "Keep your eyes open while exploring!",
        "\xA7v--------------------------------",
        "",
        "\xA7v- Giant Trees \xA7s[taigas]",
        "\xA7v- Palm Trees \xA7s[beaches, deserts]",
        "\xA7v- Oasis \xA7s[desert]",
        "\xA7v- Baobab Trees \xA7s[savanna]",
        "\xA7v- Hedge Maze \xA7s[plains, savanna]",
        "\xA7v- Wells \xA7s[plains, savanna,desert]",
        "\xA7v- Ruins \xA7s[plains, savanna]",
        "\xA7v- Windmills \xA7s[plains]",
        "\xA7v- Lighhouses \xA7s[cold and rocky beaches]",
        "\xA7v- Great Pyramids \xA7s[desert]",
        "\xA7v- Obelisks \xA7s[desert]",
        "\xA7v- Abandoned Farms \xA7s[plains]"
      ],
      buttons: []
    },
    /* --------------------------------------- META --------------------------------------- */
    info: {
      title: "Info",
      body: ["Need help or want to know more?"],
      buttons: [
        { text: "Patch Notes", link: "patch_notes" },
        { text: "Support", link: "support" },
        { text: "Credits", link: "credits" }
      ]
    },
    patch_notes: {
      title: "Patch Notes",
      body: [
        "\xA7v--------------------------------",
        "Current version: \xA7v1.0.0",
        "\xA7v--------------------------------",
        "Upcoming: \xA7v1.1.0",
        "\xA7d- Fields that hum with violet wind.",
        "\xA7b- A glacier where silence itself sleeps.",
        "\xA7v- A rift that shimmers between worlds.",
        "\xA7a- A forest trapped in eternal twilight.",
        "",
        "\xA76- Beneath the roots, treasures await those who dig... or snout around.",
        "\xA7c- In the ashes, they march - fire given legs.",
        "\xA7g- The earth beneath the maples is alive. Richer, darker, as if it remembers what once grew there.",
        "\xA7u- An uncanny acquaintance fond of shiny things.",
        "\xA7s- Echoes of forgotten places, waiting to be found.",
        "",
        "\xA7vAnd more to come...",
        "+ Your suggestions!",
        "\xA7v--------------------------------",
        "Join the Discord server and let us know what you want to see in the next update!",
        "Be the first to know what we are planning next!",
        "\xA7v[ discord.gg/\xA7buEHtjtNQ5T\xA7v ]",
        "\xA7v--------------------------------"
      ]
    },
    support: {
      title: "Support",
      body: [
        "Want to report a \xA7ebug\xA7r or give us some \xA7efeedback\xA7r?",
        " ",
        "\xA76Join the Add-On's Discord server and talk to the developers:",
        " ",
        "\xA7b[ discord.gg/uEHtjtNQ5T ]",
        " ",
        " "
      ]
    },
    credits: {
      title: "Credits",
      body: [
        "\xA73================================",
        "\xA7b              Tsunami Studios",
        "\xA73================================",
        "",
        "\xA7lVision & Direction",
        shuffle(["\xA7vAngelo", "\xA7vRose"]).join("\n"),
        "\xA7v--------------------------------",
        "\xA7lDevelopment",
        "\xA7vAngelo",
        "\xA7v--------------------------------",
        "\xA7lArt",
        "\xA7vRose",
        "\xA7vAngelo",
        "\xA7vArthur",
        "\xA7v--------------------------------",
        "\xA7lQuality Assurance",
        shuffle(["\xA7vEruch", "\xA7vTrevor", "\xA7vAva"]).join("\n"),
        "\xA7v--------------------------------",
        "\xA7lMarketing",
        "\xA7vPiero",
        "\xA7v--------------------------------",
        "\xA7lSpecial Thanks",
        "\xA7vMerwan",
        "\xA7vPrzemyslaw",
        "\xA7vMarcin",
        "\xA7v--------------------------------"
      ]
    }
  }
});
world2.afterEvents.itemUse.subscribe((data) => {
  const player = data.source;
  if (data.itemStack.typeId === "tsu_nat:guidebook") {
    guidebook.showPage(player, "start");
  }
});
function shuffle(array) {
  const newArray = [...array];
  let currentIndex = newArray.length;
  while (currentIndex != 0) {
    let randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;
    [newArray[currentIndex], newArray[randomIndex]] = [
      newArray[randomIndex],
      newArray[currentIndex]
    ];
  }
  return newArray;
}

// packs/data/modular_mc/wellcome_system/wellcome.js
import { world as world3 } from "@minecraft/server";
world3.afterEvents.playerSpawn.subscribe((event) => {
  if (event.initialSpawn) {
    if (!event.player.getDynamicProperty("tsu_nat:joined_server")) {
      event.player.runCommand("give @s tsu_nat:guidebook");
      event.player.setDynamicProperty("tsu_nat:joined_server", true);
    }
    const joinMessage = { translate: "tsu_nat.wellcome_message" };
    event.player.sendMessage(joinMessage);
  }
});

// packs/data/modular_mc/world_content/global/gamey_meat/cureTimer.ts
import {
  system as system5
} from "@minecraft/server";
var component4 = {
  onRandomTick(event, parameters) {
    if (event.block.isWaterlogged) return;
    if (event.block.permutation.getState(parameters.params.cured_state) === true) return;
    const chance = parameters.params?.chance ?? 1;
    if (Math.random() > chance) return;
    const hasSaltAbove = event.block.above()?.typeId === "tsu_nat:salt_block";
    if (!hasSaltAbove) return;
    const surroundedBySalt = hasNeighbors(event.block, "tsu_nat:salt_block") >= 5;
    if (!surroundedBySalt) return;
    event.block.setPermutation(
      event.block.permutation.withState(parameters.params.cured_state, true)
    );
  }
};
system5.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:cure_timer", component4);
});
function hasNeighbors(block, neighborId) {
  const neighbors = [
    block.above()?.typeId === neighborId,
    block.below()?.typeId === neighborId,
    block.north()?.typeId === neighborId,
    block.south()?.typeId === neighborId,
    block.east()?.typeId === neighborId,
    block.west()?.typeId === neighborId
  ];
  return neighbors.filter((neighbor) => neighbor).length;
}

// packs/data/modular_mc/world_content/new_biomes/charred_forest/ash_block/ash.ts
import {
  system as system6
} from "@minecraft/server";
var component5 = {
  onRandomTick(event, params) {
    const aboveBlock = event.block.above();
    if (aboveBlock && aboveBlock.typeId === "minecraft:snow_layer") {
      aboveBlock.setType("minecraft:air");
    }
  },
  onPlayerInteract: (event, params) => {
    const player = event.player;
    if (!player) return;
    const container = player.getComponent("minecraft:inventory")?.container;
    const heldSlot = container?.getSlot(player.selectedSlotIndex);
    if (!heldSlot?.hasItem() || !heldSlot || !heldSlot.isValid) return;
    const shouldLayer = event.block.typeId === heldSlot?.typeId;
    if (!shouldLayer) return;
    const currentLayerAmount = Number(event.block.permutation.getState("tsu_nat:height") ?? 0);
    const newLayerAmount = Math.max(0, Math.min(15, currentLayerAmount + 1));
    if (newLayerAmount > currentLayerAmount) {
      heldSlot.amount === 1 ? heldSlot.setItem() : heldSlot.amount -= 1;
      if (newLayerAmount <= 6) {
        event.block.setPermutation(
          event.block.permutation.withState("tsu_nat:height", newLayerAmount)
        );
      } else {
        event.block.setType(params.params.full_block);
      }
    }
  }
};
system6.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:layered", component5);
});

// packs/data/modular_mc/world_content/new_biomes/fungal_grove/mandrake/block/mandrakeRootComponent.js
import { world as world4, system as system7 } from "@minecraft/server";
var component6 = {
  onPlayerBreak(event, { params }) {
    const isDay = world4.getTimeOfDay() < 12e3;
    const isFullMoon = world4.getMoonPhase() === 0;
    if (!isDay && isFullMoon) {
      event.dimension.spawnEntity(params.type, event.block.center());
    }
  }
};
system7.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent(
    "tsu_nat:turn_to_entity_at_night",
    component6
  );
});

// packs/data/modular_mc/world_content/new_biomes/maple_forest/sap_bucket/sapBucket.ts
import {
  system as system8,
  ItemStack
} from "@minecraft/server";
var component7 = {
  onRandomTick(event, data) {
    event.block.dimension.playSound("cauldron_drip.water.pointed_dripstone", event.block.location);
    const params = data.params;
    const fillChance = params.fill_chance;
    const depletionChance = params.depletion_chance;
    const maxFill = params.max_state_value;
    const currentFill = event.block.permutation.getState(params.state);
    const neighbor = oozingNeighbor(event.block);
    if (!neighbor) return;
    if (currentFill >= maxFill) return;
    if (Math.random() < fillChance) {
      event.block.setPermutation(
        event.block.permutation.withState("tsu_nat:filled_level", currentFill + 1)
      );
      if (Math.random() < depletionChance) {
        neighbor.setType("tsu_nat:maple_log");
        neighbor.setPermutation(neighbor.permutation.withState("minecraft:block_face", "down"));
      }
    }
  },
  onPlayerInteract(event, data) {
    const player = event.player;
    if (!player) return;
    const inventory = player.getComponent("minecraft:inventory")?.container;
    const handSlot = inventory?.getSlot(player.selectedSlotIndex);
    if (!handSlot || !handSlot.hasItem()) return;
    if (handSlot.typeId !== "minecraft:glass_bottle") return;
    const params = data.params;
    const currentFill = event.block.permutation.getState(params.state);
    if (currentFill <= 0) return;
    event.block.setPermutation(
      event.block.permutation.withState(params.state, currentFill - 1)
    );
    if (handSlot.amount === 1) {
      handSlot.setItem();
    } else {
      handSlot.amount -= 1;
    }
    if (inventory?.emptySlotsCount) {
      inventory?.addItem(new ItemStack("tsu_nat:raw_sap", 1));
    } else {
      player.dimension.spawnItem(new ItemStack("tsu_nat:raw_sap", 1), event.block.center());
    }
    player.playSound("bottle.fill");
  }
};
system8.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:sap_bucket", component7);
});
function oozingNeighbor(block) {
  const opposites = {
    north: "south",
    south: "north",
    east: "west",
    west: "east"
  };
  const placedOnFace = block.permutation.getState("minecraft:block_face") ?? "south";
  const facingDirection = opposites[placedOnFace];
  const neighborBlock = block[facingDirection]?.();
  if (neighborBlock?.typeId === "tsu_nat:oozing_maple_log") {
    return neighborBlock;
  } else {
    return false;
  }
}

// packs/data/modular_mc/world_content/new_biomes/oasis/rope/rope.ts
import {
  system as system9,
  EquipmentSlot as EquipmentSlot2
} from "@minecraft/server";
var component8 = {
  onPlayerInteract(event) {
    const equippable = event.player?.getComponent("minecraft:equippable");
    const mainhand = equippable?.getEquipmentSlot(EquipmentSlot2.Mainhand);
    if (!mainhand?.hasItem()) return;
    if (mainhand?.typeId !== "tsu_nat:rope") return;
    let bottomFreeBlock = event.block.below();
    while (bottomFreeBlock?.typeId === "tsu_nat:rope") {
      bottomFreeBlock = bottomFreeBlock.below();
    }
    if (bottomFreeBlock?.isAir || bottomFreeBlock?.isLiquid) {
      bottomFreeBlock.setPermutation(
        event.block.permutation.withState("tsu_nat:rope_section", "rope")
      );
      if (mainhand.amount > 1) {
        mainhand.amount--;
      } else {
        mainhand.setItem();
      }
    }
  },
  onStepOn(event) {
    if (event.entity?.typeId === "minecraft:arrow") {
      event.dimension.runCommand(
        `setblock ${event.block.x} ${event.block.y} ${event.block.z} air destroy`
      );
    }
  }
};
system9.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:rope", component8);
});

// packs/data/modular_mc/world_content/templated_blocks/basic_plant_template/growingPlant.ts
import {
  EquipmentSlot as EquipmentSlot3,
  GameMode as GameMode2,
  system as system10
} from "@minecraft/server";
var component9 = {
  onRandomTick(event, data) {
    const params = data.params;
    if (Math.random() < params.random_growth_chance) {
      event.block.setType(params.grows_into);
    }
  },
  onPlayerInteract(event, data) {
    const params = data.params;
    const block = event.block;
    const dimension = event.dimension;
    const player = event.player;
    if (!player) return;
    const equippable = player.getComponent("minecraft:equippable");
    if (!equippable) return;
    const mainhand = equippable.getEquipmentSlot(EquipmentSlot3.Mainhand);
    const growthItem = params.growth_item ?? "minecraft:bonemeal";
    const hasGrowthItem = mainhand.hasItem() && mainhand.typeId === growthItem;
    if (!hasGrowthItem) return;
    block.setType(params.grows_into);
    if (player.getGameMode() !== GameMode2.Creative) {
      if (mainhand.amount > 1) mainhand.amount--;
      else mainhand.setItem(void 0);
    }
    const effectLocation = block.center();
    dimension.playSound("item.bone_meal.use", effectLocation);
    dimension.spawnParticle("minecraft:crop_growth_emitter", effectLocation);
  }
};
system10.beforeEvents.startup.subscribe(({ blockComponentRegistry }) => {
  blockComponentRegistry.registerCustomComponent("tsu_nat:plant", component9);
});

// packs/data/modular_mc/world_content/templated_blocks/door_template/door.ts
import {
  world as world6,
  system as system11,
  BlockPermutation,
  ItemStack as ItemStack2
} from "@minecraft/server";
var directionOrder = ["north", "west", "south", "east"];
var doorTypes = ["tsu_nat:maple_door", "tsu_nat:charred_door"];
var customDoor = {
  onTick({ block, dimension }, { params }) {
    let power = block.getRedstonePower();
    let topHalf = isTopHalf(block.permutation);
    let otherDoorBlock = topHalf ? block.below() : block.above();
    const currentState = block.permutation.getAllStates();
    if (power > 0 && !currentState["tsu_nat:powered"]) {
      block.setPermutation(
        block.permutation.withState("tsu_nat:powered", true)
      );
      otherDoorBlock.setPermutation(
        otherDoorBlock.permutation.withState("tsu_nat:powered", true)
      );
      openDoor(block, dimension, true);
    }
    let otherBlockPower = otherDoorBlock.getRedstonePower();
    let unpoweredDoor = (power == 0 || power == void 0) && (otherBlockPower == 0 || otherBlockPower == void 0);
    if (unpoweredDoor && currentState["tsu_nat:powered"]) {
      block.setPermutation(
        block.permutation.withState("tsu_nat:powered", false)
      );
      otherDoorBlock.setPermutation(
        otherDoorBlock.permutation.withState("tsu_nat:powered", false)
      );
      openDoor(block, dimension, false, true);
    }
  },
  beforeOnPlayerPlace: (event) => {
    let above = event.block.above()?.typeId;
    if (above !== "minecraft:air") {
      event.cancel = true;
    }
  },
  onPlace(event) {
    const currentStates = event.block.permutation.getAllStates();
    const cardinalDirection = currentStates["minecraft:cardinal_direction"];
    let directionIndex = directionOrder.indexOf(cardinalDirection);
    const blocksAround = [
      event.block.north(),
      event.block.west(),
      event.block.south(),
      event.block.east()
    ];
    let above = event.block.above();
    let topHalf = isTopHalf(event.block.permutation);
    if (above?.typeId !== "minecraft:air" || topHalf) {
      return;
    }
    let flipHinge = false;
    let blockToCheck = blocksAround[(directionIndex + 1) % 4];
    if (doorTypes.includes(blockToCheck?.typeId)) {
      flipHinge = getCardinalDirection(event.block) == getCardinalDirection(blockToCheck);
    }
    const aboveBlockPermutation = BlockPermutation.resolve(event.block.typeId, {
      "tsu_nat:block_half": "top",
      "minecraft:cardinal_direction": cardinalDirection,
      "tsu_nat:door_hinge_bit": flipHinge
    });
    above.setPermutation(aboveBlockPermutation);
    if (flipHinge) {
      event.block.setPermutation(
        event.block.permutation.withState("tsu_nat:door_hinge_bit", true)
      );
    }
  },
  onPlayerInteract({ block, dimension }, { params }) {
    openDoor(block, dimension);
  }
};
function openDoor(block, dimension, forceOpen = false, forceClose = false) {
  const toggleableState = "tsu_nat:open";
  let topHalf = isTopHalf(block.permutation);
  let otherDoorBlock = topHalf ? block.below() : block.above();
  const currentValue = block.permutation.getState(toggleableState);
  let toggledValue = !currentValue;
  if (forceOpen) toggledValue = true;
  if (forceClose) toggledValue = false;
  block.setPermutation(block.permutation.withState(toggleableState, toggledValue));
  otherDoorBlock.setPermutation(
    otherDoorBlock.permutation.withState(toggleableState, toggledValue)
  );
  const toggleSound = toggledValue ? "open.wooden_trapdoor" : "close.wooden_trapdoor";
  dimension.playSound(toggleSound, block.center());
}
world6.afterEvents.playerBreakBlock.subscribe((eventData) => {
  const { block, dimension, brokenBlockPermutation } = eventData;
  const topHalf = isTopHalf(brokenBlockPermutation);
  const aboveBlock = block.above();
  const aboveAboveBlock = block.above()?.above();
  const belowBlock = block.below();
  if (doorTypes.includes(brokenBlockPermutation.type.id)) {
    if (topHalf && doorTypes.includes(belowBlock?.typeId)) {
      dimension.runCommand(`setblock ${belowBlock.x} ${belowBlock.y} ${belowBlock.z} air destroy`);
    } else if (!topHalf && doorTypes.includes(aboveBlock?.typeId)) {
      dimension.runCommand(`setblock ${aboveBlock.x} ${aboveBlock.y} ${aboveBlock.z} air destroy`);
    }
  } else {
    if (doorTypes.includes(aboveBlock?.typeId) && !isTopHalf(aboveBlock.permutation)) {
      let item = new ItemStack2(`${aboveBlock?.typeId}`, 1);
      dimension.spawnItem(item, aboveBlock.center());
      dimension.runCommand(`setblock ${aboveBlock.x} ${aboveBlock.y} ${aboveBlock.z} air destroy`);
    }
    if (doorTypes.includes(aboveAboveBlock?.typeId) && isTopHalf(aboveAboveBlock?.permutation)) {
      dimension.runCommand(
        `setblock ${aboveAboveBlock.x} ${aboveAboveBlock.y} ${aboveAboveBlock.z} air destroy`
      );
    }
  }
});
function isTopHalf(blockPermutation) {
  return blockPermutation.getState("tsu_nat:block_half") == "top";
}
function getCardinalDirection(block) {
  const dir = block?.permutation?.getState("minecraft:cardinal_direction");
  return typeof dir === "string" ? dir : void 0;
}
system11.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:custom_door", customDoor);
});

// packs/data/modular_mc/world_content/templated_blocks/fence_template/fence.ts
import { world as world7 } from "@minecraft/server";
world7.afterEvents.playerPlaceBlock.subscribe((event) => {
  if (!event.block.typeId.endsWith("_fence")) return;
  const blocksToAffect = [
    event.block,
    event.block.north(),
    event.block.south(),
    event.block.east(),
    event.block.west()
  ];
  blocksToAffect.forEach((b) => {
    if (!b) return;
    try {
      const finalPermutation = getFencePermutation(b);
      if (finalPermutation) {
        b.setPermutation(finalPermutation);
      }
    } catch (error) {
      return;
    }
  });
});
world7.afterEvents.playerBreakBlock.subscribe((event) => {
  const blocksToAffect = [event.block.north(), event.block.south(), event.block.east(), event.block.west()];
  blocksToAffect.forEach((b) => {
    if (!b) return;
    try {
      const finalPermutation = getFencePermutation(b);
      if (finalPermutation) {
        b.setPermutation(finalPermutation);
      }
    } catch (error) {
      return;
    }
  });
});
function fenceCanConnect(block) {
  if (!block) return false;
  return block.typeId.endsWith("_fence") || block.typeId.endsWith("_fence_gate");
}
function getConnections(block) {
  const north = fenceCanConnect(block.north());
  const south = fenceCanConnect(block.south());
  const east = fenceCanConnect(block.east());
  const west = fenceCanConnect(block.west());
  return {
    north,
    south,
    east,
    west
  };
}
function getFencePermutation(centerBlock) {
  const connections = getConnections(centerBlock);
  return centerBlock.permutation.withState("tsu_nat:connects_north", connections.north).withState("tsu_nat:connects_south", connections.south).withState("tsu_nat:connects_east", connections.east).withState("tsu_nat:connects_west", connections.west);
}

// packs/data/modular_mc/world_content/templated_blocks/grass_block_template/grass_block.ts
import {
  system as system12,
  LiquidType
} from "@minecraft/server";
var component10 = {
  onRandomTick(event, parameters) {
    const dirtBlock = parameters.params?.dirt_block;
    if (!dirtBlock) return;
    const aboveBlock = event.block.above();
    if (!aboveBlock || aboveBlock.isAir || aboveBlock.canBeDestroyedByLiquidSpread(LiquidType.Water) || aboveBlock.liquidSpreadCausesSpawn(LiquidType.Water) || aboveBlock.canContainLiquid(LiquidType.Water) || !aboveBlock.isLiquidBlocking(LiquidType.Water)) {
      return;
    }
    event.block.setType(dirtBlock);
  }
};
system12.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:custom_grass_block", component10);
});

// packs/data/modular_mc/world_content/templated_blocks/leaf_litter_template/leaf_litter.ts
import {
  system as system13
} from "@minecraft/server";
var leafLitter = {
  onRandomTick(event, parameters) {
    const aboveBlock = event.block.above();
    if (aboveBlock && aboveBlock.typeId === "minecraft:snow_layer") {
      aboveBlock.setType("minecraft:air");
    }
  },
  onPlayerInteract: (event, params) => {
    const player = event.player;
    if (!player) return;
    const container = player.getComponent("minecraft:inventory")?.container;
    const heldSlot = container?.getSlot(player.selectedSlotIndex);
    if (!heldSlot?.hasItem() || !heldSlot || !heldSlot.isValid || heldSlot.typeId !== event.block.typeId) {
      return;
    }
    const currentLitterAmount = Number(
      event.block.permutation.getState("tsu_nat:litter_amount") ?? 0
    );
    const newLitterAmount = Math.max(0, Math.min(3, currentLitterAmount + 1));
    if (newLitterAmount > currentLitterAmount) {
      heldSlot.amount === 1 ? heldSlot.setItem() : heldSlot.amount -= 1;
      event.block.setPermutation(
        event.block.permutation.withState("tsu_nat:litter_amount", newLitterAmount)
      );
    }
  }
};
system13.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:leaf_litter", leafLitter);
});

// packs/data/modular_mc/world_content/templated_blocks/leaves_template/leaves.ts
import {
  system as system14
} from "@minecraft/server";
var customLeaves = {
  beforeOnPlayerPlace: (event, params) => {
    event.permutationToPlace = event.permutationToPlace.withState("tsu_nat:decay", false);
  },
  onRandomTick(event, params) {
    try {
      event.block.dimension.spawnParticle(params.params.particle, event.block.location);
    } catch (error) {
      return;
    }
    if (event.block.permutation.getState("tsu_nat:decay") === false) return;
    if (shouldDecay(event.block)) {
      event.block.dimension.runCommand(
        `setblock ${event.block.x} ${event.block.y} ${event.block.z} minecraft:air destroy`
      );
    }
  }
};
system14.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:custom_leaves", customLeaves);
});
function shouldDecay(startBlock, maxDistance = 10) {
  if (isLog(startBlock)) return false;
  const visited = /* @__PURE__ */ new Set();
  const queue = [startBlock];
  const distances = /* @__PURE__ */ new Map();
  const getKey = (x, y, z) => {
    return (x + 1e3) * 4e6 + (y + 1e3) * 2e3 + (z + 1e3);
  };
  const startKey = getKey(startBlock.x, startBlock.y, startBlock.z);
  visited.add(startKey);
  distances.set(startKey, 0);
  let queueIndex = 0;
  while (queueIndex < queue.length) {
    const block = queue[queueIndex++];
    const key = getKey(block.x, block.y, block.z);
    const distance = distances.get(key);
    if (distance >= maxDistance) continue;
    const canTraverse = isLeaf(block) || key === startKey;
    if (!canTraverse) continue;
    const neighbors = [
      block.above(),
      block.below(),
      block.east(),
      block.west(),
      block.north(),
      block.south()
    ];
    const nextDistance = distance + 1;
    for (let i = 0; i < 6; i++) {
      const neighbor = neighbors[i];
      if (!neighbor) continue;
      const neighborKey = getKey(neighbor.x, neighbor.y, neighbor.z);
      if (visited.has(neighborKey)) continue;
      if (isLog(neighbor)) return false;
      visited.add(neighborKey);
      distances.set(neighborKey, nextDistance);
      queue.push(neighbor);
    }
  }
  return true;
}
function isLog(block) {
  return block.typeId.includes("log") || block.typeId.includes("stem") || block.typeId.includes("wood");
}
function isLeaf(block) {
  return block.typeId.includes("leaves");
}

// packs/data/modular_mc/world_content/templated_blocks/log_template/log.ts
import { world as world8, system as system15 } from "@minecraft/server";
world8.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  if (!event.isFirstEvent) return;
  if (event.block.typeId.startsWith("tsu_nat:stripped") || !event.block.typeId.endsWith("_log") || !event.block.typeId.startsWith("tsu_nat:")) {
    return;
  }
  if (event.itemStack?.hasTag("minecraft:is_axe") || event.itemStack?.hasTag("minecraft:axe")) {
    const strippedId = toStrippedLog(event.block.typeId);
    const rotationState = event.block.permutation.getState("minecraft:block_face");
    system15.run(() => {
      try {
        event.block.setType(strippedId);
        event.block.setPermutation(
          event.block.permutation.withState("minecraft:block_face", rotationState)
        );
        event.block.dimension.playSound("use.wood", event.block.location);
      } catch (error) {
      }
    });
  }
});
function toStrippedLog(id) {
  if (!id.startsWith("tsu_nat:") || !id.endsWith("_log")) {
    return id;
  }
  const type = id.slice("tsu_nat:".length, -"_log".length);
  return `tsu_nat:stripped_${type}_log`;
}

// packs/data/modular_mc/world_content/templated_blocks/sapling_template/sapling.ts
import { system as system16, GameMode as GameMode3 } from "@minecraft/server";
var customSapling = {
  onRandomTick({ block, dimension }, { params }) {
    const lightLevel = block.getLightLevel();
    if (lightLevel < 9) return;
    if (Math.random() < params.grow_chance) {
      dimension.placeFeature("tsu_nat:tsu_nat_red_maple_tree.feature", block.location);
    }
  },
  onPlayerInteract({ block, dimension, player }, { params }) {
    if (!player) return;
    const equippable = player.getComponent("minecraft:equippable");
    if (!equippable) return;
    const mainhand = equippable.getEquipmentSlot("Mainhand");
    const hasBoneMeal = mainhand.hasItem() && mainhand.typeId === "minecraft:bone_meal";
    if (!hasBoneMeal) return;
    const growsInto = params.grows_into;
    if (!growsInto) return;
    const selectedFeature = growsInto[Math.floor(Math.random() * growsInto.length)];
    if (player.getGameMode() === GameMode3.Creative) {
      dimension.placeFeature(selectedFeature, block.location);
    } else {
      if (Math.random() < params.bonemeal_grow_chance) {
        dimension.placeFeature(selectedFeature, block.location);
        if (mainhand.amount > 1) {
          mainhand.amount--;
        } else {
          mainhand.setItem(void 0);
        }
      }
    }
    const effectLocation = block.center();
    dimension.playSound("item.bone_meal.use", effectLocation);
    dimension.spawnParticle("minecraft:crop_growth_emitter", effectLocation);
  }
};
system16.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:custom_sapling", customSapling);
});

// packs/data/modular_mc/world_content/templated_blocks/slab_template/slab.ts
import { Direction, world as world9, system as system17 } from "@minecraft/server";
world9.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  const { block, itemStack, blockFace, player } = event;
  if (!itemStack || !isCustomSlab(itemStack.typeId)) return;
  const convertToDoubleSlab = (targetBlock) => {
    const doubleSlabId = toDoubleSlab(targetBlock.typeId);
    event.cancel = true;
    system17.run(() => {
      targetBlock.setType(doubleSlabId);
      const container = player.getComponent("minecraft:inventory")?.container;
      if (container && player.selectedSlotIndex !== void 0) {
        const currentItem = container.getItem(player.selectedSlotIndex);
        if (currentItem && currentItem.amount > 1) {
          currentItem.amount -= 1;
          container.setItem(player.selectedSlotIndex, currentItem);
        } else {
          container.setItem(player.selectedSlotIndex, void 0);
        }
      }
    });
  };
  if (itemStack.typeId === block.typeId) {
    const slabState = block.permutation.getState("minecraft:vertical_half");
    const shouldConvert = slabState === "top" && blockFace === Direction.Down || slabState === "bottom" && blockFace === Direction.Up;
    if (shouldConvert) {
      convertToDoubleSlab(block);
      return;
    }
  }
  if (blockFace === Direction.Up) {
    const blockAbove = block.above();
    if (blockAbove && blockAbove.typeId === itemStack.typeId && blockAbove.permutation.getState("minecraft:vertical_half") === "top") {
      convertToDoubleSlab(blockAbove);
      return;
    }
  }
  if (blockFace === Direction.Down) {
    const blockBelow = block.below();
    if (blockBelow && blockBelow.typeId === itemStack.typeId && blockBelow.permutation.getState("minecraft:vertical_half") === "bottom") {
      convertToDoubleSlab(blockBelow);
      return;
    }
  }
});
function isCustomSlab(itemTypeId) {
  const customSlabPattern = /^tsu_nat:[a-zA-Z]+_slab$/;
  return customSlabPattern.test(itemTypeId);
}
function toDoubleSlab(slabType) {
  return slabType.replace(/slab/g, "double_slab");
}

// packs/data/modular_mc/world_content/templated_blocks/stairs_template/stairs.ts
import {
  system as system18
} from "@minecraft/server";
var customStairs = {
  beforeOnPlayerPlace: (event) => {
    const direction = event.permutationToPlace.getState("minecraft:cardinal_direction") ?? "north" /* North */;
    const pattern = cardinalToStairPattern(direction);
    event.permutationToPlace = event.permutationToPlace.withState("tsu_nat:stairs_pattern", pattern);
  },
  onPlace(event) {
    const blocksToAffect = [
      event.block,
      event.block.north(),
      event.block.south(),
      event.block.east(),
      event.block.west()
    ];
    blocksToAffect.forEach((block) => {
      if (!block) return;
      if (!block.typeId.includes("stairs")) return;
      const direction = getCardinalDirection2(block) ?? "north" /* North */;
      const initPattern = cardinalToStairPattern(direction);
      const finalPattern = determineStairPattern(block) || initPattern;
      const finalPermutation = block.permutation.withState("tsu_nat:stairs_pattern", finalPattern);
      block.setPermutation(finalPermutation);
    });
  },
  onPlayerBreak(event) {
    const blocksToAffect = [event.block.north(), event.block.south(), event.block.east(), event.block.west()];
    blocksToAffect.forEach((block) => {
      if (!block) return;
      if (!block.typeId.includes("stairs")) return;
      const direction = getCardinalDirection2(block) ?? "north" /* North */;
      const initPattern = cardinalToStairPattern(direction);
      const finalPattern = determineStairPattern(block) || initPattern;
      const finalPermutation = block.permutation.withState("tsu_nat:stairs_pattern", finalPattern);
      block.setPermutation(finalPermutation);
    });
  }
};
function getCardinalDirection2(block) {
  const dir = block?.permutation?.getState("minecraft:cardinal_direction");
  return typeof dir === "string" ? dir : void 0;
}
function getNeighborsCardinalDirections(block) {
  return {
    north: getCardinalDirection2(block.north()),
    south: getCardinalDirection2(block.south()),
    east: getCardinalDirection2(block.east()),
    west: getCardinalDirection2(block.west())
  };
}
function cardinalToStairPattern(cardinal) {
  switch (cardinal) {
    case "north" /* North */:
      return "1100";
    case "east" /* East */:
      return "0110";
    case "south" /* South */:
      return "0011";
    case "west" /* West */:
      return "1001";
    default:
      return "1100";
  }
}
function determineStairPattern(stairBlock) {
  const cardinalDirection = getCardinalDirection2(stairBlock);
  const neighbors = getNeighborsCardinalDirections(stairBlock);
  switch (cardinalDirection) {
    case "north" /* North */:
      if (neighbors.south === "west" /* West */) return "1101";
      if (neighbors.south === "east" /* East */) return "1110";
      if (neighbors.north === "west" /* West */) return "1000";
      if (neighbors.north === "east" /* East */) return "0100";
      return "1100";
    case "east" /* East */:
      if (neighbors.west === "south" /* South */) return "0111";
      if (neighbors.west === "north" /* North */) return "1110";
      if (neighbors.east === "south" /* South */) return "0010";
      if (neighbors.east === "north" /* North */) return "0100";
      return "0110";
    case "south" /* South */:
      if (neighbors.north === "east" /* East */) return "0111";
      if (neighbors.north === "west" /* West */) return "1011";
      if (neighbors.south === "east" /* East */) return "0010";
      if (neighbors.south === "west" /* West */) return "0001";
      return "0011";
    case "west" /* West */:
      if (neighbors.east === "north" /* North */) return "1101";
      if (neighbors.east === "south" /* South */) return "1011";
      if (neighbors.west === "north" /* North */) return "1000";
      if (neighbors.west === "south" /* South */) return "0001";
      return "1001";
    default:
      return void 0;
  }
}
system18.beforeEvents.startup.subscribe((init) => {
  init.blockComponentRegistry.registerCustomComponent("tsu_nat:custom_stairs", customStairs);
});

// packs/data/modular_mc/world_content/templated_blocks/trapdoor_template/trapdoor.ts
import { system as system19 } from "@minecraft/server";
var BlockToggleableComponent = {
  onTick({ block, dimension }, { params }) {
    let power = block.getRedstonePower();
    const currentState = block.permutation.getAllStates();
    if (power > 0 && !currentState["tsu_nat:powered"]) {
      block.setPermutation(
        block.permutation.withState("tsu_nat:powered", true)
      );
      openTrapdoor(block, dimension, true);
    }
    let unpoweredDoor = power == 0 || power == void 0;
    if (unpoweredDoor && currentState["tsu_nat:powered"]) {
      block.setPermutation(
        block.permutation.withState("tsu_nat:powered", false)
      );
      openTrapdoor(block, dimension, false, true);
    }
  },
  onPlayerInteract({ block, dimension }, { params }) {
    const toggleableState = "tsu_nat:open";
    const currentValue = block.permutation.getState(toggleableState);
    const toggledValue = !currentValue;
    block.setPermutation(block.permutation.withState(toggleableState, toggledValue));
    const toggleSound = toggledValue ? "open.wooden_trapdoor" : "close.wooden_trapdoor";
    dimension.playSound(toggleSound, block.center());
  }
};
system19.beforeEvents.startup.subscribe(({ blockComponentRegistry }) => {
  blockComponentRegistry.registerCustomComponent("tsu_nat:custom_trapdoor", BlockToggleableComponent);
});
function openTrapdoor(block, dimension, forceOpen = false, forceClose = false) {
  const toggleableState = "tsu_nat:open";
  const currentValue = block.permutation.getState(toggleableState);
  let toggledValue = !currentValue;
  if (forceOpen) toggledValue = true;
  if (forceClose) toggledValue = false;
  block.setPermutation(block.permutation.withState(toggleableState, toggledValue));
  const toggleSound = toggledValue ? "open.wooden_trapdoor" : "close.wooden_trapdoor";
  dimension.playSound(toggleSound, block.center());
}
//# sourceMappingURL=main.js.map
