ActionEntry class

Пакет: com.hypixel.hytale.builtin.buildertools

Файл: com/hypixel/hytale/builtin/buildertools/BuilderToolsPlugin.java

Поля (22)

МодификаторыТипИмя
private final UndoAction action
private long cachedWeight
private int cumulativeRotXBefore
private int cumulativeRotYBefore
private int cumulativeRotZBefore
private boolean entityNotFound
long var1
List var10
Store var11
boolean var14
var14
PrototypePlayerBuilderToolSettings var15
BuilderToolsPlugin.ActionEntry var18
PrototypePlayerBuilderToolSettings var21
SelectionSnapshot var22
List var5
var5
var5
List var6
var6
boolean var7
var7

Методы (17)

МодификаторыВозвратСигнатура
for for(SelectionSnapshot var4 : this.snapshots)
for for(Ref var13 : var10)
for for(SelectionSnapshot var19 : this.snapshots)
public UndoAction getActionpublic UndoAction getAction()
public int getCumulativeRotXBeforepublic int getCumulativeRotXBefore()
public int getCumulativeRotYBeforepublic int getCumulativeRotYBefore()
public int getCumulativeRotZBeforepublic int getCumulativeRotZBefore()
if if(this.cachedWeight < 0L)
if if(this.action instanceof BuilderToolsPlugin.Action var8 && var8 == BuilderToolsPlugin.Action.TRANSFORM)
if if(var10 != null)
if if(var22 != null)
if if(var22 instanceof EntityAddSnapshot var23)
if if(var6 == null)
public boolean isEntityNotFoundpublic boolean isEntityNotFound()
public BuilderToolsPlugin.ActionEntry restorepublic BuilderToolsPlugin.ActionEntry restore(Ref<EntityStore> var1, PlayerRef var2, World var3, ComponentAccessor<EntityStore> var4)
public void setCumulativeRotBeforepublic void setCumulativeRotBefore(int var1, int var2, int var3)
public long weightpublic long weight()

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.buildertools;

class="kw">import com.hypixel.fastutil.ints.Int2ObjectConcurrentHashMap;
class="kw">import com.hypixel.hytale.assetstore.AssetPack;
class="kw">import com.hypixel.hytale.assetstore.AssetRegistry;
class="kw">import com.hypixel.hytale.assetstore.event.LoadedAssetsEvent;
class="kw">import com.hypixel.hytale.assetstore.event.RemovedAssetsEvent;
class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.assetstore.map.DefaultAssetMap;
class="kw">import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ClearBlocksCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ClearEditHistory;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ClearEntitiesCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ContractSelectionCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.CopyCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.CutCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.DeselectCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.EditLineCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.EnvironmentCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ExpandCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ExtendFaceCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.FillCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.FlipCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.FloodFillCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.GlobalMaskCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.HollowCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.HotbarSwitchCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.LayerCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.MoveCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.PasteCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.Pos1Command;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.Pos2Command;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.PrefabCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.PrefabPreviewCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.RedoCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.RepairFillersCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ReplaceCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.RotateCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.SelectChunkCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.SelectChunkSectionCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.SelectionHistoryCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.SetCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.SetToolHistorySizeCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ShiftCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.ShrinkCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.StackCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.SubmergeCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.TintCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.UndoCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.UpdateSelectionCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.commands.WallsCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.imageimport.ImageImportCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.interactions.PickupItemInteraction;
class="kw">import com.hypixel.hytale.builtin.buildertools.objimport.ObjImportCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabAnchor;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabDirtySystems;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditSession;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditSessionManager;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditorCreationSettings;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabMarkerProvider;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabSelectionInteraction;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.commands.PrefabEditCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.saving.PrefabSaveContributor;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.saving.PrefabSaveSupport;
class="kw">import com.hypixel.hytale.builtin.buildertools.prefabeditor.saving.SupportMode;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfig;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigCommandExecutor;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigEditStore;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.ScriptedBrushAsset;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.commands.BrushConfigCommand;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.global.DebugBrushOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.global.DisableHoldInteractionOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.global.IgnoreExistingBrushDataOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.BlockPatternOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.BreakpointOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.ClearOperationMaskOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.ClearRotationOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.DeleteOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.EchoOnceOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.EchoOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.ErodeOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.FluidFixOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.HeightmapLayerOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.KernelErosionOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.LayerOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.LiftOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.LoadIntFromToolArgOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.LoadMaterialFromToolArgOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.MaterialOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.MeltOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.PastePrefabOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.ReplaceOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.RunCommandOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.SetDensity;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.SetOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.ShapeOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.SmoothOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.dimensions.DimensionsOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.dimensions.RandomizeDimensionsOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.ExitOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.JumpIfBlockTypeOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.JumpIfClickType;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.JumpIfCompareOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.JumpIfStringMatchOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.JumpIfToolArgOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.JumpToIndexOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.JumpToRandomIndex;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.loops.CircleOffsetAndLoopOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.loops.CircleOffsetFromArgOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.loops.LoadLoopFromToolArgOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.loops.LoopOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.flowcontrol.loops.LoopRandomOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.masks.AppendMaskFromToolArgOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.masks.AppendMaskOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.masks.HistoryMaskOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.masks.MaskOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.masks.UseBrushMaskOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.masks.UseOperationMaskOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.offsets.OffsetOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.offsets.RandomOffsetOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.saveandload.LoadBrushConfigOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.saveandload.LoadOperationsFromAssetOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.saveandload.PersistentDataOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.saveandload.SaveBrushConfigOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.saveandload.SaveIndexOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential.transforms.RotateOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.system.BrushOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.BlockSelectionSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.ClipboardBoundsSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.ClipboardContentsSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.EntityAddSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.EntityFreezeSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.EntityRemoveSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.EntityScaleSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.EntitySettingsSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.EntitySnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.EntityTransformSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.snapshot.SelectionSnapshot;
class="kw">import com.hypixel.hytale.builtin.buildertools.tooloperations.PaintOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.tooloperations.ToolOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.utils.FillerPlacementUtil;
class="kw">import com.hypixel.hytale.builtin.buildertools.utils.Material;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.common.util.CompletableFutureUtil;
class="kw">import com.hypixel.hytale.common.util.PathUtil;
class="kw">import com.hypixel.hytale.component.AddReason;
class="kw">import com.hypixel.hytale.component.Archetype;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.ComponentRegistryProxy;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.RemoveReason;
class="kw">import com.hypixel.hytale.component.ResourceType;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.system.WorldEventSystem;
class="kw">import com.hypixel.hytale.event.EventBus;
class="kw">import com.hypixel.hytale.event.EventRegistry;
class="kw">import com.hypixel.hytale.function.predicate.TriIntObjPredicate;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.Axis;
class="kw">import com.hypixel.hytale.math.block.BlockCubeUtil;
class="kw">import com.hypixel.hytale.math.block.BlockUtil;
class="kw">import com.hypixel.hytale.math.iterator.LineIterator;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.math.vector.Rotation3f;
class="kw">import com.hypixel.hytale.math.vector.Vector3iUtil;
class="kw">import com.hypixel.hytale.math.vector.VectorBoxUtil;
class="kw">import com.hypixel.hytale.metrics.MetricProvider;
class="kw">import com.hypixel.hytale.metrics.MetricResults;
class="kw">import com.hypixel.hytale.metrics.MetricsRegistry;
class="kw">import com.hypixel.hytale.protocol.BlockMaterial;
class="kw">import com.hypixel.hytale.protocol.DrawType;
class="kw">import com.hypixel.hytale.protocol.SoundCategory;
class="kw">import com.hypixel.hytale.protocol.packets.buildertools.BrushOrigin;
class="kw">import com.hypixel.hytale.protocol.packets.buildertools.BrushShape;
class="kw">import com.hypixel.hytale.protocol.packets.buildertools.BuilderToolArgUpdate;
class="kw">import com.hypixel.hytale.protocol.packets.buildertools.BuilderToolOnUseInteraction;
class="kw">import com.hypixel.hytale.protocol.packets.buildertools.BuilderToolsEnabledTools;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.BlockChange;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.EditorBlocksChange;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.NotificationStyle;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.asset.AssetModule;
class="kw">import com.hypixel.hytale.server.core.asset.HytaleAssetStore;
class="kw">import com.hypixel.hytale.server.core.asset.type.blockhitbox.BlockBoundingBoxes;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.BuilderTool;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.BlockArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.BoolArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.BrushOriginArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.BrushShapeArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.FloatArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.IntArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.MaskArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.OptionArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.StringArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.ToolArg;
class="kw">import com.hypixel.hytale.server.core.asset.type.buildertool.config.args.ToolArgException;
class="kw">import com.hypixel.hytale.server.core.asset.type.item.config.Item;
class="kw">import com.hypixel.hytale.server.core.blocktype.component.BlockPhysics;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandContext;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandManager;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandRegistry;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandSender;
class="kw">import com.hypixel.hytale.server.core.entity.UUIDComponent;
class="kw">import com.hypixel.hytale.server.core.entity.entities.BlockEntity;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.event.events.permissions.GroupPermissionChangeEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.permissions.PlayerGroupEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.permissions.PlayerPermissionChangeEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.player.PlayerConnectEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
class="kw">import com.hypixel.hytale.server.core.inventory.InventoryComponent;
class="kw">import com.hypixel.hytale.server.core.inventory.InventoryUtils;
class="kw">import com.hypixel.hytale.server.core.inventory.ItemStack;
class="kw">import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
class="kw">import com.hypixel.hytale.server.core.io.PacketHandler;
class="kw">import com.hypixel.hytale.server.core.io.ServerManager;
class="kw">import com.hypixel.hytale.server.core.modules.block.BlockModule;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
class="kw">import com.hypixel.hytale.server.core.modules.entity.tracker.EntityTrackerSystems;
class="kw">import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.server.OpenCustomUIInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.prefabspawner.PrefabSpawnerBlock;
class="kw">import com.hypixel.hytale.server.core.modules.singleplayer.SingleplayerModule;
class="kw">import com.hypixel.hytale.server.core.permissions.HytalePermissions;
class="kw">import com.hypixel.hytale.server.core.permissions.PermissionsModule;
class="kw">import com.hypixel.hytale.server.core.plugin.JavaPlugin;
class="kw">import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabCopyableComponent;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabFormat;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabLoadException;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabSaveException;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabStore;
class="kw">import com.hypixel.hytale.server.core.prefab.event.PrefabPasteEvent;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.SelectionManager;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.SelectionProvider;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.mask.BlockMask;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.standard.FeedbackConsumer;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.standard.RotateBlockMode;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.universe.world.SoundUtil;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.accessor.ChunkAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.accessor.LocalCachedChunkAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.accessor.OverridableChunkAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.AbstractCachedAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkColumn;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.FluidSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.events.AddWorldEvent;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.util.Config;
class="kw">import com.hypixel.hytale.server.core.util.FillerBlockUtil;
class="kw">import com.hypixel.hytale.server.core.util.MessageUtil;
class="kw">import com.hypixel.hytale.server.core.util.NotificationUtil;
class="kw">import com.hypixel.hytale.server.core.util.PrefabUtil;
class="kw">import com.hypixel.hytale.server.core.util.TargetUtil;
class="kw">import com.hypixel.hytale.server.core.util.TempAssetIdUtil;
class="kw">import com.hypixel.hytale.sneakythrow.consumer.ThrowableConsumer;
class="kw">import com.hypixel.hytale.sneakythrow.consumer.ThrowableTriConsumer;
class="kw">import it.unimi.dsi.fastutil.Pair;
class="kw">import it.unimi.dsi.fastutil.ints.Int2IntFunction;
class="kw">import it.unimi.dsi.fastutil.ints.Int2IntMap;
class="kw">import it.unimi.dsi.fastutil.ints.Int2IntMaps;
class="kw">import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.longs.LongArrayList;
class="kw">import it.unimi.dsi.fastutil.longs.LongIterator;
class="kw">import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.longs.LongSet;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayFIFOQueue;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectListIterator;
class="kw">import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
class="kw">import java.nio.file.Path;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Arrays;
class="kw">import java.util.Collections;
class="kw">import java.util.HashMap;
class="kw">import java.util.HashSet;
class="kw">import java.util.Iterator;
class="kw">import java.util.List;
class="kw">import java.util.Locale;
class="kw">import java.util.Map;
class="kw">import java.util.Objects;
class="kw">import java.util.Random;
class="kw">import java.util.Set;
class="kw">import java.util.UUID;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.ExecutorService;
class="kw">import java.util.concurrent.Executors;
class="kw">import java.util.concurrent.ScheduledFuture;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.concurrent.atomic.AtomicBoolean;
class="kw">import java.util.concurrent.locks.StampedLock;
class="kw">import java.util.function.BiConsumer;
class="kw">import java.util.function.Consumer;
class="kw">import java.util.function.IntUnaryOperator;
class="kw">import java.util.function.Predicate;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Quaterniond;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3dc;
class="kw">import org.joml.Vector3i;
class="kw">import org.joml.Vector3ic;

class="kw">public class BuilderToolsPlugin class="kw">extends JavaPlugin class="kw">implements SelectionProvider, MetricProvider {
   class="kw">public class="kw">static class="kw">final String EDITOR_BLOCK = "Editor_Block";
   class="kw">public class="kw">static class="kw">final String EDITOR_BLOCK_PREFAB_AIR = "Editor_Empty";
   class="kw">public class="kw">static class="kw">final String EDITOR_BLOCK_PREFAB_ANCHOR = "Editor_Anchor";
   class="kw">protected class="kw">static class="kw">final float SPHERE_SIZE = 1.0F;
   class="kw">static class="kw">final int MAX_CLIPBOARD_BLOCK_COUNT = 16000000;
   class="kw">static class="kw">final int MAX_EDIT_BLOCK_COUNT = 16000000;
   class="kw">public class="kw">static class="kw">final int STREAM_TO_CLIENT_LIMIT = 4000000;
   class="kw">public class="kw">static class="kw">final int SHAPE_PREVIEW_THRESHOLD = 2000000;
   class="kw">public class="kw">static class="kw">final int SHAPE_PREVIEW_MAX_VOLUME = 16000000;
   class="kw">private class="kw">static class="kw">final String EDIT_PROGRESS_NOTIFICATION_TAG = "buildertools.editProgress";
   class="kw">private class="kw">static class="kw">final String BRUSH_PROGRESS_NOTIFICATION_TAG = "buildertools.brushProgress";
   class="kw">private class="kw">static class="kw">final String PASTE_NOTIFICATION_TAG = "buildertools.paste";
   class="kw">private class="kw">static class="kw">final FeedbackConsumer FEEDBACK_CONSUMER = BuilderToolsPlugin::sendFeedback;
   class="kw">private class="kw">static class="kw">final MetricsRegistry<BuilderToolsPlugin> PLUGIN_METRICS_REGISTRY = new MetricsRegistry<BuilderToolsPlugin>()
      .register(
         "BuilderStates",
         var0 -> var0.builderStates.values().toArray(BuilderToolsPlugin.BuilderState[]::new),
         new ArrayCodec<>(BuilderToolsPlugin.BuilderState.STATE_METRICS_REGISTRY, BuilderToolsPlugin.BuilderState[]::new)
      );
   class="kw">private class="kw">static class="kw">final long RETAIN_BUILDER_STATE_TIMESTAMP = Long.MAX_VALUE;
   class="kw">private class="kw">static class="kw">final long MIN_CLEANUP_INTERVAL_NANOS = TimeUnit.MINUTES.toNanos(1L);
   class="kw">private class="kw">final Map<UUID, BuilderToolsPlugin.BuilderState> builderStates = new ConcurrentHashMap<>();
   class="kw">private PrefabEditSessionManager prefabEditSessionManager;
   class="kw">private class="kw">final BlockColorIndex blockColorIndex = new BlockColorIndex();
   class="kw">private class="kw">static BuilderToolsPlugin instance;
   class="kw">private int historyCount;
   class="kw">private long historyBlockBudget;
   class="kw">private long redoHistoryBlockBudget;
   class="kw">private long toolExpireTimeNanos;
   @Nullable
   class="kw">private ScheduledFuture<?> cleanupTask;
   class="kw">private class="kw">final ExecutorService prefabSaveExecutor = Executors.newSingleThreadExecutor(var0 -> {
      Thread var1 = new Thread(var0, "BuilderTools-PrefabSave");
      var1.setDaemon(true);
      class="kw">return var1;
   });
   class="kw">private ComponentType<EntityStore, BuilderToolsUserData> userDataComponentType;
   class="kw">private ComponentType<EntityStore, PrefabAnchor> prefabAnchorComponentType;
   class="kw">private class="kw">final Int2ObjectConcurrentHashMap<ConcurrentHashMap<UUID, UUID>> pastedPrefabPathUUIDMap = new Int2ObjectConcurrentHashMap<>();
   class="kw">private class="kw">final Int2ObjectConcurrentHashMap<ConcurrentHashMap<String, UUID>> pastedPrefabPathNameToUUIDMap = new Int2ObjectConcurrentHashMap<>();
   class="kw">private class="kw">final List<PrefabSaveContributor> prefabSaveContributors = new ArrayList<>();
   class="kw">private class="kw">final List<PrefabSaveContributor> clipboardContributors = new ArrayList<>();
   @Nullable
   class="kw">private class="kw">volatile BiConsumer<PlayerRef, Store<EntityStore>> selectionBoundsUpdatedCallback;
   @Nullable
   class="kw">private class="kw">volatile BiConsumer<PlayerRef, Store<EntityStore>> builderToolModeDeactivatedCallback;
   @Nullable
   class="kw">private class="kw">volatile BiConsumer<PlayerRef, Store<EntityStore>> selectionClearedCallback;
   class="kw">private class="kw">static class="kw">final float SMOOTHING_KERNEL_TOTAL = 27.0F;
   class="kw">private class="kw">static class="kw">final int[] SMOOTHING_KERNEL = new int[]{1, 2, 1, 2, 3, 2, 1, 2, 1, 2, 3, 2, 3, 4, 3, 2, 3, 2, 1, 2, 1, 2, 3, 2, 1, 2, 1};
   class="kw">private class="kw">static class="kw">final String[] KNOWN_SHAPE_SUFFIXES = new String[]{
      "Pillar_Base",
      "Pillar_Middle",
      "Roof_Flat",
      "Roof_Steep",
      "Roof_Shallow",
      "Roof_Corner",
      "Roof_Hollow",
      "Stalactite_Small",
      "Stalactite_Large",
      "Smooth",
      "Beam",
      "Half",
      "Stairs",
      "Wall",
      "Fence",
      "Corner",
      "Roof",
      "Decorative",
      "Ornate"
   };
   class="kw">private class="kw">final Config<BuilderToolsPlugin.BuilderToolsConfig> config = this.withConfig("BuilderToolsModule", BuilderToolsPlugin.BuilderToolsConfig.CODEC);
   class="kw">private class="kw">static class="kw">final Message MESSAGE_PACK_NOT_FOUND = Message.translation("server.commands.editprefab.save.pack.notFound");
   class="kw">private class="kw">static class="kw">final Message MESSAGE_PACK_IMMUTABLE = Message.translation("server.commands.editprefab.save.pack.immutable");
   class="kw">private ResourceType<EntityStore, PrefabEditSession> prefabEditSessionResourceType;

   @Nonnull
   class="kw">public class="kw">static List<BuilderToolsPlugin.ColorGradientMaterial> parseGradientMaterials(@Nullable String var0) {
      ArrayList var1 = new ArrayList<>();
      if (var0 != null && !var0.isEmpty()) {
         String[] var2 = var0.split(",", 0);

         for (String var6 : var2) {
            int var7 = var6.indexOf("%");
            if (var7 >= 0) {
               try {
                  float var8 = Float.parseFloat(var6.substring(0, var7));
                  String var9 = var6.substring(var7 + 1);
                  BlockPattern var10 = BlockPattern.parse(var9);
                  if (var10 != null) {
                     var1.add(new BuilderToolsPlugin.ColorGradientMaterial(var10, var8));
                  }
               } catch (NumberFormatException var11) {
               }
            }
         }

         class="kw">return var1;
      } else {
         class="kw">return var1;
      }
   }

   @Nonnull
   class="kw">public ExecutorService getPrefabSaveExecutor() {
      class="kw">return this.prefabSaveExecutor;
   }

   class="kw">public BuilderToolsPlugin(@Nonnull JavaPluginInit var1) {
      super(var1);
      instance = this;
      this.getLogger().setLevel(Level.FINE);
   }

   class="kw">public class="kw">static BuilderToolsPlugin get() {
      class="kw">return instance;
   }

   class="kw">public void registerPrefabSaveContributor(@Nonnull PrefabSaveContributor var1) {
      this.prefabSaveContributors.add(var1);
   }

   @Nonnull
   class="kw">public List<PrefabSaveContributor> getPrefabSaveContributors() {
      class="kw">return this.prefabSaveContributors;
   }

   class="kw">public void registerClipboardContributor(@Nonnull PrefabSaveContributor var1) {
      this.clipboardContributors.add(var1);
   }

   @Nonnull
   class="kw">public List<PrefabSaveContributor> getClipboardContributors() {
      class="kw">return this.clipboardContributors;
   }

   class="kw">public void setSelectionBoundsUpdatedCallback(@Nullable BiConsumer<PlayerRef, Store<EntityStore>> var1) {
      this.selectionBoundsUpdatedCallback = var1;
   }

   class="kw">public void setBuilderToolModeDeactivatedCallback(@Nullable BiConsumer<PlayerRef, Store<EntityStore>> var1) {
      this.builderToolModeDeactivatedCallback = var1;
   }

   class="kw">public void setSelectionClearedCallback(@Nullable BiConsumer<PlayerRef, Store<EntityStore>> var1) {
      this.selectionClearedCallback = var1;
   }

   @Nullable
   class="kw">public BiConsumer<PlayerRef, Store<EntityStore>> getSelectionBoundsUpdatedCallback() {
      class="kw">return this.selectionBoundsUpdatedCallback;
   }

   @Nullable
   class="kw">public BiConsumer<PlayerRef, Store<EntityStore>> getBuilderToolModeDeactivatedCallback() {
      class="kw">return this.builderToolModeDeactivatedCallback;
   }

   @Nullable
   class="kw">public BiConsumer<PlayerRef, Store<EntityStore>> getSelectionClearedCallback() {
      class="kw">return this.selectionClearedCallback;
   }

   @Nonnull
   class="kw">public BlockColorIndex getBlockColorIndex() {
      class="kw">return this.blockColorIndex;
   }

   class="kw">private class="kw">static String getBlockBaseMaterial(String var0) {
      for (String var4 : KNOWN_SHAPE_SUFFIXES) {
         if (var0.endsWith("_" + var4)) {
            class="kw">return var0.substring(0, var0.length() - var4.length() - 1);
         }
      }

      class="kw">return var0;
   }

   class="kw">private class="kw">static String getBlockShape(String var0) {
      for (String var4 : KNOWN_SHAPE_SUFFIXES) {
         if (var0.endsWith("_" + var4)) {
            class="kw">return var4;
         }
      }

      class="kw">return "";
   }

   class="kw">private class="kw">static boolean passesFilter(String var0, int var1, int var2) {
      if (!"All".equals(var0) && var1 != var2) {
         BlockType var3 = BlockType.getAssetMap().getAsset(var1);
         BlockType var4 = BlockType.getAssetMap().getAsset(var2);
         if (var3 != null && var4 != null) {
            class="kw">return class="kw">switch (var0) {
               case "SameMaterial" -> getBlockBaseMaterial(var3.getId()).equals(getBlockBaseMaterial(var4.getId()));
               case "SameShape" -> getBlockShape(var3.getId()).equals(getBlockShape(var4.getId()));
               class="kw">default -> true;
            };
         } else {
            class="kw">return false;
         }
      } else {
         class="kw">return true;
      }
   }

   class="kw">private class="kw">static boolean shouldShowNotification(@Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1) {
      PlayerSettings var2 = var1.getComponent(var0, PlayerSettings.getComponentType());
      class="kw">return var2 != null && var2.creativeSettings().showBuilderToolsNotifications();
   }

   class="kw">public class="kw">static void invalidateWorldMapForSelection(@Nonnull BlockSelection var0, @Nonnull World var1) {
      invalidateWorldMapForBounds(var0.getSelectionMin(), var0.getSelectionMax(), var1);
   }

   class="kw">static void invalidateWorldMapForBounds(@Nonnull Vector3i var0, @Nonnull Vector3i var1, @Nonnull World var2) {
      LongSet var3 = new LongOpenHashSet();
      int var4 = var0.x >> 5;
      int var5 = var1.x >> 5;
      int var6 = var0.z >> 5;
      int var7 = var1.z >> 5;

      for (int var8 = var4; var8 <= var5; var8++) {
         for (int var9 = var6; var9 <= var7; var9++) {
            var3.add(ChunkUtil.indexChunk(var8, var9));
         }
      }

      var2.getWorldMapManager().clearImagesInChunks(var3);

      for (Player var11 : var2.getPlayers()) {
         var11.getWorldMapTracker().clearChunks(var3);
      }
   }

   @Nonnull
   class="kw">public class="kw">static BuilderToolsPlugin.BuilderState getState(@Nonnull Player var0, @Nonnull PlayerRef var1) {
      class="kw">return instance.getBuilderState(var0, var1);
   }

   @Nullable
   class="kw">public class="kw">static BlockSelection getMaskSelection(@Nullable BlockSelection var0) {
      class="kw">return var0 != null && var0.hasSelectionBounds() ? var0 : null;
   }

   class="kw">public class="kw">static <T class="kw">extends Throwable> void addToQueue(
      @Nonnull Player var0,
      @Nonnull PlayerRef var1,
      @Nonnull ThrowableTriConsumer<Ref<EntityStore>, BuilderToolsPlugin.BuilderState, ComponentAccessor<EntityStore>, T> var2
   ) {
      getState(var0, var1).addToQueue(var2);
   }

   class="kw">public class="kw">static <T class="kw">extends Throwable> void addToQueue(
      @Nonnull Player var0,
      @Nonnull PlayerRef var1,
      long var2,
      @Nonnull ThrowableTriConsumer<Ref<EntityStore>, BuilderToolsPlugin.BuilderState, ComponentAccessor<EntityStore>, T> var4
   ) {
      getState(var0, var1).addToQueue(var2, var4);
   }

   @Nullable
   class="kw">public class="kw">static AssetPack resolveTargetPack(@Nonnull String var0, @Nonnull Player var1, @Nonnull CommandContext var2) {
      class="kw">return resolveTargetPack(var0, null, var1, var2);
   }

   @Nullable
   class="kw">public class="kw">static AssetPack resolveTargetPack(@Nonnull String var0, @Nullable Path var1, @Nonnull Player var2, @Nonnull CommandContext var3) {
      AssetModule var4 = AssetModule.get();
      if (!var0.isEmpty()) {
         AssetPack var8 = var4.getAssetPack(var0);
         if (var8 == null) {
            var3.sendMessage(MESSAGE_PACK_NOT_FOUND.param("name", var0));
            class="kw">return null;
         } else if (var8.isImmutable()) {
            var3.sendMessage(MESSAGE_PACK_IMMUTABLE.param("name", var0));
            class="kw">return null;
         } else {
            class="kw">return var8;
         }
      } else {
         if (var1 != null) {
            AssetPack var5 = PrefabStore.get().findAssetPackForPrefabPath(var1);
            if (var5 != null) {
               if (!var5.isImmutable()) {
                  class="kw">return var5;
               }

               var3.sendMessage(Message.translation("server.commands.editprefab.save.noPack"));
               class="kw">return null;
            }
         }

         String var7 = BuilderToolsUserData.get(var2).getLastSavePack();
         if (var7 != null) {
            AssetPack var6 = var4.getAssetPack(var7);
            if (var6 != null && !var6.isImmutable()) {
               class="kw">return var6;
            }
         }

         AssetPack var9 = var4.getBaseAssetPack();
         if (!var9.isImmutable()) {
            class="kw">return var9;
         }

         var3.sendMessage(Message.translation("server.commands.editprefab.save.noPack"));
         class="kw">return null;
      }
   }

   @Override
   class="kw">protected void setup() {
      CommandRegistry var1 = this.getCommandRegistry();
      EventRegistry var2 = this.getEventRegistry();
      ComponentRegistryProxy var3 = this.getEntityStoreRegistry();
      ServerManager.get().registerSubPacketHandlers(BuilderToolsPacketHandler::new);
      var2.register(PlayerConnectEvent.class, this::onPlayerConnect);
      var2.register(PlayerDisconnectEvent.class, this::onPlayerDisconnect);
      var2.registerGlobal(PlayerReadyEvent.class, this::onPlayerReady);
      var2.registerGlobal(AddWorldEvent.class, var0 -> var0.getWorld().getWorldMapManager().addMarkerProvider("prefabs", PrefabMarkerProvider.INSTANCE));
      EventBus var4 = HytaleServer.get().getEventBus();
      var4.register(PlayerGroupEvent.Added.class, var1x -> this.resendEnabledTools(var1x.getPlayerUuid()));
      var4.register(PlayerGroupEvent.Removed.class, var1x -> this.resendEnabledTools(var1x.getPlayerUuid()));
      var4.register(PlayerPermissionChangeEvent.PermissionsAdded.class, var1x -> this.resendEnabledTools(var1x.getPlayerUuid()));
      var4.register(PlayerPermissionChangeEvent.PermissionsRemoved.class, var1x -> this.resendEnabledTools(var1x.getPlayerUuid()));
      var4.register(GroupPermissionChangeEvent.Added.class, this::onGroupPermissionsChanged);
      var4.register(GroupPermissionChangeEvent.Removed.class, this::onGroupPermissionsChanged);
      var3.registerSystem(new BuilderToolsPlugin.PrefabPasteEventSystem(this));
      var3.registerSystem(new PrefabDirtySystems.BlockBreakDirtySystem());
      var3.registerSystem(new PrefabDirtySystems.BlockPlaceDirtySystem());
      this.getEventRegistry().register(LoadedAssetsEvent.class, Item.class, var1x -> {
         ScriptedBrushAsset.invalidateBrushToItemCache();
         this.resendEnabledToolsToAll();
      });
      this.getEventRegistry().register(RemovedAssetsEvent.class, Item.class, var1x -> {
         ScriptedBrushAsset.invalidateBrushToItemCache();
         this.resendEnabledToolsToAll();
      });
      this.prefabAnchorComponentType = var3.registerComponent(PrefabAnchor.class, "PrefabAnchor", PrefabAnchor.CODEC);
      Interaction.CODEC.register("PrefabSelectionInteraction", PrefabSelectionInteraction.class, PrefabSelectionInteraction.CODEC);
      Interaction.CODEC.register("PickupItem", PickupItemInteraction.class, PickupItemInteraction.CODEC);
      Interaction.getAssetStore().loadAssets("Hytale:Hytale", List.of(new PickupItemInteraction("*PickupItem")));
      RootInteraction.getAssetStore().loadAssets("Hytale:Hytale", List.of(PickupItemInteraction.DEFAULT_ROOT));
      this.prefabEditSessionManager = new PrefabEditSessionManager(this);
      this.prefabEditSessionResourceType = var3.registerResource(PrefabEditSession.class, "PrefabEditSession", PrefabEditSession.CODEC);
      AssetRegistry.register(
         ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(
                        PrefabEditorCreationSettings.class, new DefaultAssetMap()
                     )
                     .setPath("PrefabEditorCreationSettings"))
                  .setKeyFunction(PrefabEditorCreationSettings::getId))
               .setCodec(PrefabEditorCreationSettings.CODEC))
            .build()
      );
      AssetRegistry.register(
         ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(
                        ScriptedBrushAsset.class, new DefaultAssetMap()
                     )
                     .setPath("ScriptedBrushes"))
                  .setKeyFunction(ScriptedBrushAsset::getId))
               .setCodec(ScriptedBrushAsset.CODEC))
            .build()
      );
      var1.registerCommand(new ClearBlocksCommand());
      var1.registerCommand(new ClearEntitiesCommand());
      var1.registerCommand(new ClearEditHistory());
      var1.registerCommand(new ContractSelectionCommand());
      var1.registerCommand(new CopyCommand());
      var1.registerCommand(new DeselectCommand());
      var1.registerCommand(new CutCommand());
      var1.registerCommand(new EditLineCommand());
      var1.registerCommand(new EnvironmentCommand());
      var1.registerCommand(new ExpandCommand());
      var1.registerCommand(new ExtendFaceCommand());
      var1.registerCommand(new FlipCommand());
      var1.registerCommand(new MoveCommand());
      var1.registerCommand(new PasteCommand());
      var1.registerCommand(new Pos1Command());
      var1.registerCommand(new Pos2Command());
      var1.registerCommand(new PrefabCommand());
      var1.registerCommand(new PrefabPreviewCommand());
      var1.registerCommand(new RedoCommand());
      var1.registerCommand(new ReplaceCommand());
      var1.registerCommand(new RotateCommand());
      var1.registerCommand(new SelectChunkCommand());
      var1.registerCommand(new SelectChunkSectionCommand());
      var1.registerCommand(new SelectionHistoryCommand());
      var1.registerCommand(new SetCommand());
      var1.registerCommand(new ShiftCommand());
      var1.registerCommand(new ShrinkCommand());
      var1.registerCommand(new StackCommand());
      var1.registerCommand(new SubmergeCommand());
      var1.registerCommand(new TintCommand());
      var1.registerCommand(new UndoCommand());
      var1.registerCommand(new UpdateSelectionCommand());
      var1.registerCommand(new GlobalMaskCommand());
      var1.registerCommand(new RepairFillersCommand());
      var1.registerCommand(new PrefabEditCommand());
      var1.registerCommand(new HotbarSwitchCommand());
      var1.registerCommand(new WallsCommand());
      var1.registerCommand(new HollowCommand());
      var1.registerCommand(new FillCommand());
      var1.registerCommand(new FloodFillCommand());
      var1.registerCommand(new BrushConfigCommand());
      var1.registerCommand(new SetToolHistorySizeCommand());
      var1.registerCommand(new ObjImportCommand());
      var1.registerCommand(new ImageImportCommand());
      var1.registerCommand(new LayerCommand());
      OpenCustomUIInteraction.registerBlockEntityCustomPage(
         this,
         PrefabSpawnerBlock.PrefabSpawnerSettingsPage.class,
         "PrefabSpawner",
         (var0, var1x) -> {
            Store var2 = var1x.getStore();
            BlockModule.BlockStateInfo var3 = var2.getComponent(var1x, BlockModule.BlockStateInfo.getComponentType());
            PrefabSpawnerBlock var4 = var2.getComponent(var1x, PrefabSpawnerBlock.getComponentType());
            class="kw">return var3 != null && var4 != null
               ? new PrefabSpawnerBlock.PrefabSpawnerSettingsPage(var0, var3, var4, CustomPageLifetime.CanDismissOrCloseThroughInteraction)
               : null;
         }
      );
      SelectionManager.setSelectionProvider(this);
      ToolArg.CODEC.register("Bool", BoolArg.class, BoolArg.CODEC);
      ToolArg.CODEC.register("String", StringArg.class, StringArg.CODEC);
      ToolArg.CODEC.register("Int", IntArg.class, IntArg.CODEC);
      ToolArg.CODEC.register("Float", FloatArg.class, FloatArg.CODEC);
      ToolArg.CODEC.register("Block", BlockArg.class, BlockArg.CODEC);
      ToolArg.CODEC.register("Mask", MaskArg.class, MaskArg.CODEC);
      ToolArg.CODEC.register("BrushShape", BrushShapeArg.class, BrushShapeArg.CODEC);
      ToolArg.CODEC.register("BrushOrigin", BrushOriginArg.class, BrushOriginArg.CODEC);
      ToolArg.CODEC.register("Option", OptionArg.class, OptionArg.CODEC);
      this.registerBrushOperations();
      this.userDataComponentType = var3.registerComponent(BuilderToolsUserData.class, "BuilderTools", BuilderToolsUserData.CODEC);
      var3.registerSystem(new BuilderToolsSystems.EnsureBuilderTools());
      var3.registerSystem(new BuilderToolsUserDataSystem());
   }

   class="kw">private void registerBrushOperations() {
      BrushOperation.OPERATION_CODEC.register("dimensions", DimensionsOperation.class, DimensionsOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("randomdimensions", RandomizeDimensionsOperation.class, RandomizeDimensionsOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("runcommand", RunCommandOperation.class, RunCommandOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("historymask", HistoryMaskOperation.class, HistoryMaskOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("mask", MaskOperation.class, MaskOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("clearoperationmask", ClearOperationMaskOperation.class, ClearOperationMaskOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("usebrushmask", UseBrushMaskOperation.class, UseBrushMaskOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("useoperationmask", UseOperationMaskOperation.class, UseOperationMaskOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("appendmask", AppendMaskOperation.class, AppendMaskOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("appendmaskfromtoolarg", AppendMaskFromToolArgOperation.class, AppendMaskFromToolArgOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("ignorebrushsettings", IgnoreExistingBrushDataOperation.class, IgnoreExistingBrushDataOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("debug", DebugBrushOperation.class, DebugBrushOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loop", LoopOperation.class, LoopOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loadloop", LoadLoopFromToolArgOperation.class, LoadLoopFromToolArgOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("looprandom", LoopRandomOperation.class, LoopRandomOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loopcircle", CircleOffsetAndLoopOperation.class, CircleOffsetAndLoopOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loopcirclefromarg", CircleOffsetFromArgOperation.class, CircleOffsetFromArgOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("savebrushconfig", SaveBrushConfigOperation.class, SaveBrushConfigOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loadbrushconfig", LoadBrushConfigOperation.class, LoadBrushConfigOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("saveindex", SaveIndexOperation.class, SaveIndexOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loadoperationsfromasset", LoadOperationsFromAssetOperation.class, LoadOperationsFromAssetOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("jump", JumpToIndexOperation.class, JumpToIndexOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("exit", ExitOperation.class, ExitOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("jumprandom", JumpToRandomIndex.class, JumpToRandomIndex.CODEC);
      BrushOperation.OPERATION_CODEC.register("jumpifequal", JumpIfStringMatchOperation.class, JumpIfStringMatchOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("jumpifclicktype", JumpIfClickType.class, JumpIfClickType.CODEC);
      BrushOperation.OPERATION_CODEC.register("jumpifcompare", JumpIfCompareOperation.class, JumpIfCompareOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("jumpifblocktype", JumpIfBlockTypeOperation.class, JumpIfBlockTypeOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("jumpiftoolarg", JumpIfToolArgOperation.class, JumpIfToolArgOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("pattern", BlockPatternOperation.class, BlockPatternOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loadmaterial", LoadMaterialFromToolArgOperation.class, LoadMaterialFromToolArgOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("loadint", LoadIntFromToolArgOperation.class, LoadIntFromToolArgOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("lift", LiftOperation.class, LiftOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("density", SetDensity.class, SetDensity.CODEC);
      BrushOperation.OPERATION_CODEC.register("set", SetOperation.class, SetOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("smooth", SmoothOperation.class, SmoothOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("kernelsmooth", KernelErosionOperation.class, KernelErosionOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("fluidfix", FluidFixOperation.class, FluidFixOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("shape", ShapeOperation.class, ShapeOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("rotation", RotateOperation.class, RotateOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("clearrotation", ClearRotationOperation.class, ClearRotationOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("offset", OffsetOperation.class, OffsetOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("layer", LayerOperation.class, LayerOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("heightmaplayer", HeightmapLayerOperation.class, HeightmapLayerOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("melt", MeltOperation.class, MeltOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("material", MaterialOperation.class, MaterialOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("delete", DeleteOperation.class, DeleteOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("disableonhold", DisableHoldInteractionOperation.class, DisableHoldInteractionOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("randomoffset", RandomOffsetOperation.class, RandomOffsetOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("erode", ErodeOperation.class, ErodeOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("persistentdata", PersistentDataOperation.class, PersistentDataOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("pasteprefab", PastePrefabOperation.class, PastePrefabOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("echo", EchoOperation.class, EchoOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("echoonce", EchoOnceOperation.class, EchoOnceOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("replace", ReplaceOperation.class, ReplaceOperation.CODEC);
      BrushOperation.OPERATION_CODEC.register("breakpoint", BreakpointOperation.class, BreakpointOperation.CODEC);
   }

   class="kw">public ResourceType<EntityStore, PrefabEditSession> getPrefabEditSessionResourceType() {
      class="kw">return this.prefabEditSessionResourceType;
   }

   @Override
   class="kw">protected void start() {
      BuilderToolsPlugin.BuilderToolsConfig var1 = this.config.get();
      this.historyCount = var1.historyCount;
      this.historyBlockBudget = var1.historyBlockBudget;
      this.redoHistoryBlockBudget = var1.redoHistoryBlockBudget;
      this.toolExpireTimeNanos = TimeUnit.SECONDS.toNanos(var1.toolExpireTime);
      if (this.toolExpireTimeNanos > 0L) {
         long var2 = Math.max(MIN_CLEANUP_INTERVAL_NANOS, this.toolExpireTimeNanos);
         this.cleanupTask = HytaleServer.SCHEDULED_EXECUTOR.scheduleWithFixedDelay(this::cleanup, var2, var2, TimeUnit.NANOSECONDS);
      }
   }

   @Override
   class="kw">protected void shutdown() {
      if (this.cleanupTask != null) {
         this.cleanupTask.cancel(false);
      }

      this.prefabSaveExecutor.shutdown();
   }

   class="kw">private void cleanup() {
      long var1 = System.nanoTime() - this.toolExpireTimeNanos;
      Iterator var3 = this.builderStates.entrySet().iterator();

      while (var3.hasNext()) {
         Entry var4 = var3.next();
         BuilderToolsPlugin.BuilderState var5 = var4.getValue();
         if (var5.timestamp < var1) {
            var3.remove();
            this.getLogger().at(Level.FINE).log("[%s] Expired and removed builder tool", var5.getDisplayName());
         }
      }
   }

   class="kw">public void setToolHistorySize(int var1) {
      this.historyCount = var1;
   }

   class="kw">private void onPlayerConnect(@Nonnull PlayerConnectEvent var1) {
      this.retainBuilderState(var1.getPlayer(), var1.getPlayerRef());
   }

   class="kw">private void onPlayerDisconnect(@Nonnull PlayerDisconnectEvent var1) {
      this.releaseBuilderState(var1.getPlayerRef().getUuid());
   }

   class="kw">private void onPlayerReady(@Nonnull PlayerReadyEvent var1) {
      Ref var2 = var1.getPlayerRef();
      if (var2.isValid()) {
         Store var3 = var2.getStore();
         UUIDComponent var4 = var3.getComponent(var2, UUIDComponent.getComponentType());
         if (var4 != null) {
            BuilderToolsPlugin.BuilderState var5 = this.builderStates.get(var4.getUuid());
            if (var5 != null && var5.getSelection() != null) {
               var5.sendSelectionToClient();
            }

            PlayerRef var6 = var3.getComponent(var2, PlayerRef.getComponentType());
            if (var6 != null) {
               this.sendEnabledTools(var6);
            }
         }
      }
   }

   class="kw">private void onGroupPermissionsChanged(@Nonnull GroupPermissionChangeEvent var1) {
      String var2 = var1.getGroupName();
      PermissionsModule var3 = PermissionsModule.get();

      for (PlayerRef var5 : Universe.get().getPlayers()) {
         if (var3.getGroupsForUser(var5.getUuid()).contains(var2)) {
            this.sendEnabledTools(var5);
         }
      }
   }

   class="kw">private void resendEnabledTools(@Nonnull UUID var1) {
      PlayerRef var2 = Universe.get().getPlayer(var1);
      if (var2 != null) {
         this.sendEnabledTools(var2);
      }
   }

   class="kw">private void resendEnabledToolsToAll() {
      Universe var1 = Universe.get();
      if (var1 != null) {
         for (PlayerRef var3 : var1.getPlayers()) {
            this.sendEnabledTools(var3);
         }
      }
   }

   class="kw">private void sendEnabledTools(@Nonnull PlayerRef var1) {
      PermissionsModule var2 = PermissionsModule.get();
      UUID var3 = var1.getUuid();
      boolean var4 = var2.hasPermission(var3, HytalePermissions.BUILDER_TOOLS_EDITOR);
      ArrayList var5 = new ArrayList<>();

      for (Entry var7 : Item.getAssetMap().getAssetMap().entrySet()) {
         String var8 = var7.getKey();
         BuilderTool var9 = var7.getValue().getBuilderTool();
         if (var9 != null && var9.isSurvivalAllowed() && var8 != null && !var5.contains(var8)) {
            String var10 = var9.getId();
            if (var4 || var10 != null && var2.hasPermission(var3, HytalePermissions.toolPermission(var10))) {
               var5.add(var8);
            }
         }
      }

      BuilderToolsEnabledTools var11 = new BuilderToolsEnabledTools();
      var11.toolIds = var5.toArray(new String[0]);
      var1.getPacketHandler().write(var11);
   }

   class="kw">public void onToolArgUpdate(
      @Nonnull Ref<EntityStore> var1, @Nonnull PlayerRef var2, @Nonnull BuilderToolArgUpdate var3, @Nonnull ComponentAccessor<EntityStore> var4
   ) {
      ItemContainer var5 = InventoryUtils.getSectionById(var1, var3.section, var4);
      if (var5 == null) {
         MessageUtil.sendFailureReply(
            var2,
            var3.token,
            Message.translation("server.builderTools.invalidTool").param("item", Message.translation("builderTools.invalidTool.unknown.section"))
         );
      } else {
         ItemStack var6 = var5.getItemStack((short)var3.slot);
         if (var6 == null) {
            MessageUtil.sendFailureReply(var2, var3.token, Message.translation("server.builderTools.invalidTool").param("item", "Empty"));
         } else {
            Item var7 = var6.getItem();
            BuilderTool var8 = var7.getBuilderTool();
            if (var8 == null) {
               MessageUtil.sendFailureReply(var2, var3.token, Message.translation("server.builderTools.invalidTool").param("item", var6.getDisplayName()));
            } else {
               try {
                  ItemStack var9 = var8.updateArgMetadata(var6, var3.id, var3.value);
                  var5.setItemStackForSlot((short)var3.slot, var9);
                  MessageUtil.sendSuccessReply(var2, var3.token);
               } catch (ToolArgException var10) {
                  MessageUtil.sendFailureReply(var2, var3.token, var10.getTranslationMessage());
               } catch (IllegalArgumentException var11) {
                  MessageUtil.sendFailureReply(
                     var2, var3.token, Message.translation("server.builderTools.toolArgParseError").param("arg", var3.id).param("value", var3.value)
                  );
               }
            }
         }
      }
   }

   @Nonnull
   class="kw">public BuilderToolsPlugin.BuilderState getBuilderState(@Nonnull Player var1, @Nonnull PlayerRef var2) {
      class="kw">return this.builderStates.computeIfAbsent(var2.getUuid(), var2x -> new BuilderToolsPlugin.BuilderState(var1, var2));
   }

   @Nullable
   class="kw">public BuilderToolsPlugin.BuilderState clearBuilderState(UUID var1) {
      BuilderToolsPlugin.BuilderState var2 = this.builderStates.remove(var1);
      if (var2 != null) {
         this.getLogger().at(Level.FINE).log("[%s] Removed builder tool for", var2.getDisplayName());
      }

      class="kw">return var2;
   }

   class="kw">private void retainBuilderState(@Nonnull Player var1, @Nonnull PlayerRef var2) {
      this.builderStates.compute(var2.getUuid(), (var3, var4) -> {
         if (var4 == null) {
            class="kw">return null;
         }

         var4.retain(var1, var2);
         this.getLogger().at(Level.FINE).log("[%s] Retained builder tool", var4.getDisplayName());
         class="kw">return (BuilderToolsPlugin.BuilderState)var4;
      });
   }

   class="kw">private void releaseBuilderState(@Nonnull UUID var1) {
      if (this.toolExpireTimeNanos <= 0L) {
         this.clearBuilderState(var1);
      } else {
         this.builderStates.compute(var1, (var1x, var2) -> {
            if (var2 == null) {
               class="kw">return null;
            }

            var2.release();
            this.getLogger().at(Level.FINE).log("[%s] Marked builder tool for removal", var2.getDisplayName());
            class="kw">return (BuilderToolsPlugin.BuilderState)var2;
         });
      }
   }

   class="kw">public ComponentType<EntityStore, BuilderToolsUserData> getUserDataComponentType() {
      class="kw">return this.userDataComponentType;
   }

   class="kw">public class="kw">static void sendFeedback(
      @Nonnull Message var0, @Nullable CommandSender var1, @Nonnull NotificationStyle var2, @Nonnull ComponentAccessor<EntityStore> var3
   ) {
      sendFeedback(var0, var1, var2, null, var3);
   }

   class="kw">public class="kw">static void sendFeedback(
      @Nonnull Message var0, @Nullable CommandSender var1, @Nonnull NotificationStyle var2, @Nullable String var3, @Nonnull ComponentAccessor<EntityStore> var4
   ) {
      if (var1 class="kw">instanceof PlayerRef var5) {
         if (!shouldShowNotification(var5.getReference(), var4)) {
            class="kw">return;
         }

         NotificationUtil.sendNotification(var5.getPacketHandler(), var0, null, null, null, var2, var3);
      } else if (var1 != null) {
         var1.sendMessage(var0);
      }
   }

   class="kw">public class="kw">static void sendFeedback(@Nonnull String var0, int var1, CommandSender var2, ComponentAccessor<EntityStore> var3) {
      if (var2 class="kw">instanceof PlayerRef var4) {
         if (!shouldShowNotification(var4.getReference(), var3)) {
            class="kw">return;
         }

         NotificationUtil.sendNotification(
            var4.getPacketHandler(),
            Message.translation("server.builderTools.blocksEdited").param("key", var0),
            Message.raw(String.valueOf(var1)),
            null,
            null,
            NotificationStyle.Success,
            progressTagFor(var4)
         );
      } else if (var2 != null) {
         var2.sendMessage(Message.translation("server.builderTools.blocksEdited").param("key", var0));
      }
   }

   class="kw">public class="kw">static void sendFeedback(@Nonnull String var0, int var1, int var2, CommandSender var3, ComponentAccessor<EntityStore> var4) {
      if (var2 % 100000 == 0 || var2 == var1) {
         int var5 = var1 > 0 ? (int)Math.min(100.0, (double)var2 / var1 * 100.0) : 100;
         Message var6 = friendlyOperationLabel(var0);
         if (var3 class="kw">instanceof PlayerRef var7) {
            if (!shouldShowNotification(var7.getReference(), var4)) {
               class="kw">return;
            }

            String var8 = progressTagFor(var7);
            NotificationUtil.sendNotification(
               var7.getPacketHandler(),
               Message.translation("server.builderTools.editingStatus").param("label", var6),
               Message.translation("server.builderTools.editingStatusDetail").param("percent", var5).param("total", var1),
               null,
               null,
               NotificationStyle.Success,
               var8
            );
         } else if (var3 != null) {
            var3.sendMessage(Message.translation("server.builderTools.editingStatus.console").param("label", var6).param("percent", var5).param("total", var1));
         }
      }
   }

   @Nonnull
   class="kw">private class="kw">static String progressTagFor(@Nonnull PlayerRef var0) {
      BuilderToolsPlugin.BuilderState var1 = get().builderStates.get(var0.getUuid());
      class="kw">return var1 != null ? var1.currentProgressTag() : "buildertools.editProgress";
   }

   @Nonnull
   class="kw">private class="kw">static Message friendlyOperationLabel(@Nullable String var0) {
      if (var0 != null && !var0.isBlank()) {
         String var1 = var0.replaceFirst("\\s+\\S+/\\S+$", "").trim();

         String var2 = class="kw">switch (var1) {
            case "Gather" -> var0.trim().endsWith("1/1") ? "server.builderTools.op.copying" : "server.builderTools.op.cutting";
            case "Cut" -> "server.builderTools.op.cutting";
            case "Clear" -> "server.builderTools.op.clearing";
            case "Fill" -> "server.builderTools.op.filling";
            case "Set" -> "server.builderTools.op.setting";
            case "Replace" -> "server.builderTools.op.replacing";
            case "Shrink" -> "server.builderTools.op.shrinking";
            case "Extrude" -> "server.builderTools.op.extruding";
            case "Hollow" -> "server.builderTools.op.hollowing";
            case "Walls" -> "server.builderTools.op.walls";
            case "Transform" -> "server.builderTools.op.placing";
            case "Submerge" -> "server.builderTools.op.submerging";
            case "Unsubmerge" -> "server.builderTools.op.unsubmerging";
            case "Save" -> "server.builderTools.op.saving";
            class="kw">default -> "server.builderTools.op.editing";
         };
         class="kw">return Message.translation(var2);
      } else {
         class="kw">return Message.translation("server.builderTools.op.editing");
      }
   }

   @Override
   class="kw">public <T class="kw">extends Throwable> void computeSelectionCopy(
      @Nonnull Ref<EntityStore> var1, @Nonnull Player var2, @Nonnull ThrowableConsumer<BlockSelection, T> var3, @Nonnull ComponentAccessor<EntityStore> var4
   ) {
      if (this.isEnabled()) {
         PlayerRef var5 = var4.getComponent(var1, PlayerRef.getComponentType());
         assert var5 != null;
         this.getBuilderState(var2, var5).computeSelectionCopy(var3);
      }
   }

   @Nonnull
   @Override
   class="kw">public MetricResults toMetricResults() {
      class="kw">return PLUGIN_METRICS_REGISTRY.toMetricResults(this);
   }

   class="kw">public ComponentType<EntityStore, PrefabAnchor> getPrefabAnchorComponentType() {
      class="kw">return this.prefabAnchorComponentType;
   }

   class="kw">public PrefabEditSessionManager getPrefabEditSessionManager() {
      class="kw">return this.prefabEditSessionManager;
   }

   @Nullable
   @Deprecated
   class="kw">public class="kw">static Holder<ChunkStore> createBlockComponent(
      WorldChunk var0, int var1, int var2, int var3, int var4, int var5, @Nullable Holder<ChunkStore> var6, boolean var7
   ) {
      if (var4 == 0) {
         class="kw">return null;
      }

      BlockType var8 = BlockType.getAssetMap().getAsset(var4);
      class="kw">return var8.getBlockEntity() != null ? var8.getBlockEntity().clone() : null;
   }

   class="kw">public class="kw">static void forEachCopyableInSelection(
      @Nonnull World var0, int var1, int var2, int var3, int var4, int var5, int var6, @Nonnull Consumer<Ref<EntityStore>> var7
   ) {
      int var8 = var4 + 1;
      int var9 = var5 + 1;
      int var10 = var6 + 1;
      if (var0.isInThread()) {
         internalForEachCopyableInSelection(var0, var1, var2, var3, var8, var9, var10, var7);
      } else {
         CompletableFuture.runAsync(() -> internalForEachCopyableInSelection(var0, var1, var2, var3, var8, var9, var10, var7), var0).join();
      }
   }

   class="kw">private class="kw">static void internalForEachCopyableInSelection(
      @Nonnull World var0, int var1, int var2, int var3, int var4, int var5, int var6, @Nonnull Consumer<Ref<EntityStore>> var7
   ) {
      var0.getEntityStore()
         .getStore()
         .forEachChunk(Archetype.of(PrefabCopyableComponent.getComponentType(), TransformComponent.getComponentType()), (var7x, var8) -> {
            int var9 = var7x.size();

            for (int var10 = 0; var10 < var9; var10++) {
               Vector3d var11 = var7x.getComponent(var10, TransformComponent.getComponentType()).getPosition();
               Ref var12 = var7x.getReferenceTo(var10);
               if (VectorBoxUtil.isInside(var1, var2, var3, 0.0, 0.0, 0.0, var4, var5, var6, var11)) {
                  var7.accept(var12);
               }
            }
         });
   }

   class="kw">private class="kw">static int getNonEmptyNeighbourBlock(@Nonnull ChunkAccessor var0, int var1, int var2, int var3) {
      int var4;
      if ((var4 = var0.getBlock(var1, var2, var3 + 1)) > 0) {
         class="kw">return var4;
      } else if ((var4 = var0.getBlock(var1, var2, var3 - 1)) > 0) {
         class="kw">return var4;
      } else if ((var4 = var0.getBlock(var1, var2 + 1, var3)) > 0) {
         class="kw">return var4;
      } else if ((var4 = var0.getBlock(var1, var2 - 1, var3)) > 0) {
         class="kw">return var4;
      } else if ((var4 = var0.getBlock(var1 - 1, var2, var3)) > 0) {
         class="kw">return var4;
      } else {
         class="kw">return (var4 = var0.getBlock(var1 + 1, var2, var3)) > 0 ? var4 : 0;
      }
   }

   @Nonnull
   class="kw">public UUID getNewPathIdOnPrefabPasted(@Nullable UUID var1, String var2, int var3) {
      ConcurrentHashMap var4 = this.pastedPrefabPathUUIDMap.get(var3);
      if (var4 == null) {
         var4 = new ConcurrentHashMap<>();
         this.pastedPrefabPathUUIDMap.put(var3, var4);
      }

      if (var1 != null) {
         class="kw">return var4.computeIfAbsent(var1, var0 -> UUID.randomUUID());
      }

      ConcurrentHashMap var5 = this.pastedPrefabPathNameToUUIDMap.get(var3);
      if (var5 == null) {
         var5 = new ConcurrentHashMap<>();
         this.pastedPrefabPathNameToUUIDMap.put(var3, var5);
      }

      UUID var6 = var5.computeIfAbsent(var2, var0 -> UUID.randomUUID());
      var4.put(var6, var6);
      class="kw">return var6;
   }

   class="kw">public class="kw">static boolean onPasteStart(int var0, @Nonnull ComponentAccessor<EntityStore> var1) {
      PrefabPasteEvent var2 = new PrefabPasteEvent(var0, true);
      var1.invoke(var2);
      class="kw">return !var2.isCancelled();
   }

   class="kw">public void onPasteEnd(int var1, @Nonnull ComponentAccessor<EntityStore> var2) {
      PrefabPasteEvent var3 = new PrefabPasteEvent(var1, false);
      var2.invoke(var3);
   }

   class="kw">public Int2ObjectConcurrentHashMap<ConcurrentHashMap<UUID, UUID>> getPastedPrefabPathUUIDMap() {
      class="kw">return this.pastedPrefabPathUUIDMap;
   }

   class="kw">public enum Action class="kw">implements UndoAction {
      EDIT("server.builderTools.action.edit"),
      EDIT_SELECTION("server.builderTools.action.editSelection"),
      EDIT_LINE("server.builderTools.action.editLine"),
      CUT_COPY("server.builderTools.action.cutCopy", false),
      CUT_REMOVE("server.builderTools.action.cutRemove"),
      COPY("server.builderTools.action.copy", false),
      PASTE("server.builderTools.action.paste"),
      CLEAR("server.builderTools.action.clear"),
      TRANSFORM("server.builderTools.action.transform"),
      FLIP("server.builderTools.action.flip"),
      MOVE("server.builderTools.action.move"),
      STACK("server.builderTools.action.stack"),
      SET("server.builderTools.action.set"),
      REPLACE("server.builderTools.action.replace"),
      EXTRUDE("server.builderTools.action.extrude"),
      UPDATE_SELECTION("server.builderTools.action.updateSelection", false),
      WALLS("server.builderTools.action.walls"),
      HOLLOW("server.builderTools.action.hollow"),
      LAYER("server.builderTools.action.layer"),
      ENTITY_TRANSFORM("server.builderTools.action.entityTransform"),
      ENTITY_SCALE("server.builderTools.action.entityScale"),
      ENTITY_CLONE("server.builderTools.action.entityClone"),
      ENTITY_REMOVE("server.builderTools.action.entityRemove"),
      ENTITY_FREEZE("server.builderTools.action.entityFreeze"),
      ENTITY_SETTINGS("server.builderTools.action.entitySettings"),
      TRIGGER_VOLUME("server.builderTools.action.triggerVolume", false),
      POINT("server.builderTools.action.point", false);

      class="kw">private class="kw">final String translationKey;
      class="kw">private class="kw">final boolean marksPrefabDirty;

      Action(String nullxx) {
         this(nullxx, true);
      }

      Action(String nullxx, boolean nullxxx) {
         this.translationKey = nullxx;
         this.marksPrefabDirty = nullxxx;
      }

      @Nonnull
      @Override
      class="kw">public String id() {
         class="kw">return "builtin:" + this.name().toLowerCase(Locale.ROOT);
      }

      @Nonnull
      @Override
      class="kw">public Message toMessage() {
         class="kw">return Message.translation(this.translationKey);
      }

      @Override
      class="kw">public boolean marksPrefabDirty() {
         class="kw">return this.marksPrefabDirty;
      }
   }

   class="kw">public class="kw">static class ActionEntry {
      class="kw">private class="kw">final UndoAction action;
      class="kw">private class="kw">final List<SelectionSnapshot<?>> snapshots;
      class="kw">private boolean entityNotFound;
      class="kw">private int cumulativeRotXBefore;
      class="kw">private int cumulativeRotYBefore;
      class="kw">private int cumulativeRotZBefore;
      class="kw">private long cachedWeight = -1L;

      class="kw">public ActionEntry(UndoAction var1, SelectionSnapshot<?> var2) {
         this(var1, Collections.singletonList(var2));
      }

      class="kw">public ActionEntry(UndoAction var1, List<SelectionSnapshot<?>> var2) {
         this.action = var1;
         this.snapshots = var2;
      }

      class="kw">public UndoAction getAction() {
         class="kw">return this.action;
      }

      @Nonnull
      class="kw">public List<SelectionSnapshot<?>> getSnapshots() {
         class="kw">return this.snapshots;
      }

      class="kw">public long weight() {
         if (this.cachedWeight < 0L) {
            long var1 = 0L;

            for (SelectionSnapshot var4 : this.snapshots) {
               var1 += var4.estimatedBlockWeight();
            }

            this.cachedWeight = var1;
         }

         class="kw">return this.cachedWeight;
      }

      class="kw">public boolean isEntityNotFound() {
         class="kw">return this.entityNotFound;
      }

      class="kw">public void setCumulativeRotBefore(int var1, int var2, int var3) {
         this.cumulativeRotXBefore = var1;
         this.cumulativeRotYBefore = var2;
         this.cumulativeRotZBefore = var3;
      }

      class="kw">public int getCumulativeRotXBefore() {
         class="kw">return this.cumulativeRotXBefore;
      }

      class="kw">public int getCumulativeRotYBefore() {
         class="kw">return this.cumulativeRotYBefore;
      }

      class="kw">public int getCumulativeRotZBefore() {
         class="kw">return this.cumulativeRotZBefore;
      }

      @Nonnull
      class="kw">public BuilderToolsPlugin.ActionEntry restore(Ref<EntityStore> var1, PlayerRef var2, World var3, ComponentAccessor<EntityStore> var4) {
         List var5 = Collections.emptyList();
         List var6 = null;
         boolean var7 = false;
         if (this.action class="kw">instanceof BuilderToolsPlugin.Action var8 && var8 == BuilderToolsPlugin.Action.TRANSFORM) {
            PrototypePlayerBuilderToolSettings var15 = ToolOperation.getOrCreatePrototypeSettings(var2.getUuid());
            List var10 = var15.getLastTransformEntityRefs();
            if (var10 != null) {
               var7 = true;
               Store var11 = var3.getEntityStore().getStore();

               for (Ref var13 : var10) {
                  if (var13 != null && var13.isValid()) {
                     var5 = (List<SelectionSnapshot<?>>)(var5.isEmpty() ? new ObjectArrayList() : var5);
                     var5.add(new EntityRemoveSnapshot(var13));
                     var11.removeEntity(var13, RemoveReason.UNLOAD);
                  }
               }

               var15.setLastTransformEntityRefs(null);
            }
         }

         boolean var14 = false;

         for (SelectionSnapshot var19 : this.snapshots) {
            if (!var7 || !(var19 class="kw">instanceof EntityAddSnapshot)) {
               SelectionSnapshot var22 = var19.restore(var1, var2, var3, var4);
               if (var22 != null) {
                  var5 = (List<SelectionSnapshot<?>>)(var5.isEmpty() ? new ObjectArrayList() : var5);
                  var5.add(var22);
                  if (var22 class="kw">instanceof EntityAddSnapshot var23) {
                     if (var6 == null) {
                        var6 = new ReferenceArrayList();
                     }

                     var6.add(var23.getEntityRef());
                  }
               } else if (var19 class="kw">instanceof EntitySnapshot) {
                  var14 = true;
               }
            }
         }

         if (this.action class="kw">instanceof BuilderToolsPlugin.Action var17
            && (var17 == BuilderToolsPlugin.Action.TRANSFORM || var17 == BuilderToolsPlugin.Action.CUT_REMOVE)
            && var6 != null
            && !var6.isEmpty()) {
            PrototypePlayerBuilderToolSettings var21 = ToolOperation.getOrCreatePrototypeSettings(var2.getUuid());
            var21.setLastTransformEntityRefs(var6);
         }

         BuilderToolsPlugin.ActionEntry var18 = new BuilderToolsPlugin.ActionEntry(this.action, var5);
         var18.entityNotFound = var14;
         class="kw">return var18;
      }
   }

   class="kw">public class="kw">static class BuilderState {
      class="kw">private class="kw">static class="kw">final MetricsRegistry<BuilderToolsPlugin.BuilderState> STATE_METRICS_REGISTRY = new MetricsRegistry<BuilderToolsPlugin.BuilderState>()
         .register("Uuid", var0 -> var0.playerRef.getUuid(), Codec.UUID_STRING)
         .register("Username", BuilderToolsPlugin.BuilderState::getDisplayName, Codec.STRING)
         .register("ActivePrefabPath", BuilderToolsPlugin.BuilderState::getActivePrefabPath, Codec.UUID_STRING)
         .register("Selection", BuilderToolsPlugin.BuilderState::getSelection, BlockSelection.METRICS_REGISTRY)
         .register("TaskFuture", var0 -> Objects.toString(var0.getTaskFuture()), Codec.STRING)
         .register("TaskCount", BuilderToolsPlugin.BuilderState::getTaskCount, Codec.INTEGER)
         .register("UndoCount", BuilderToolsPlugin.BuilderState::getUndoCount, Codec.INTEGER)
         .register("RedoCount", BuilderToolsPlugin.BuilderState::getRedoCount, Codec.INTEGER);
      class="kw">private class="kw">static class="kw">final int MAX_FLOOD_CELLS = 200000;
      class="kw">private class="kw">static class="kw">final int[][] FLOOD_NEIGHBORS = new int[][]{{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
      @Deprecated(forRemoval = true)
      class="kw">private Player player;
      class="kw">private PlayerRef playerRef;
      @Nonnull
      class="kw">private class="kw">final BuilderToolsUserData userData;
      class="kw">private class="kw">final StampedLock undoLock = new StampedLock();
      class="kw">private class="kw">final BuilderToolsPlugin.HistoryStack undo = new BuilderToolsPlugin.HistoryStack();
      class="kw">private class="kw">final BuilderToolsPlugin.HistoryStack redo = new BuilderToolsPlugin.HistoryStack();
      class="kw">private class="kw">final StampedLock taskLock = new StampedLock();
      class="kw">private class="kw">final ObjectArrayFIFOQueue<BuilderToolsPlugin.QueuedTask> tasks = new ObjectArrayFIFOQueue();
      class="kw">private long progressEpoch;
      @Nullable
      class="kw">private String pinnedProgressTag;
      @Nullable
      class="kw">private class="kw">volatile CompletableFuture<Void> taskFuture;
      class="kw">private class="kw">volatile long timestamp = Long.MAX_VALUE;
      class="kw">private BlockSelection selection;
      @Nullable
      class="kw">private Vector3i rawPos1;
      @Nullable
      class="kw">private Vector3i rawPos2;
      class="kw">private boolean skipNextPreviewRebuild;
      class="kw">private int cumulativeRotX;
      class="kw">private int cumulativeRotY;
      class="kw">private int cumulativeRotZ;
      @Nullable
      class="kw">private BlockSelection preRotationSnapshot;
      class="kw">private BlockMask globalMask;
      @Nonnull
      class="kw">private Random random = new Random(26061984L);
      class="kw">private UUID activePrefabPath;
      @Nullable
      class="kw">private Path prefabListRoot;
      @Nullable
      class="kw">private Path prefabListPath;
      @Nullable
      class="kw">private String prefabListSearchQuery;
      @Nullable
      class="kw">private BlockSelection pendingUndoSnapshot;
      class="kw">private List<EntityAddSnapshot> pendingEntitySnapshots = new ArrayList<>();
      class="kw">private List<EntityTransformSnapshot> pendingEntityTransformSnapshots = new ArrayList<>();
      class="kw">private int executionCountInGroup;
      class="kw">private int brushStrokeBlocks;
      class="kw">private int brushStrokeId;
      class="kw">private class="kw">static class="kw">final int AREA_UPPER_BOUND = 4;
      class="kw">private class="kw">static class="kw">final double SHADING_MAX_LOS_RANGE = 48.0;
      class="kw">private class="kw">static class="kw">final double SHADING_AMBIENT = 0.2;
      class="kw">private class="kw">static class="kw">final int[] SOBEL_SMOOTH = new int[]{1, 4, 6, 4, 1};
      class="kw">private class="kw">static class="kw">final int[] SOBEL_DERIV = new int[]{-1, -2, 0, 2, 1};
      @Nullable
      class="kw">private EntityTransformSnapshot pendingEntityTransformSession;
      @Nullable
      class="kw">private EntityScaleSnapshot pendingEntityScaleSession;
      @Nullable
      class="kw">private Ref<EntityStore> pendingEntityScaleRef;

      class="kw">private BuilderState(@Nonnull Player var1, @Nonnull PlayerRef var2) {
         this.player = var1;
         this.playerRef = var2;
         this.userData = BuilderToolsUserData.get(var1);
      }

      class="kw">private void release() {
         this.timestamp = System.nanoTime();
      }

      class="kw">private void retain(@Nonnull Player var1, @Nonnull PlayerRef var2) {
         long var3 = this.taskLock.writeLock();

         try {
            this.player = var1;
            this.playerRef = var2;
            this.timestamp = Long.MAX_VALUE;
            if (this.selection != null) {
               this.sendArea();
            }

            this.scheduleTaskIfPossible();
         } class="kw">finally {
            this.taskLock.unlockWrite(var3);
         }
      }

      class="kw">private void scheduleTaskIfPossible() {
         World var1 = this.player.getWorld();
         if (var1 == null) {
            BuilderToolsPlugin.get().getLogger().at(Level.FINE).log("[%s] Deferring task; player has no world", this.getDisplayName());
         } else {
            if (this.taskFuture == null || this.taskFuture.isDone()) {
               this.taskFuture = CompletableFutureUtil._catch(CompletableFuture.runAsync(this::runTask, var1));
            }
         }
      }

      class="kw">public void syncRawPositions() {
         if (this.selection != null && this.selection.hasSelectionBounds()) {
            this.rawPos1 = this.selection.getSelectionMin();
            this.rawPos2 = this.selection.getSelectionMax();
         } else {
            this.rawPos1 = null;
            this.rawPos2 = null;
         }
      }

      class="kw">public <T class="kw">extends Throwable> void addToQueue(
         @Nonnull ThrowableTriConsumer<Ref<EntityStore>, BuilderToolsPlugin.BuilderState, ComponentAccessor<EntityStore>, T> var1
      ) {
         this.addToQueue(0L, var1);
      }

      class="kw">public <T class="kw">extends Throwable> void addToQueue(
         long var1, @Nonnull ThrowableTriConsumer<Ref<EntityStore>, BuilderToolsPlugin.BuilderState, ComponentAccessor<EntityStore>, T> var3
      ) {
         long var4 = this.taskLock.writeLock();

         try {
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("[%s] Add task with ComponentAccessor to queue %s: %s, %s", this.getDisplayName(), var3, this.taskFuture, this.tasks);
            this.tasks.enqueue(new BuilderToolsPlugin.QueuedTask(var3));
            this.scheduleTaskIfPossible();
         } class="kw">finally {
            this.taskLock.unlockWrite(var4);
         }
      }

      class="kw">public <T class="kw">extends Throwable> void computeSelectionCopy(@Nonnull ThrowableConsumer<BlockSelection, T> var1) {
         this.addToQueue(
            (var2, var3, var4) -> {
               long var5 = System.nanoTime();
               if (this.selection == null) {
                  this.selection = new BlockSelection();
               }

               BlockSelection var7 = this.selection;
               this.pushHistory(BuilderToolsPlugin.Action.COPY, BlockSelectionSnapshot.copyOf(this.selection));
               this.selection = new BlockSelection();
               this.preRotationSnapshot = null;
               this.selection.setPosition(var7.getX(), var7.getY(), var7.getZ());
               this.selection.setSelectionArea(var7.getSelectionMin(), var7.getSelectionMax());
               var1.accept(this.selection);
               this.syncRawPositions();
               long var8 = System.nanoTime() - var5;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log(
                     "Took: %dns (%dms) to execute computeSelectionCopy for %s which copied %d blocks",
                     var8,
                     TimeUnit.NANOSECONDS.toMillis(var8),
                     var1,
                     this.selection.getBlockCount()
                  );
               this.sendUpdate();
            }
         );
      }

      class="kw">public void runTask() {
         Ref var1 = this.playerRef.getReference();
         if (var1 != null && var1.isValid()) {
            Store var25 = var1.getStore();

            while (true) {
               long var3 = this.taskLock.readLock();

               try {
                  if (this.tasks.isEmpty()) {
                     break;
                  }
               } class="kw">finally {
                  this.taskLock.unlockRead(var3);
               }

               BuilderToolsPlugin.QueuedTask var5 = null;

               try {
                  long var6 = this.taskLock.writeLock();

                  try {
                     var5 = (BuilderToolsPlugin.QueuedTask)this.tasks.dequeue();
                     this.progressEpoch++;
                     this.pinnedProgressTag = null;
                     BuilderToolsPlugin.get()
                        .getLogger()
                        .at(Level.FINE)
                        .log("[%s] Run task from queue: %s, %s, %s", this.getDisplayName(), var5, this.taskFuture, this.tasks);
                  } class="kw">finally {
                     this.taskLock.unlockWrite(var6);
                  }

                  var5.execute(var1, this, var25);
               } catch (Throwable var22) {
                  ((HytaleLogger.Api)BuilderToolsPlugin.get().getLogger().at(Level.SEVERE).withCause(var22))
                     .log("Failed to execute builder tools task for: %s", this.getDisplayName());
               }
            }

            this.taskFuture = null;
         } else {
            long var2 = this.taskLock.writeLock();

            try {
               while (!this.tasks.isEmpty()) {
                  this.tasks.dequeue();
               }

               this.taskFuture = null;
            } class="kw">finally {
               this.taskLock.unlockWrite(var2);
            }
         }
      }

      class="kw">public int getTaskCount() {
         long var1 = this.taskLock.readLock();

         try {
            class="kw">return this.tasks.size();
         } class="kw">finally {
            this.taskLock.unlockRead(var1);
         }
      }

      @Nonnull
      class="kw">private String currentProgressTag() {
         String var1 = this.pinnedProgressTag;
         class="kw">return var1 != null ? var1 : "buildertools.editProgress" + this.progressEpoch;
      }

      class="kw">public int getUndoCount() {
         long var1 = this.taskLock.readLock();

         try {
            class="kw">return this.undo.size();
         } class="kw">finally {
            this.taskLock.unlockRead(var1);
         }
      }

      class="kw">public int getRedoCount() {
         long var1 = this.taskLock.readLock();

         try {
            class="kw">return this.redo.size();
         } class="kw">finally {
            this.taskLock.unlockRead(var1);
         }
      }

      class="kw">public long peekUndoWeight() {
         long var1 = this.undoLock.readLock();

         try {
            class="kw">return this.undo.peekLastWeight();
         } class="kw">finally {
            this.undoLock.unlockRead(var1);
         }
      }

      class="kw">public long peekRedoWeight() {
         long var1 = this.undoLock.readLock();

         try {
            class="kw">return this.redo.peekLastWeight();
         } class="kw">finally {
            this.undoLock.unlockRead(var1);
         }
      }

      class="kw">public String getDisplayName() {
         class="kw">return this.playerRef.getUsername();
      }

      @Nonnull
      class="kw">public BuilderToolsUserData getUserData() {
         class="kw">return this.userData;
      }

      @Nullable
      class="kw">public CompletableFuture<Void> getTaskFuture() {
         class="kw">return this.taskFuture;
      }

      @Nullable
      class="kw">public BlockSelection getSelection() {
         class="kw">return this.selection;
      }

      class="kw">public BlockMask getGlobalMask() {
         class="kw">return this.globalMask;
      }

      @Nonnull
      class="kw">public Random getRandom() {
         class="kw">return this.random;
      }

      class="kw">public void setSelection(@Nonnull BlockSelection var1) {
         this.selection = var1;
         this.preRotationSnapshot = null;
      }

      class="kw">public void setSkipNextPreviewRebuild(boolean var1) {
         this.skipNextPreviewRebuild = var1;
      }

      class="kw">public void sendSelectionToClient() {
         this.sendUpdate();
      }

      class="kw">private void sendErrorFeedback(@Nonnull Ref<EntityStore> var1, @Nonnull Message var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         this.sendErrorFeedback(var1, var2, null, var3);
      }

      class="kw">private void sendErrorFeedback(@Nonnull Ref<EntityStore> var1, @Nonnull Message var2, @Nullable String var3, @Nonnull ComponentAccessor<EntityStore> var4) {
         BuilderToolsPlugin.sendFeedback(var2, this.playerRef, NotificationStyle.Warning, var3, var4);
         SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex("CREATE_ERROR"), SoundCategory.UI, var4);
      }

      class="kw">private void sendFeedback(@Nonnull Ref<EntityStore> var1, @Nonnull Message var2, @Nullable String var3, @Nonnull ComponentAccessor<EntityStore> var4) {
         this.sendFeedback(var2, var4);
         if (var3 != null) {
            SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex(var3), SoundCategory.UI, var4);
         }
      }

      class="kw">private void sendFeedback(
         @Nonnull Ref<EntityStore> var1,
         @Nonnull Message var2,
         @Nullable String var3,
         @Nonnull NotificationStyle var4,
         @Nonnull ComponentAccessor<EntityStore> var5
      ) {
         this.sendFeedback(var2, var4, var5);
         if (var3 != null) {
            SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex(var3), SoundCategory.UI, var5);
         }
      }

      class="kw">private void sendFeedback(@Nonnull Message var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         BuilderToolsPlugin.sendFeedback(var1, this.playerRef, NotificationStyle.Default, var2);
      }

      class="kw">private void sendFeedback(@Nonnull Message var1, @Nullable String var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         BuilderToolsPlugin.sendFeedback(var1, this.playerRef, NotificationStyle.Default, var2, var3);
      }

      class="kw">private void sendFeedback(@Nonnull Message var1, @Nonnull NotificationStyle var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         BuilderToolsPlugin.sendFeedback(var1, this.playerRef, var2, var3);
      }

      class="kw">private void sendFeedback(@Nonnull String var1, int var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         BuilderToolsPlugin.sendFeedback(var1, var2, this.playerRef, var3);
      }

      class="kw">private void sendFeedback(@Nonnull String var1, int var2, int var3, @Nonnull ComponentAccessor<EntityStore> var4) {
         BuilderToolsPlugin.sendFeedback(var1, var2, var3, this.playerRef, var4);
      }

      class="kw">private void sendBrushEditFeedback(int var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         this.brushStrokeBlocks += var1;
         this.sendFeedback("Edit", this.brushStrokeBlocks, var2);
      }

      class="kw">public void setActivePrefabPath(UUID var1) {
         this.activePrefabPath = var1;
      }

      class="kw">public UUID getActivePrefabPath() {
         class="kw">return this.activePrefabPath;
      }

      @Nullable
      class="kw">public Path getPrefabListRoot() {
         class="kw">return this.prefabListRoot;
      }

      class="kw">public void setPrefabListRoot(@Nullable Path var1) {
         this.prefabListRoot = var1;
      }

      @Nullable
      class="kw">public Path getPrefabListPath() {
         class="kw">return this.prefabListPath;
      }

      class="kw">public void setPrefabListPath(@Nullable Path var1) {
         this.prefabListPath = var1;
      }

      @Nullable
      class="kw">public String getPrefabListSearchQuery() {
         class="kw">return this.prefabListSearchQuery;
      }

      class="kw">public void setPrefabListSearchQuery(@Nullable String var1) {
         this.prefabListSearchQuery = var1;
      }

      class="kw">public int edit(@Nonnull Ref<EntityStore> var1, @Nonnull BuilderToolOnUseInteraction var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         World var4 = var3.getExternalData().getWorld();
         UUIDComponent var5 = var3.getComponent(var1, UUIDComponent.getComponentType());
         assert var5 != null;
         long var6 = System.nanoTime();

         ToolOperation var8;
         try {
            var8 = ToolOperation.fromPacket(var1, this.player, this.playerRef, var2, var3);
         } catch (Exception var23) {
            this.playerRef.sendMessage(Message.translation("server.builderTools.interaction.toolParseError").param("error", var23.getMessage()));
            class="kw">return 0;
         }

         PrototypePlayerBuilderToolSettings var9 = ToolOperation.PROTOTYPE_TOOL_SETTINGS.get(var5.getUuid());
         if (var9 != null && var8 class="kw">instanceof PaintOperation) {
            BuilderTool var10 = BuilderTool.getActiveBuilderTool(var1, var3);
            if (var9.isLoadingBrush()) {
               class="kw">return 0;
            }

            if (var10 != null && var10.getBrushConfigurationCommand() != null && !var10.getBrushConfigurationCommand().isEmpty()) {
               String var26 = var10.getBrushConfigurationCommand();
               String var27 = var9.getCurrentlyLoadedBrushConfigName();
               if (var27.equalsIgnoreCase(var26)) {
                  var8.executeAsBrushConfig(var9, var2, var3);
               } else {
                  ScriptedBrushAsset var29 = ScriptedBrushAsset.get(var26);
                  if (var29 != null) {
                     var9.setCurrentlyLoadedBrushConfigName(var26);
                     BrushConfigCommandExecutor var31 = var9.getBrushConfigCommandExecutor();
                     var29.loadIntoExecutor(var31);
                     var9.setUsePrototypeBrushConfigurations(false);
                     var8.executeAsBrushConfig(var9, var2, var3);
                  } else {
                     var9.setCurrentlyLoadedBrushConfigName(var26);
                     BrushConfigCommandExecutor var32 = var9.getBrushConfigCommandExecutor();
                     var32.getSequentialOperations().clear();
                     var32.getGlobalOperations().clear();
                     var9.setLoadingBrush(true);
                     CommandManager.get().handleCommand(this.playerRef, var26).thenAccept(var4x -> {
                        PrototypePlayerBuilderToolSettings var5 = ToolOperation.PROTOTYPE_TOOL_SETTINGS.get(var5.getUuid());
                        var5.setLoadingBrush(false);
                        var5.setUsePrototypeBrushConfigurations(false);
                        var8.executeAsBrushConfig(var5, var2, var3);
                     });
                  }
               }

               class="kw">return 0;
            }

            if (var9.usePrototypeBrushConfigurations()) {
               ItemStack var11 = InventoryComponent.getItemInHand(var3, var1);
               if (var11 != null && var11.getItemId().equals(var9.getPrototypeItemId())) {
                  var8.executeAsBrushConfig(var9, var2, var3);
                  class="kw">return 0;
               }
            }
         }

         Vector3i var24 = var8.getPosition();
         Vector3i var25 = var9 != null && var2.isHoldDownInteraction ? var9.getLastBrushPosition() : null;
         List var12 = ToolOperation.calculateInterpolatedPositions(var25, var24, var8.getBrushWidth(), var8.getBrushHeight(), var8.getBrushSpacing());
         if (var12.isEmpty()) {
            class="kw">return 0;
         }

         for (Vector3i var14 : var12) {
            var8.executeAt(var14.x(), var14.y(), var14.z(), var3);
         }

         if (var9 != null) {
            var9.setLastBrushPosition(var12.get(var12.size() - 1));
         }

         EditOperation var28 = var8.getEditOperation();
         BlockSelection var30 = var28.getBefore();
         BlockSelection var15 = var28.getAfter();
         var15.tryFixFiller(true);
         this.captureMissingUndoState(var30, var15, var28.getAccessor());
         int var16 = var2.undoGroupSize > 0 ? var2.undoGroupSize : 10;
         this.handleBrushUndoGrouping(var30, var28.getSpawnedEntityRefs(), var28.getMovedEntitySnapshots(), var16, var2.isHoldDownInteraction);
         var15.placeNoReturn("Use Builder Tool ?/?", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var4, var3);
         BuilderToolsPlugin.invalidateWorldMapForSelection(var15, var4);
         long var17 = System.nanoTime();
         long var19 = var17 - var6;
         int var21 = var15.getBlockCount() + var15.getFluidCount() + var15.getTintCount();
         int var22 = var12.size();
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute edit of %d blocks (%d positions)", var19, TimeUnit.NANOSECONDS.toMillis(var19), var21, var22);
         if (var21 > 0 && var9 != null && BuilderToolsPlugin.shouldShowNotification(var1, var3) && var8.showEditNotification()) {
            this.sendBrushEditFeedback(var21, var3);
         }

         class="kw">return var21;
      }

      class="kw">public void placeBrushConfig(@Nonnull Ref<EntityStore> var1, long var2, @Nonnull BrushConfigEditStore var4, @Nonnull ComponentAccessor<EntityStore> var5) {
         PlayerRef var6 = var5.getComponent(var1, PlayerRef.getComponentType());
         assert var6 != null;
         World var7 = var5.getExternalData().getWorld();
         BlockSelection var8 = var4.getAfter();
         BlockSelection var9 = var4.getBefore();
         PrototypePlayerBuilderToolSettings var10 = ToolOperation.PROTOTYPE_TOOL_SETTINGS.get(var6.getUuid());
         BrushConfig var11 = var4.getBrushConfig();
         int var12 = var10 != null ? var10.getUndoGroupSize() : 10;
         boolean var13 = var11 != null && var11.isHoldDownInteraction();
         var8.tryFixFiller(true);
         this.captureMissingUndoState(var9, var8, var4.getAccessor());
         this.handleBrushUndoGrouping(var9, Collections.emptyList(), Collections.emptyList(), var12, var13);
         var8.placeNoReturn("Use Builder Tool ?/?", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var7, var5);
         BuilderToolsPlugin.invalidateWorldMapForSelection(var8, var7);
         long var14 = System.nanoTime();
         long var16 = var14 - var2;
         int var18 = var8.getBlockCount() + var8.getFluidCount() + var8.getTintCount();
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute edit of %d blocks", var16, TimeUnit.NANOSECONDS.toMillis(var16), var18);
         if (var18 > 0 && BuilderToolsPlugin.shouldShowNotification(var6.getReference(), var5)) {
            this.sendBrushEditFeedback(var18, var5);
         }
      }

      class="kw">private void captureMissingUndoState(@Nonnull BlockSelection var1, @Nonnull BlockSelection var2, @Nonnull ChunkAccessor var3) {
         var2.forEachBlock(
            (var3x, var4, var5, var6) -> {
               if (!var1.hasBlockAtLocalPos(var3x, var4, var5)) {
                  int var7 = var3x + var2.getX();
                  int var8 = var4 + var2.getY();
                  int var9 = var5 + var2.getZ();
                  WorldChunk var10 = var3.getChunkIfInMemory(ChunkUtil.indexChunkFromBlock(var7, var9));
                  if (var10 != null) {
                     var1.addBlockAtWorldPos(
                        var7,
                        var8,
                        var9,
                        var10.getBlock(var7, var8, var9),
                        var10.getRotationIndex(var7, var8, var9),
                        var10.getFiller(var7, var8, var9),
                        var10.getSupportValue(var7, var8, var9),
                        var10.getBlockComponentHolder(var7, var8, var9)
                     );
                     if (var1.getFluidAtWorldPos(var7, var8, var9) < 0) {
                        int var11 = var10.getFluidId(var7, var8, var9);
                        if (var11 != 0) {
                           var1.addFluidAtWorldPos(var7, var8, var9, var11, var10.getFluidLevel(var7, var8, var9));
                        }
                     }
                  }
               }
            }
         );
      }

      class="kw">public void flood(@Nonnull EditOperation var1, int var2, int var3, int var4, int var5, int var6, @Nonnull BlockPattern var7, int var8) {
         int var9 = var5 / 2;
         int var10 = var6 / 2;
         Vector3i var11 = new Vector3i(var2 - var9, var3 - var10, var4 - var9);
         Vector3i var12 = new Vector3i(var2 + var9, var3 + var10, var4 + var9);
         OverridableChunkAccessor var13 = var1.getAccessor();
         LongOpenHashSet var14 = new LongOpenHashSet();
         LongArrayList var15 = new LongArrayList();
         var15.push(BlockUtil.pack(var2, var3, var4));

         do {
            long var16 = var15.popLong();
            var14.add(var16);
            int var18 = BlockUtil.unpackX(var16);
            int var19 = BlockUtil.unpackY(var16);
            int var20 = BlockUtil.unpackZ(var16);
            int var21 = var7.nextBlock(this.random);
            long var22 = BlockUtil.pack(var18 + 1, var19, var20);
            if (this.isFloodPossible(var13, var22, var11, var12, var21, var8) && !var14.contains(var22)) {
               var15.push(var22);
            }

            long var24 = BlockUtil.pack(var18 - 1, var19, var20);
            if (this.isFloodPossible(var13, var24, var11, var12, var21, var8) && !var14.contains(var24)) {
               var15.push(var24);
            }

            long var26 = BlockUtil.pack(var18, var19 + 1, var20);
            if (this.isFloodPossible(var13, var26, var11, var12, var21, var8) && !var14.contains(var26)) {
               var15.push(var26);
            }

            long var28 = BlockUtil.pack(var18, var19 - 1, var20);
            if (this.isFloodPossible(var13, var28, var11, var12, var21, var8) && !var14.contains(var28)) {
               var15.push(var28);
            }

            long var30 = BlockUtil.pack(var18, var19, var20 + 1);
            if (this.isFloodPossible(var13, var30, var11, var12, var21, var8) && !var14.contains(var30)) {
               var15.push(var30);
            }

            long var32 = BlockUtil.pack(var18, var19, var20 - 1);
            if (this.isFloodPossible(var13, var32, var11, var12, var21, var8) && !var14.contains(var32)) {
               var15.push(var32);
            }

            if (this.isFloodPossible(var13, var16, var11, var12, var21, var8)) {
               var1.setBlock(var18, var19, var20, var21);
            }
         } while (!var15.isEmpty());
      }

      class="kw">private boolean isFloodPossible(@Nonnull ChunkAccessor var1, long var2, @Nonnull Vector3i var4, @Nonnull Vector3i var5, int var6, int var7) {
         int var8 = BlockUtil.unpackX(var2);
         int var9 = BlockUtil.unpackY(var2);
         int var10 = BlockUtil.unpackZ(var2);
         if (var8 >= var4.x() && var9 >= var4.y() && var10 >= var4.z() && var8 <= var5.x() && var9 <= var5.y() && var10 <= var5.z()) {
            BlockTypeAssetMap var11 = BlockType.getAssetMap();
            BlockType var12 = var11.getAsset(var1.getBlock(var8, var9, var10));
            class="kw">return var1.getBlock(var8, var9, var10) == var7 || var12.getDrawType() != DrawType.Cube && var12.getDrawType() != DrawType.CubeWithModel;
         } else {
            class="kw">return false;
         }
      }

      class="kw">public boolean isAsideAir(@Nonnull ChunkAccessor var1, int var2, int var3, int var4) {
         class="kw">return var1.getBlock(var2 + 1, var3, var4) <= 0
            || var1.getBlock(var2 - 1, var3, var4) <= 0
            || var1.getBlock(var2, var3 + 1, var4) <= 0
            || var1.getBlock(var2, var3 - 1, var4) <= 0
            || var1.getBlock(var2, var3, var4 + 1) <= 0
            || var1.getBlock(var2, var3, var4 - 1) <= 0;
      }

      class="kw">public boolean isAsideBlock(@Nonnull ChunkAccessor var1, int var2, int var3, int var4) {
         class="kw">return var1.getBlock(var2, var3, var4) <= 0
            && (
               var1.getBlock(var2 + 1, var3, var4) > 0
                  || var1.getBlock(var2 - 1, var3, var4) > 0
                  || var1.getBlock(var2, var3 + 1, var4) > 0
                  || var1.getBlock(var2, var3 - 1, var4) > 0
                  || var1.getBlock(var2, var3, var4 + 1) > 0
                  || var1.getBlock(var2, var3, var4 - 1) > 0
            );
      }

      @Nonnull
      class="kw">public BuilderToolsPlugin.BuilderState.BlocksSampleData getBlocksSampleData(@Nonnull ChunkAccessor var1, int var2, int var3, int var4, int var5) {
         BuilderToolsPlugin.BuilderState.BlocksSampleData var6 = new BuilderToolsPlugin.BuilderState.BlocksSampleData();
         Int2IntMap var7 = new Int2IntOpenHashMap();

         for (int var8 = var2 - var5; var8 <= var2 + var5; var8++) {
            for (int var9 = var4 - var5; var9 <= var4 + var5; var9++) {
               for (int var10 = var3 - var5; var10 <= var3 + var5; var10++) {
                  int var11 = var1.getBlock(var8, var10, var9);
                  var7.put(var11, var7.getOrDefault(var11, 0) + 1);
               }
            }
         }

         BlockTypeAssetMap var14 = BlockType.getAssetMap();
         ObjectIterator var15 = Int2IntMaps.fastIterable(var7).iterator();

         while (var15.hasNext()) {
            it.unimi.dsi.fastutil.ints.Int2IntMap.Entry var16 = (it.unimi.dsi.fastutil.ints.Int2IntMap.Entry)var15.next();
            int var17 = var16.getIntKey();
            int var12 = var16.getIntValue();
            if (var12 > var6.mainBlockCount) {
               var6.mainBlock = var17;
               var6.mainBlockCount = var12;
            }

            BlockType var13 = var14.getAsset(var17);
            if (var12 > var6.mainBlockNotAirCount && var17 != 0) {
               var6.mainBlockNotAir = var17;
               var6.mainBlockNotAirCount = var12;
            }
         }

         class="kw">return var6;
      }

      @Nonnull
      class="kw">public BuilderToolsPlugin.BuilderState.SmoothSampleData getBlocksSmoothData(@Nonnull ChunkAccessor var1, int var2, int var3, int var4) {
         BuilderToolsPlugin.BuilderState.SmoothSampleData var5 = new BuilderToolsPlugin.BuilderState.SmoothSampleData();
         Int2IntMap var6 = new Int2IntOpenHashMap();
         int var7 = 0;

         for (int var8 = var2 - 1; var8 <= var2 + 1; var8++) {
            for (int var9 = var3 - 1; var9 <= var3 + 1; var9++) {
               for (int var10 = var4 - 1; var10 <= var4 + 1; var10++) {
                  int var11 = var1.getBlock(var8, var9, var10);
                  var6.put(var11, var6.getOrDefault(var11, 0) + BuilderToolsPlugin.SMOOTHING_KERNEL[var7++]);
               }
            }
         }

         float var15 = 0.0F;
         BlockTypeAssetMap var16 = BlockType.getAssetMap();
         ObjectIterator var17 = Int2IntMaps.fastIterable(var6).iterator();

         while (var17.hasNext()) {
            it.unimi.dsi.fastutil.ints.Int2IntMap.Entry var18 = (it.unimi.dsi.fastutil.ints.Int2IntMap.Entry)var17.next();
            int var12 = var18.getIntKey();
            int var13 = var18.getIntValue();
            BlockType var14 = var16.getAsset(var12);
            if (var14.getMaterial() == BlockMaterial.Solid) {
               var15 += var13;
               if (var13 > var5.solidBlockCount) {
                  var5.solidBlock = var12;
                  var5.solidBlockCount = var13;
               }
            } else if (var13 > var5.fillerBlockCount) {
               var5.fillerBlock = var12;
               var5.fillerBlockCount = var13;
            }
         }

         var5.solidStrength = var15 / 27.0F;
         class="kw">return var5;
      }

      class="kw">public void editLine(
         int var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         BlockPattern var7,
         int var8,
         int var9,
         int var10,
         BrushShape var11,
         BrushOrigin var12,
         int var13,
         int var14,
         @Nullable BlockMask var15,
         ComponentAccessor<EntityStore> var16
      ) {
         World var17 = var16.getExternalData().getWorld();
         long var18 = System.nanoTime();
         float var20 = var8 / 2.0F;
         float var21 = var9 / 2.0F;
         int var22 = MathUtil.fastCeil(var20);
         int var23 = MathUtil.fastCeil(var21);
         int var24 = Math.max(var22, var23);
         Vector3i var25 = new Vector3i(Math.min(var1, var4) - var24, Math.min(var2, var5) - var24, Math.min(var3, var6) - var24);
         Vector3i var26 = new Vector3i(Math.max(var1, var4) + var24, Math.max(var2, var5) + var24, Math.max(var3, var6) + var24);
         BlockSelection var27 = BuilderToolsPlugin.getMaskSelection(this.selection);
         Vector3i var28 = var27 == null ? null : var27.getSelectionMin();
         Vector3i var29 = var27 == null ? null : var27.getSelectionMax();
         BlockSelection var30 = new BlockSelection();
         var30.setPosition(var1, var2, var3);
         var30.setSelectionArea(var25, var26);
         this.pushHistory(BuilderToolsPlugin.Action.EDIT_LINE, new BlockSelectionSnapshot(var30));
         BlockSelection var31 = new BlockSelection(var30);
         int var32 = 0;
         if (var12 == BrushOrigin.Bottom) {
            var32 = var23 + 1;
         } else if (var12 == BrushOrigin.Top) {
            var32 = -var23;
         }

         float var33 = Math.max(0.0F, var20 - var10);
         float var34 = Math.max(0.0F, var21 - var10);
         Predicate var35 = this.createShapePredicate(var11, var20, var21, var33, var34, var10 > 0);
         int var36 = var4 - var1;
         int var37 = var6 - var3;
         int var38 = var36 / 2;
         int var39 = var37 / 2;
         LocalCachedChunkAccessor var40 = LocalCachedChunkAccessor.atWorldCoords(
            var17, var1 + var38, var3 + var39, Math.max(Math.abs(var36), Math.abs(var37)) + var24 + 1
         );
         Vector3i var41 = new Vector3i();
         LineIterator var42 = new LineIterator(var1, var2, var3, var4, var5, var6);
         int var43 = 0;

         while (var42.hasNext()) {
            Vector3i var44 = var42.next();
            if (var43 % var13 != 0) {
               var43++;
            } else {
               var43++;

               for (int var45 = -var22; var45 <= var22; var45++) {
                  for (int var46 = var22; var46 >= -var22; var46--) {
                     int var47 = var44.x() + var45;
                     int var48 = var44.z() + var46;
                     WorldChunk var49 = var40.getChunk(ChunkUtil.indexChunkFromBlock(var47, var48));

                     for (int var50 = -var23; var50 <= var23; var50++) {
                        var41.set(var45, var50, var46);
                        if (var35.test(var41)) {
                           int var51 = var44.y() + var50 + var32;
                           int var52 = var49.getBlock(var47, var51, var48);
                           int var53 = var49.getFluidId(var47, var51, var48);
                           if ((var15 == null || !var15.isExcluded(var40, var47, var51, var48, var28, var29, var52, var53)) && this.random.nextInt(100) < var14
                              )
                            {
                              int var54 = var7.nextBlock(this.random);
                              var30.addBlockAtWorldPos(
                                 var47,
                                 var51,
                                 var48,
                                 var52,
                                 var49.getRotationIndex(var47, var51, var48),
                                 var49.getFiller(var47, var51, var48),
                                 var49.getSupportValue(var47, var51, var48),
                                 var49.getBlockComponentHolder(var47, var51, var48)
                              );
                              var31.addBlockAtWorldPos(var47, var51, var48, var54, 0, 0, 0);
                           }
                        }
                     }
                  }
               }
            }
         }

         var31.placeNoReturn("Edit 1/1", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var17, var16);
         BuilderToolsPlugin.invalidateWorldMapForSelection(var31, var17);
         long var55 = System.nanoTime();
         long var56 = var55 - var18;
         int var57 = var31.getBlockCount();
         double var58 = new Vector3i(var1, var2, var3).distance(var4, var5, var6);
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute editLine of %d blocks with length %s", var56, TimeUnit.NANOSECONDS.toMillis(var56), var57, var58);
         this.sendFeedback(Message.translation("server.builderTools.drawLineOf").param("count", Math.round(var58)), var16);
      }

      class="kw">private Predicate<Vector3i> createShapePredicate(BrushShape var1, float var2, float var3, float var4, float var5, boolean var6) {
         float var7 = var2 + 0.41F;
         float var8 = var3 + 0.41F;
         float var9 = var4 + 0.41F;
         float var10 = var5 + 0.41F;

         class="kw">return class="kw">switch (var1) {
            case Cube -> var5x -> {
               double var6 = Math.abs(var5x.x());
               double var8 = Math.abs(var5x.y());
               double var10 = Math.abs(var5x.z());
               boolean var12 = var6 <= var7 && var8 <= var8 && var10 <= var7;
               if (!var6) {
                  class="kw">return var12;
               }

               boolean var13 = var6 < var9 && var8 < var10 && var10 < var9;
               class="kw">return var12 && !var13;
            };
            case Sphere -> var5x -> {
               double var6 = var5x.x();
               double var8 = var5x.y();
               double var10 = var5x.z();
               double var12 = var6 * var6 / (var7 * var7) + var8 * var8 / (var8 * var8) + var10 * var10 / (var7 * var7);
               boolean var14 = var12 <= 1.0;
               if (!var6) {
                  class="kw">return var14;
               }

               double var15 = var6 * var6 / (var9 * var9) + var8 * var8 / (var10 * var10) + var10 * var10 / (var9 * var9);
               boolean var17 = var9 > 0.0F && var10 > 0.0F && var15 <= 1.0;
               class="kw">return var14 && !var17;
            };
            case Cylinder -> var5x -> {
               double var6 = var5x.x();
               double var8 = var5x.y();
               double var10 = var5x.z();
               double var12 = (var6 * var6 + var10 * var10) / (var7 * var7);
               boolean var14 = var12 <= 1.0 && Math.abs(var8) <= var8;
               if (!var6) {
                  class="kw">return var14;
               }

               double var15 = (var6 * var6 + var10 * var10) / (var9 * var9);
               boolean var17 = var9 > 0.0F && var15 <= 1.0 && Math.abs(var8) < var10;
               class="kw">return var14 && !var17;
            };
            case Cone -> var4x -> {
               double var5 = var4x.x();
               double var7 = var4x.y();
               double var9 = var4x.z();
               double var11 = (var7 + var8) / (2.0F * var8);
               if (!(var11 < 0.0) && !(var11 > 1.0)) {
                  double var13 = var7 * (1.0 - var11);
                  double var15 = Math.sqrt(var5 * var5 + var9 * var9);
                  boolean var17 = var15 <= var13;
                  if (!var6) {
                     class="kw">return var17;
                  }

                  double var18 = Math.max(0.0, var13 - (var7 - var9));
                  boolean var20 = var15 < var18;
                  class="kw">return var17 && !var20;
               } else {
                  class="kw">return false;
               }
            };
            case InvertedCone -> var4x -> {
               double var5 = var4x.x();
               double var7 = var4x.y();
               double var9 = var4x.z();
               double var11 = (var7 + var8) / (2.0F * var8);
               if (!(var11 < 0.0) && !(var11 > 1.0)) {
                  double var13 = var7 * var11;
                  double var15 = Math.sqrt(var5 * var5 + var9 * var9);
                  boolean var17 = var15 <= var13;
                  if (!var6) {
                     class="kw">return var17;
                  }

                  double var18 = Math.max(0.0, var13 - (var7 - var9));
                  boolean var20 = var15 < var18;
                  class="kw">return var17 && !var20;
               } else {
                  class="kw">return false;
               }
            };
            case Pyramid -> var4x -> {
               double var5 = var4x.x();
               double var7 = var4x.y();
               double var9 = var4x.z();
               double var11 = (var7 + var8) / (2.0F * var8);
               if (!(var11 < 0.0) && !(var11 > 1.0)) {
                  double var13 = var7 * (1.0 - var11);
                  boolean var15 = Math.abs(var5) <= var13 && Math.abs(var9) <= var13;
                  if (!var6) {
                     class="kw">return var15;
                  }

                  double var16 = Math.max(0.0, var13 - (var7 - var9));
                  boolean var18 = Math.abs(var5) < var16 && Math.abs(var9) < var16;
                  class="kw">return var15 && !var18;
               } else {
                  class="kw">return false;
               }
            };
            case InvertedPyramid -> var4x -> {
               double var5 = var4x.x();
               double var7 = var4x.y();
               double var9 = var4x.z();
               double var11 = (var7 + var8) / (2.0F * var8);
               if (!(var11 < 0.0) && !(var11 > 1.0)) {
                  double var13 = var7 * var11;
                  boolean var15 = Math.abs(var5) <= var13 && Math.abs(var9) <= var13;
                  if (!var6) {
                     class="kw">return var15;
                  }

                  double var16 = Math.max(0.0, var13 - (var7 - var9));
                  boolean var18 = Math.abs(var5) < var16 && Math.abs(var9) < var16;
                  class="kw">return var15 && !var18;
               } else {
                  class="kw">return false;
               }
            };
            case Dome -> var5x -> {
               double var6 = var5x.x();
               double var8 = var5x.y();
               double var10 = var5x.z();
               if (var8 < 0.0) {
                  class="kw">return false;
               }

               double var12 = var6 * var6 / (var7 * var7) + var8 * var8 / (var8 * var8) + var10 * var10 / (var7 * var7);
               boolean var14 = var12 <= 1.0;
               if (!var6) {
                  class="kw">return var14;
               }

               double var15 = var6 * var6 / (var9 * var9) + var8 * var8 / (var10 * var10) + var10 * var10 / (var9 * var9);
               boolean var17 = var9 > 0.0F && var10 > 0.0F && var15 <= 1.0;
               class="kw">return var14 && !var17;
            };
            case InvertedDome -> var5x -> {
               double var6 = var5x.x();
               double var8 = var5x.y();
               double var10 = var5x.z();
               if (var8 > 0.0) {
                  class="kw">return false;
               }

               double var12 = var6 * var6 / (var7 * var7) + var8 * var8 / (var8 * var8) + var10 * var10 / (var7 * var7);
               boolean var14 = var12 <= 1.0;
               if (!var6) {
                  class="kw">return var14;
               }

               double var15 = var6 * var6 / (var9 * var9) + var8 * var8 / (var10 * var10) + var10 * var10 / (var9 * var9);
               boolean var17 = var9 > 0.0F && var10 > 0.0F && var15 <= 1.0;
               class="kw">return var14 && !var17;
            };
            case Diamond -> var4x -> {
               double var5 = var4x.x();
               double var7 = var4x.y();
               double var9 = var4x.z();
               double var11 = Math.abs(var7) / var8;
               if (var11 > 1.0) {
                  class="kw">return false;
               }

               double var13 = var7 * (1.0 - var11);
               boolean var15 = Math.abs(var5) <= var13 && Math.abs(var9) <= var13;
               if (!var6) {
                  class="kw">return var15;
               }

               double var16 = Math.max(0.0, var13 - (var7 - var9));
               boolean var18 = Math.abs(var5) < var16 && Math.abs(var9) < var16;
               class="kw">return var15 && !var18;
            };
            case Torus -> var4x -> {
               double var5 = var4x.x();
               double var7 = var4x.y();
               double var9 = var4x.z();
               double var11 = Math.max(1.0F, var8 / 2.0F);
               double var13 = Math.max(1.0, var7 - var11);
               double var15 = var11 + 0.41F;
               double var17 = Math.sqrt(var5 * var5 + var9 * var9);
               double var19 = var17 - var13;
               double var21 = Math.sqrt(var19 * var19 + var7 * var7);
               boolean var23 = var21 <= var15;
               if (!var6) {
                  class="kw">return var23;
               }

               double var24 = Math.max(0.0, var15 - (var9 > 0.0F ? var7 - var9 : 0.0F));
               boolean var26 = var24 > 0.0 && var21 < var24;
               class="kw">return var23 && !var26;
            };
         };
      }

      class="kw">private class="kw">static boolean isBlockSolidCover(LocalCachedChunkAccessor var0, int var1, int var2, int var3) {
         int var4 = var0.getBlock(var1, var2, var3);
         if (var4 <= 0) {
            class="kw">return false;
         }

         BlockType var5 = BlockType.getAssetMap().getAsset(var4);
         class="kw">return var5 != null && var5.getMaterial() == BlockMaterial.Solid;
      }

      class="kw">private class="kw">static boolean isFaceCovered(LocalCachedChunkAccessor var0, int var1, int var2, int var3, int var4, int var5, int var6) {
         int var7 = var1 + var4;
         int var8 = var2 + var5;
         int var9 = var3 + var6;

         while (true) {
            int var10 = var0.getChunk(ChunkUtil.indexChunkFromBlock(var7, var9)).getFiller(var7, var8, var9);
            if (var10 == 0
               || var7 - FillerBlockUtil.unpackX(var10) != var1
               || var8 - FillerBlockUtil.unpackY(var10) != var2
               || var9 - FillerBlockUtil.unpackZ(var10) != var3) {
               class="kw">return isBlockSolidCover(var0, var7, var8, var9);
            }

            var7 += var4;
            var8 += var5;
            var9 += var6;
         }
      }

      class="kw">private int[] getFaceHalfExtents(int var1, int var2, int var3, int var4, int var5) {
         if (Math.abs(var1) == 1) {
            class="kw">return new int[]{0, var5, var4};
         } else {
            class="kw">return Math.abs(var2) == 1 ? new int[]{var4, 0, var5} : new int[]{var4, var5, 0};
         }
      }

      class="kw">private LongOpenHashSet findConnectedSurfaceBlocks(
         @Nonnull LocalCachedChunkAccessor var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         int var9,
         @Nonnull String var10,
         @Nonnull String var11
      ) {
         int[] var12 = this.getFaceHalfExtents(var5, var6, var7, var8, var9);
         int var13 = var12[0];
         int var14 = var12[1];
         int var15 = var12[2];
         int var16 = var2 - var13;
         int var17 = var2 + var13;
         int var18 = var3 - var14;
         int var19 = var3 + var14;
         int var20 = var4 - var15;
         int var21 = var4 + var15;
         if (Math.abs(var5) == 1) {
            var16 = var2;
            var17 = var2;
         } else if (Math.abs(var6) == 1) {
            var18 = var3;
            var19 = var3;
         } else {
            var20 = var4;
            var21 = var4;
         }

         LongOpenHashSet var22 = new LongOpenHashSet();
         LongArrayList var23 = new LongArrayList();
         LongOpenHashSet var24 = new LongOpenHashSet();
         long var25 = BlockUtil.pack(var2, var3, var4);
         if ("Default".equals(var11) && isFaceCovered(var1, var2, var3, var4, var5, var6, var7)) {
            class="kw">return var22;
         }

         var23.push(var25);
         var24.add(var25);
         int[][] var27;
         if (Math.abs(var5) == 1) {
            var27 = new int[][]{{0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
         } else if (Math.abs(var6) == 1) {
            var27 = new int[][]{{1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}};
         } else {
            var27 = new int[][]{{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}};
         }

         int var28 = var1.getBlock(var2, var3, var4);

         while (!var23.isEmpty()) {
            long var29 = var23.popLong();
            int var31 = BlockUtil.unpackX(var29);
            int var32 = BlockUtil.unpackY(var29);
            int var33 = BlockUtil.unpackZ(var29);
            int var34 = var1.getBlock(var31, var32, var33);
            if (var34 > 0 && BuilderToolsPlugin.passesFilter(var10, var34, var28)) {
               WorldChunk var35 = var1.getChunk(ChunkUtil.indexChunkFromBlock(var31, var33));
               int var36 = var35.getFiller(var31, var32, var33);
               if (var36 == 0) {
                  boolean var37 = true;
                  if ("FullBlocks".equals(var10) || "NotFullBlocks".equals(var10)) {
                     BlockType var38 = BlockType.getAssetMap().getAsset(var34);
                     boolean var39 = var38 != null && var38.getMaterial() == BlockMaterial.Solid;
                     var37 = "FullBlocks".equals(var10) ? var39 : !var39;
                  }

                  if (var37) {
                     var22.add(var29);
                  }
               }

               for (int[] var40 : var27) {
                  int var41 = var31 + var40[0];
                  int var42 = var32 + var40[1];
                  int var43 = var33 + var40[2];
                  if (var41 >= var16
                     && var41 <= var17
                     && var42 >= var18
                     && var42 <= var19
                     && var43 >= var20
                     && var43 <= var21
                     && (!"Default".equals(var11) || !isFaceCovered(var1, var41, var42, var43, var5, var6, var7))) {
                     long var44 = BlockUtil.pack(var41, var42, var43);
                     if (!var24.contains(var44)) {
                        var24.add(var44);
                        var23.push(var44);
                     }
                  }
               }
            }
         }

         class="kw">return var22;
      }

      class="kw">public void extendOrShrinkFace(
         int var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         int var9,
         boolean var10,
         @Nonnull BlockPattern var11,
         @Nonnull String var12,
         @Nonnull String var13,
         int var14,
         boolean var15,
         ComponentAccessor<EntityStore> var16
      ) {
         World var17 = var16.getExternalData().getWorld();
         long var18 = System.nanoTime();
         int var20 = var8 / 2;
         int var21 = var9 / 2;
         int var22 = Math.max(var20, var21);
         LocalCachedChunkAccessor var23 = LocalCachedChunkAccessor.atWorldCoords(var17, var1, var3, var22 + var7);
         int var24 = var23.getBlock(var1, var2, var3);
         if (var24 > 0) {
            LongOpenHashSet var25 = this.findConnectedSurfaceBlocks(var23, var1, var2, var3, var4, var5, var6, var20, var21, var12, var13);
            if (!var25.isEmpty()) {
               int var26 = var25.size() * var7 * 4;
               BlockSelection var27 = new BlockSelection(var26, 0);
               var27.setPosition(var10 ? var1 : var1 + var4, var10 ? var2 : var2 + var5, var10 ? var3 : var3 + var6);
               BlockSelection var28 = new BlockSelection(var26, 0);
               var28.copyPropertiesFrom(var27);
               if (var10) {
                  this.shrinkAlongFace(var23, var25, var4, var5, var6, var7, var12, var24, var27, var28);
               } else {
                  this.extrudeAlongFace(var23, var25, var4, var5, var6, var7, 0, 0, 0, 0, false, var11, var27, var28);
               }

               String var29 = var10 ? "Shrink" : "Extrude";
               this.handleBrushUndoGrouping(var27, Collections.emptyList(), Collections.emptyList(), var14, var15);
               var28.placeNoReturn(var29, this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var17, var16);
               BuilderToolsPlugin.invalidateWorldMapForSelection(var28, var17);
               long var30 = System.nanoTime();
               long var32 = var30 - var18;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log("Took: %dns (%dms) to %s %d blocks", var32, TimeUnit.NANOSECONDS.toMillis(var32), var29.toLowerCase(Locale.ROOT), var28.getBlockCount());
               this.sendUpdate();
               this.sendArea();
            }
         }
      }

      class="kw">private void extrudeAlongFace(
         @Nonnull LocalCachedChunkAccessor var1,
         @Nonnull LongOpenHashSet var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         int var9,
         int var10,
         boolean var11,
         @Nonnull BlockPattern var12,
         @Nonnull BlockSelection var13,
         @Nonnull BlockSelection var14
      ) {
         BlockTypeAssetMap var15 = BlockType.getAssetMap();
         IndexedLookupTableAssetMap var16 = BlockBoundingBoxes.getAssetMap();
         boolean var17 = !var12.isEmpty();
         boolean var18 = var8 != 0 || var9 != 0 || var10 != 0;
         int var19 = var18 ? var8 : var3;
         int var20 = var18 ? var9 : var4;
         int var21 = var18 ? var10 : var5;

         record Placement(int x, int y, int z, int blockId, int rotation, int fluidId, byte fluidLevel) {
            Placement {
            }
         }

         ObjectArrayList var22 = new ObjectArrayList(var2.size() * var6);
         LongOpenHashSet var23 = new LongOpenHashSet(var2.size() * var6 * 4);
         long[] var24 = var2.toLongArray();
         Arrays.sort(var24);

         for (long var28 : var24) {
            int var30 = BlockUtil.unpackX(var28);
            int var31 = BlockUtil.unpackY(var28);
            int var32 = BlockUtil.unpackZ(var28);
            WorldChunk var33 = var1.getChunk(ChunkUtil.indexChunkFromBlock(var30, var32));
            int var34 = var33.getBlock(var30, var31, var32);
            int var35 = var33.getRotationIndex(var30, var31, var32);
            int var36 = var11 ? var33.getFluidId(var30, var31, var32) : 0;
            byte var37 = var11 ? var33.getFluidLevel(var30, var31, var32) : 0;
            int var38 = var8;
            int var39 = var9;
            int var40 = var10;
            if (!var18) {
               int var41 = 1;
               BlockType var42 = var15.getAsset(var34);
               BlockBoundingBoxes var43 = var42 == null ? null : var16.getAsset(var42.getHitboxTypeIndex());
               if (var43 != null && var43.protrudesUnitBox()) {
                  var41 = footprintSpanAlongNormal(var43.get(var35), var3, var4, var5)[1] + 1;
               }

               var38 = var3 * var41;
               var39 = var4 * var41;
               var40 = var5 * var41;
            }

            for (int var60 = 0; var60 < var6; var60++) {
               int var61;
               int var62;
               if (var17) {
                  Material var44 = Material.fromPattern(var12, this.random);
                  if (var44.equals(Material.EMPTY)) {
                     var61 = var34;
                     var62 = var35;
                  } else {
                     if (var44.isFluid()) {
                        int var45 = var30 + var38;
                        int var46 = var31 + var39;
                        int var47 = var32 + var40;
                        WorldChunk var48 = var1.getChunk(ChunkUtil.indexChunkFromBlock(var45, var47));
                        if (var48.getFluidId(var45, var46, var47) == 0) {
                           var13.addFluidAtWorldPos(var45, var46, var47, var48.getFluidId(var45, var46, var47), var48.getFluidLevel(var45, var46, var47));
                           var14.addFluidAtWorldPos(var45, var46, var47, var44.getFluidId(), var44.getFluidLevel());
                        }

                        var38 += var19;
                        var39 += var20;
                        var40 += var21;
                        class="kw">continue;
                     }

                     var61 = var44.getBlockId();
                     var62 = var44.getRotation();
                  }
               } else {
                  var61 = var34;
                  var62 = var35;
               }

               if (var61 <= 0 && !var11) {
                  var38 += var19;
                  var39 += var20;
                  var40 += var21;
               } else {
                  int var63 = 0;
                  int var64 = 1;
                  BlockType var65 = var15.getAsset(var61);
                  BlockBoundingBoxes var66 = var65 == null ? null : var16.getAsset(var65.getHitboxTypeIndex());
                  boolean var67 = var66 != null && var66.protrudesUnitBox();
                  if (!var18 && var67) {
                     int[] var49 = footprintSpanAlongNormal(var66.get(var62), var3, var4, var5);
                     var63 = var49[0];
                     var64 = var49[1] - var49[0] + 1;
                  }

                  int var68 = var30 + var38 - var3 * var63;
                  int var50 = var31 + var39 - var4 * var63;
                  int var51 = var32 + var40 - var5 * var63;
                  if (var67) {
                     BlockBoundingBoxes.RotatedVariantBoxes var52 = var66.get(var62);
                     boolean[] var53 = new boolean[]{true};
                     FillerBlockUtil.forEachFillerBlock(var52, (var5x, var6x, var7x) -> {
                        if (var23.contains(BlockUtil.pack(var68 + var5x, var50 + var6x, var51 + var7x))) {
                           var53[0] = false;
                        }
                     });
                     if (var53[0]) {
                        FillerBlockUtil.forEachFillerBlock(
                           var52, (var4x, var5x, var6x) -> var23.add(BlockUtil.pack(var68 + var4x, var50 + var5x, var51 + var6x))
                        );
                        var22.add(new Placement(var68, var50, var51, var61, var62, var36, var37));
                     }
                  } else if (var23.add(BlockUtil.pack(var68, var50, var51))) {
                     var22.add(new Placement(var68, var50, var51, var61, var62, var36, var37));
                  }

                  int var69 = var18 ? 1 : var64 + var7;
                  var38 += var19 * var69;
                  var39 += var20 * var69;
                  var40 += var21 * var69;
               }
            }
         }

         ObjectListIterator var54 = var22.iterator();

         while (var54.hasNext()) {
            Placement var56 = (Placement)var54.next();
            if (var56.blockId() <= 0) {
               FillerPlacementUtil.captureAndClearFootprint(var1, var13, var14, var56.x(), var56.y(), var56.z());
            }
         }

         var54 = var22.iterator();

         while (var54.hasNext()) {
            Placement var57 = (Placement)var54.next();
            if (var57.blockId() > 0) {
               FillerPlacementUtil.addBlockWithFiller(var1, var13, var14, var57.x(), var57.y(), var57.z(), var57.blockId(), var57.rotation());
            }

            if (var11) {
               WorldChunk var58 = var1.getChunk(ChunkUtil.indexChunkFromBlock(var57.x(), var57.z()));
               int var59 = var58.getFluidId(var57.x(), var57.y(), var57.z());
               if (var59 != 0 || var57.fluidId() != 0) {
                  var13.addFluidAtWorldPos(var57.x(), var57.y(), var57.z(), var59, var58.getFluidLevel(var57.x(), var57.y(), var57.z()));
                  var14.addFluidAtWorldPos(var57.x(), var57.y(), var57.z(), var57.fluidId(), var57.fluidLevel());
               }
            }
         }
      }

      class="kw">private void shrinkAlongFace(
         @Nonnull LocalCachedChunkAccessor var1,
         @Nonnull LongOpenHashSet var2,
         int var3,
         int var4,
         int var5,
         int var6,
         @Nonnull String var7,
         int var8,
         @Nonnull BlockSelection var9,
         @Nonnull BlockSelection var10
      ) {
         BlockTypeAssetMap var11 = BlockType.getAssetMap();
         IndexedLookupTableAssetMap var12 = BlockBoundingBoxes.getAssetMap();
         LongIterator var13 = var2.iterator();

         while (var13.hasNext()) {
            long var14 = (Long)var13.next();
            int var16 = BlockUtil.unpackX(var14);
            int var17 = BlockUtil.unpackY(var14);
            int var18 = BlockUtil.unpackZ(var14);
            int var19 = 0;

            for (int var20 = 0; var20 < var6; var20++) {
               int var21 = var16 - var3 * var19;
               int var22 = var17 - var4 * var19;
               int var23 = var18 - var5 * var19;
               WorldChunk var24 = var1.getChunk(ChunkUtil.indexChunkFromBlock(var21, var23));
               int var25 = var24.getBlock(var21, var22, var23);
               if (var25 <= 0 || var24.getFiller(var21, var22, var23) != 0 || !BuilderToolsPlugin.passesFilter(var7, var25, var8)) {
                  break;
               }

               int var26 = var24.getRotationIndex(var21, var22, var23);
               BlockType var27 = var11.getAsset(var25);
               BlockBoundingBoxes var28 = var27 == null ? null : var12.getAsset(var27.getHitboxTypeIndex());
               if (var28 != null && var28.protrudesUnitBox()) {
                  BlockBoundingBoxes.RotatedVariantBoxes var29 = var28.get(var26);
                  FillerBlockUtil.forEachFillerBlock(
                     var29,
                     (var6x, var7x, var8x) -> {
                        int var9 = var21 + var6x;
                        int var10 = var22 + var7x;
                        int var11 = var23 + var8x;
                        WorldChunk var12 = var1.getChunk(ChunkUtil.indexChunkFromBlock(var9, var11));
                        if (!var9.hasBlockAtWorldPos(var9, var10, var11)) {
                           var9.addBlockAtWorldPos(
                              var9,
                              var10,
                              var11,
                              var12.getBlock(var9, var10, var11),
                              var12.getRotationIndex(var9, var10, var11),
                              var12.getFiller(var9, var10, var11),
                              var12.getSupportValue(var9, var10, var11),
                              var12.getBlockComponentHolder(var9, var10, var11)
                           );
                        }

                        var10.addBlockAtWorldPos(var9, var10, var11, 0, 0, 0, 0);
                     }
                  );
                  var19 += 1 - footprintSpanAlongNormal(var29, var3, var4, var5)[0];
               } else {
                  if (!var9.hasBlockAtWorldPos(var21, var22, var23)) {
                     var9.addBlockAtWorldPos(
                        var21,
                        var22,
                        var23,
                        var25,
                        var26,
                        var24.getFiller(var21, var22, var23),
                        var24.getSupportValue(var21, var22, var23),
                        var24.getBlockComponentHolder(var21, var22, var23)
                     );
                  }

                  var10.addBlockAtWorldPos(var21, var22, var23, 0, 0, 0, 0);
                  var19++;
               }
            }
         }
      }

      class="kw">private class="kw">static int[] footprintSpanAlongNormal(@Nonnull BlockBoundingBoxes.RotatedVariantBoxes var0, int var1, int var2, int var3) {
         int[] var4 = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE};
         FillerBlockUtil.forEachFillerBlock(var0, (var4x, var5, var6) -> {
            int var7 = var4x * var1 + var5 * var2 + var6 * var3;
            if (var7 < var4[0]) {
               var4[0] = var7;
            }

            if (var7 > var4[1]) {
               var4[1] = var7;
            }
         });
         class="kw">return var4;
      }

      class="kw">public void fillVolume(
         int var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         int var9,
         @Nonnull BlockPattern var10,
         int var11,
         boolean var12,
         ComponentAccessor<EntityStore> var13
      ) {
         if (!var10.isEmpty()) {
            World var14 = var13.getExternalData().getWorld();
            long var15 = System.nanoTime();
            int var17 = var8 / 2;
            int var18 = var9 / 2;
            int var19 = Math.max(var17, var18);
            int[] var20 = this.getFaceHalfExtents(var4, var5, var6, var17, var18);
            int var21 = var20[0];
            int var22 = var20[1];
            int var23 = var20[2];
            int var24 = var1 + var4;
            int var25 = var2 + var5;
            int var26 = var3 + var6;
            int var27 = var24 - var21;
            int var28 = var24 + var21;
            int var29 = var25 - var22;
            int var30 = var25 + var22;
            int var31 = var26 - var23;
            int var32 = var26 + var23;
            if (Math.abs(var4) == 1) {
               var27 = var4 > 0 ? var24 : var24 - var7 + 1;
               var28 = var4 > 0 ? var24 + var7 - 1 : var24;
            } else if (Math.abs(var5) == 1) {
               var29 = var5 > 0 ? var25 : var25 - var7 + 1;
               var30 = var5 > 0 ? var25 + var7 - 1 : var25;
            } else {
               var31 = var6 > 0 ? var26 : var26 - var7 + 1;
               var32 = var6 > 0 ? var26 + var7 - 1 : var26;
            }

            LocalCachedChunkAccessor var33 = LocalCachedChunkAccessor.atWorldCoords(var14, var1, var3, var19 + var7);
            if (var33.getBlock(var24, var25, var26) <= 0) {
               LongOpenHashSet var34 = new LongOpenHashSet();
               LongArrayList var35 = new LongArrayList();
               LongOpenHashSet var36 = new LongOpenHashSet();
               long var37 = BlockUtil.pack(var24, var25, var26);
               var35.push(var37);
               var36.add(var37);
               int[][] var39 = new int[][]{{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};

               while (!var35.isEmpty()) {
                  long var40 = var35.popLong();
                  int var42 = BlockUtil.unpackX(var40);
                  int var43 = BlockUtil.unpackY(var40);
                  int var44 = BlockUtil.unpackZ(var40);
                  if (var33.getBlock(var42, var43, var44) <= 0) {
                     var34.add(var40);

                     for (int[] var48 : var39) {
                        int var49 = var42 + var48[0];
                        int var50 = var43 + var48[1];
                        int var51 = var44 + var48[2];
                        if (var49 >= var27 && var49 <= var28 && var50 >= var29 && var50 <= var30 && var51 >= var31 && var51 <= var32) {
                           long var52 = BlockUtil.pack(var49, var50, var51);
                           if (!var36.contains(var52)) {
                              var36.add(var52);
                              var35.push(var52);
                           }
                        }
                     }
                  }
               }

               int var59 = var34.size() * var7;
               BlockSelection var41 = new BlockSelection(var59, 0);
               var41.setPosition(var1, var2, var3);
               BlockSelection var60 = new BlockSelection(var59, 0);
               var60.copyPropertiesFrom(var41);
               LongIterator var61 = var34.iterator();

               while (var61.hasNext()) {
                  long var63 = (Long)var61.next();
                  int var65 = BlockUtil.unpackX(var63);
                  int var66 = BlockUtil.unpackY(var63);
                  int var67 = BlockUtil.unpackZ(var63);
                  WorldChunk var68 = var33.getChunk(ChunkUtil.indexChunkFromBlock(var65, var67));
                  int var69 = var68.getBlock(var65, var66, var67);
                  if (var69 <= 0) {
                     Material var70 = Material.fromPattern(var10, this.random);
                     if (var70.isFluid()) {
                        int var71 = var68.getFluidId(var65, var66, var67);
                        if (var71 == 0) {
                           byte var53 = var68.getFluidLevel(var65, var66, var67);
                           var41.addFluidAtWorldPos(var65, var66, var67, var71, var53);
                           var60.addFluidAtWorldPos(var65, var66, var67, var70.getFluidId(), var70.getFluidLevel());
                        }
                     } else {
                        int var72 = var70.getBlockId();
                        int var73 = var70.getRotation();
                        Holder var54 = var68.getBlockComponentHolder(var65, var66, var67);
                        Holder var55 = BuilderToolsPlugin.createBlockComponent(var68, var65, var66, var67, var72, var69, var54, false);
                        int var56 = var68.getSupportValue(var65, var66, var67);
                        int var57 = var68.getFiller(var65, var66, var67);
                        int var58 = var68.getRotationIndex(var65, var66, var67);
                        var41.addBlockAtWorldPos(var65, var66, var67, var69, var58, var57, var56, var54);
                        var60.addBlockAtWorldPos(var65, var66, var67, var72, var73, 0, 0, var55);
                     }
                  }
               }

               this.handleBrushUndoGrouping(var41, Collections.emptyList(), Collections.emptyList(), var11, var12);
               var60.placeNoReturn("Fill", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var14, var13);
               BuilderToolsPlugin.invalidateWorldMapForSelection(var60, var14);
               long var62 = System.nanoTime();
               long var64 = var62 - var15;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log("Took: %dns (%dms) to fill %d blocks", var64, TimeUnit.NANOSECONDS.toMillis(var64), var60.getBlockCount());
               this.sendUpdate();
               this.sendArea();
            }
         }
      }

      class="kw">private class="kw">static boolean isFullCubeBlock(int var0, int var1) {
         if (var1 != 0) {
            class="kw">return false;
         }

         BlockType var2 = BlockType.getAssetMap().getAsset(var0);
         class="kw">return var2 != null && var2.getHitboxTypeIndex() == 0 && var2.getCustomModel() == null;
      }

      class="kw">private class="kw">static boolean isGradientRecolorable(int var0, int var1, int var2) {
         class="kw">return var1 != 0 ? false : isFullCubeBlock(var0, var1) || FillerBlockUtil.multiCellFootprint(var0, var2) != null;
      }

      class="kw">public void applyRecoloring(
         int var1,
         int var2,
         int var3,
         int var4,
         int var5,
         @Nonnull BlockPattern var6,
         boolean var7,
         @Nonnull BrushShape var8,
         int var9,
         boolean var10,
         @Nonnull BlockColorIndex var11,
         @Nonnull ComponentAccessor<EntityStore> var12
      ) {
         World var13 = var12.getExternalData().getWorld();
         int var14 = var4 / 2;
         int var15 = var5 / 2;
         int var16 = Math.max(var14, var15);
         LocalCachedChunkAccessor var17 = LocalCachedChunkAccessor.atWorldCoords(var13, var1, var3, var16);
         int var18 = var17.getBlock(var1, var2, var3);
         if (var18 > 0) {
            BlockTypeAssetMap var19 = BlockType.getAssetMap();
            String var20 = null;
            HashMap var21 = null;
            if (var7) {
               BlockType var22 = var19.getAsset(var18);
               if (var22 == null) {
                  class="kw">return;
               }

               var21 = new HashMap<>();
               String var23 = Objects.requireNonNullElse(var22.getDefaultStateKey(), var22.getId());
               var20 = BuilderToolsPlugin.getBlockBaseMaterial(var23);
            }

            int var49 = var14;
            int var50 = var15;
            int var24 = var14;
            Predicate var25 = this.createShapePredicate(var8, var14, var15, 0.0F, 0.0F, false);
            Vector3i var26 = new Vector3i();
            int var27 = (var49 * 2 + 1) * (var50 * 2 + 1) * (var24 * 2 + 1);
            BlockSelection var28 = new BlockSelection(var27, 0);
            var28.setPosition(var1, var2, var3);
            BlockSelection var29 = new BlockSelection(var27, 0);
            var29.copyPropertiesFrom(var28);
            LongOpenHashSet var30 = new LongOpenHashSet();

            for (int var31 = -var49; var31 <= var49; var31++) {
               for (int var32 = -var50; var32 <= var50; var32++) {
                  for (int var33 = -var24; var33 <= var24; var33++) {
                     int var34 = var1 + var31;
                     int var35 = var2 + var32;
                     int var36 = var3 + var33;
                     if (var35 >= 0 && var35 < 320) {
                        var26.set(var31, var32, var33);
                        if (var25.test(var26)) {
                           WorldChunk var37 = var17.getChunk(ChunkUtil.indexChunkFromBlock(var34, var36));
                           int var38 = var37.getBlock(var34, var35, var36);
                           BlockType var39 = var19.getAsset(var38);
                           if (var39 != null && var37.getFiller(var34, var35, var36) == 0) {
                              String var40 = Objects.requireNonNullElse(var39.getDefaultStateKey(), var39.getId());
                              if (var7 ? BuilderToolsPlugin.getBlockBaseMaterial(var40).equals(var20) : var38 == var18) {
                                 Material var41 = Material.fromPattern(var6, this.random);
                                 int var42 = var41.getBlockId();
                                 int var43 = var41.getRotation();
                                 if (var7) {
                                    BlockType var44 = var19.getAsset(var42);
                                    String var45 = Objects.requireNonNullElse(var44.getDefaultStateKey(), var44.getId());
                                    String var46 = BuilderToolsPlugin.getBlockShape(var40);
                                    if (!var46.isEmpty()) {
                                       int var47 = var21.computeIfAbsent(
                                          var45 + "|" + var46,
                                          var5x -> {
                                             int var6 = var19.getIndex(var45 + "_" + var46);
                                             class="kw">return var6 != Integer.MIN_VALUE && !var11.isExcludedQuality(var6)
                                                ? var6
                                                : var11.findClosestVariant(var41.getBlockId(), var46);
                                          }
                                       );
                                       if (var47 != Integer.MIN_VALUE && var47 >= 0) {
                                          var42 = var47;
                                       }
                                    }

                                    var43 = var37.getRotationIndex(var34, var35, var36);
                                 }

                                 BlockType var51 = var19.getAsset(var40);
                                 String var52 = var51 != null ? var51.getStateForBlock(var39.getId()) : null;
                                 if (var52 != null && !var52.equals("class="kw">default")) {
                                    BlockType var53 = var19.getAsset(var42);
                                    String var54 = var53 != null ? var53.getBlockKeyForState(var52) : null;
                                    if (var54 != null) {
                                       int var48 = var19.getIndex(var54);
                                       if (var48 != Integer.MIN_VALUE) {
                                          var42 = var48;
                                       }
                                    }
                                 }

                                 FillerPlacementUtil.stampBlockWithFiller(var17, var28, var29, var30, var34, var35, var36, var42, var43, false);
                              }
                           }
                        }
                     }
                  }
               }
            }

            this.handleBrushUndoGrouping(var28, Collections.emptyList(), Collections.emptyList(), var9, var10);
            var29.placeNoReturn("Color", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var13, var12);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var29, var13);
            this.sendUpdate();
            this.sendArea();
         }
      }

      class="kw">private class="kw">static float edgeBlendFactor(@Nonnull BrushShape var0, int var1, int var2, int var3, int var4, int var5, float var6) {
         if (var6 <= 0.0F) {
            class="kw">return 1.0F;
         }

         double var7 = var4 + 0.5;
         double var9 = var5 + 0.5;

         double var11 = class="kw">switch (var0) {
            case Cube, Pyramid, InvertedPyramid, Diamond -> Math.max(Math.abs(var1) / var7, Math.max(Math.abs(var2) / var9, Math.abs(var3) / var7));
            class="kw">default -> Math.sqrt(var1 * var1 / (var7 * var7) + var2 * var2 / (var9 * var9) + var3 * var3 / (var7 * var7));
         };
         double var13 = 1.0 - var6;
         class="kw">return var11 <= var13 ? 1.0F : (float)Math.max(0.0, (1.0 - var11) / var6);
      }

      class="kw">public void applyGradient(
         int var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         int var9,
         int var10,
         int var11,
         @Nonnull List<BuilderToolsPlugin.ColorGradientMaterial> var12,
         @Nonnull String var13,
         float var14,
         @Nonnull BrushShape var15,
         boolean var16,
         int var17,
         boolean var18,
         @Nonnull ComponentAccessor<EntityStore> var19
      ) {
         if (var12.size() >= 2) {
            World var20 = var19.getExternalData().getWorld();
            if ("Linear".equals(var13)) {
               this.applyLinearGradient(
                  var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var14, var15, var16, var17, var18, var20, var19
               );
            } else {
               this.applyShapedGradient(
                  var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var20, var19
               );
            }
         }
      }

      class="kw">private void applyLinearGradient(
         int var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         int var9,
         int var10,
         int var11,
         @Nonnull List<BuilderToolsPlugin.ColorGradientMaterial> var12,
         float var13,
         @Nonnull BrushShape var14,
         boolean var15,
         int var16,
         boolean var17,
         @Nonnull World var18,
         @Nonnull ComponentAccessor<EntityStore> var19
      ) {
         double var20 = Math.sqrt((var9 - var6) * (var9 - var6) + (var10 - var7) * (var10 - var7) + (var11 - var8) * (var11 - var8));
         if (!(var20 < 1.0)) {
            double var22 = (var9 - var6) / var20;
            double var24 = (var10 - var7) / var20;
            double var26 = (var11 - var8) / var20;
            int var28 = var4 / 2;
            int var29 = var5 / 2;
            int var30 = var28;
            int var31 = var29;
            int var32 = var28;
            Predicate var33 = this.createShapePredicate(var14, var28, var29, 0.0F, 0.0F, false);
            Vector3i var34 = new Vector3i();
            int var35 = (var30 * 2 + 1) * (var31 * 2 + 1) * (var32 * 2 + 1);
            LocalCachedChunkAccessor var36 = LocalCachedChunkAccessor.atWorldCoords(var18, var1, var3, Math.max(var30, var32) + 2);
            BlockSelection var37 = new BlockSelection(var35, 0);
            var37.setPosition(var1, var2, var3);
            BlockSelection var38 = new BlockSelection(var35, 0);
            var38.copyPropertiesFrom(var37);
            LongOpenHashSet var39 = new LongOpenHashSet();

            for (int var40 = -var30; var40 <= var30; var40++) {
               for (int var41 = -var31; var41 <= var31; var41++) {
                  for (int var42 = -var32; var42 <= var32; var42++) {
                     int var43 = var1 + var40;
                     int var44 = var2 + var41;
                     int var45 = var3 + var42;
                     if (var44 >= 0 && var44 < 320) {
                        var34.set(var40, var41, var42);
                        if (var33.test(var34)) {
                           WorldChunk var46 = var36.getChunk(ChunkUtil.indexChunkFromBlock(var43, var45));
                           int var47 = var46.getBlock(var43, var44, var45);
                           if (var47 > 0 && isGradientRecolorable(var47, var46.getFiller(var43, var44, var45), var46.getRotationIndex(var43, var44, var45))) {
                              double var48 = var43 - var6;
                              double var50 = var44 - var7;
                              double var52 = var45 - var8;
                              double var54 = (var48 * var22 + var50 * var24 + var52 * var26) / var20;
                              float var56 = (float)Math.max(0.0, Math.min(1.0, var54));
                              if (var15) {
                                 var56 = 1.0F - var56;
                              }

                              BlockPattern var57 = this.getGradientMaterialAtPosition(var12, var56, var13);
                              if (var57 != null) {
                                 this.applyGradientBlock(var36, var37, var38, var39, var43, var44, var45, var57);
                              }
                           }
                        }
                     }
                  }
               }
            }

            this.handleBrushUndoGrouping(var37, Collections.emptyList(), Collections.emptyList(), var16, var17);
            var38.placeNoReturn("Gradient", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var18, var19);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var38, var18);
            this.sendUpdate();
            this.sendArea();
         }
      }

      class="kw">private void applyShapedGradient(
         int var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         int var9,
         int var10,
         int var11,
         @Nonnull List<BuilderToolsPlugin.ColorGradientMaterial> var12,
         @Nonnull String var13,
         float var14,
         @Nonnull BrushShape var15,
         boolean var16,
         int var17,
         boolean var18,
         @Nonnull World var19,
         @Nonnull ComponentAccessor<EntityStore> var20
      ) {
         double var21 = Math.sqrt((var9 - var6) * (var9 - var6) + (var10 - var7) * (var10 - var7) + (var11 - var8) * (var11 - var8));
         if (!(var21 < 1.0)) {
            int var23 = var4 / 2;
            int var24 = var5 / 2;
            int var25 = var23;
            int var26 = var24;
            int var27 = var23;
            Predicate var28 = this.createShapePredicate(var15, var23, var24, 0.0F, 0.0F, false);
            Vector3i var29 = new Vector3i();
            int var30 = (var25 * 2 + 1) * (var26 * 2 + 1) * (var27 * 2 + 1);
            LocalCachedChunkAccessor var31 = LocalCachedChunkAccessor.atWorldCoords(var19, var1, var3, Math.max(var25, var27) + 2);
            BlockSelection var32 = new BlockSelection(var30, 0);
            var32.setPosition(var1, var2, var3);
            BlockSelection var33 = new BlockSelection(var30, 0);
            var33.copyPropertiesFrom(var32);
            LongOpenHashSet var34 = new LongOpenHashSet();

            for (int var35 = -var25; var35 <= var25; var35++) {
               for (int var36 = -var26; var36 <= var26; var36++) {
                  for (int var37 = -var27; var37 <= var27; var37++) {
                     int var38 = var1 + var35;
                     int var39 = var2 + var36;
                     int var40 = var3 + var37;
                     if (var39 >= 0 && var39 < 320) {
                        var29.set(var35, var36, var37);
                        if (var28.test(var29)) {
                           WorldChunk var41 = var31.getChunk(ChunkUtil.indexChunkFromBlock(var38, var40));
                           int var42 = var41.getBlock(var38, var39, var40);
                           if (var42 > 0 && isGradientRecolorable(var42, var41.getFiller(var38, var39, var40), var41.getRotationIndex(var38, var39, var40))) {
                              double var43 = var38 - var6;
                              double var45 = var39 - var7;
                              double var47 = var40 - var8;
                              double var49 = Math.abs(var43);
                              double var51 = Math.abs(var45);
                              double var53 = Math.abs(var47);

                              double var55 = class="kw">switch (var13) {
                                 case "Cube" -> Math.max(var49, Math.max(var51, var53));
                                 case "Diamond" -> var49 + var51 + var53;
                                 case "Cylinder" -> Math.max(Math.sqrt(var43 * var43 + var47 * var47), var51);
                                 class="kw">default -> Math.sqrt(var43 * var43 + var45 * var45 + var47 * var47);
                              };
                              float var59 = (float)Math.min(1.0, var55 / var21);
                              if (var16) {
                                 var59 = 1.0F - var59;
                              }

                              BlockPattern var60 = this.getGradientMaterialAtPosition(var12, var59, var14);
                              if (var60 != null) {
                                 this.applyGradientBlock(var31, var32, var33, var34, var38, var39, var40, var60);
                              }
                           }
                        }
                     }
                  }
               }
            }

            this.handleBrushUndoGrouping(var32, Collections.emptyList(), Collections.emptyList(), var17, var18);
            var33.placeNoReturn("Gradient", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var19, var20);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var33, var19);
            this.sendUpdate();
            this.sendArea();
         }
      }

      class="kw">private void applyGradientBlock(
         @Nonnull LocalCachedChunkAccessor var1,
         @Nonnull BlockSelection var2,
         @Nonnull BlockSelection var3,
         @Nonnull LongOpenHashSet var4,
         int var5,
         int var6,
         int var7,
         @Nonnull BlockPattern var8
      ) {
         Material var9 = Material.fromPattern(var8, this.random);
         FillerPlacementUtil.stampBlockWithFiller(var1, var2, var3, var4, var5, var6, var7, var9.getBlockId(), var9.getRotation(), false);
      }

      @Nullable
      class="kw">private BlockPattern getGradientMaterialAtPosition(@Nonnull List<BuilderToolsPlugin.ColorGradientMaterial> var1, float var2, float var3) {
         float var4 = 0.0F;
         int var5 = var1.size() - 1;

         for (int var6 = 0; var6 < var1.size(); var6++) {
            var4 += var1.get(var6).weight / 100.0F;
            if (var2 <= var4) {
               var5 = var6;
               break;
            }
         }

         if (var3 <= 0.0F) {
            class="kw">return var1.get(var5).pattern;
         }

         float var10 = var4 - var1.get(var5).weight / 100.0F;
         if (var5 < var1.size() - 1 && var4 - var2 < var3) {
            float var11 = var1.get(var5 + 1).weight / 100.0F;
            float var12 = Math.min(var3, Math.min(var4 - var10, var11));
            if (var4 - var2 < var12) {
               float var13 = 0.5F * (1.0F - (var4 - var2) / var12);
               if (this.random.nextFloat() < var13) {
                  class="kw">return var1.get(var5 + 1).pattern;
               }
            }
         } else if (var5 > 0 && var2 - var10 < var3) {
            float var7 = var1.get(var5 - 1).weight / 100.0F;
            float var8 = Math.min(var3, Math.min(var4 - var10, var7));
            if (var2 - var10 < var8) {
               float var9 = 0.5F * (1.0F - (var2 - var10) / var8);
               if (this.random.nextFloat() < var9) {
                  class="kw">return var1.get(var5 - 1).pattern;
               }
            }
         }

         class="kw">return var1.get(var5).pattern;
      }

      class="kw">public void applyShading(
         int var1,
         int var2,
         int var3,
         float var4,
         float var5,
         float var6,
         int var7,
         int var8,
         boolean var9,
         boolean var10,
         boolean var11,
         @Nonnull BuilderToolsPlugin.ShadingLight var12,
         @Nullable int[] var13,
         float var14,
         @Nonnull BrushShape var15,
         boolean var16,
         float var17,
         int var18,
         boolean var19,
         @Nonnull BlockColorIndex var20,
         @Nonnull ComponentAccessor<EntityStore> var21
      ) {
         World var22 = var21.getExternalData().getWorld();
         int var23 = var7 / 2;
         int var24 = var8 / 2;
         int var25 = Math.max(var23, var24);
         boolean var26 = var12 != BuilderToolsPlugin.ShadingLight.PLAYER || var11;
         double var27 = var26 ? var1 + 0.5 : var4;
         double var29 = var26 ? var2 + 0.5 : var5;
         double var31 = var26 ? var3 + 0.5 : var6;
         double var33 = var4 - var1;
         double var35 = var6 - var3;
         int var37 = (int)Math.ceil(Math.min(48.0, Math.sqrt(var33 * var33 + var35 * var35)));
         LocalCachedChunkAccessor var38 = LocalCachedChunkAccessor.atWorldCoords(var22, var1, var3, var25 + var37);
         int var39 = (var7 + 1) * (var8 + 1) * (var7 + 1);
         BlockSelection var40 = new BlockSelection(var39, 0);
         var40.setPosition(var1, var2, var3);
         BlockSelection var41 = new BlockSelection(var39, 0);
         var41.copyPropertiesFrom(var40);
         Predicate var42 = this.createShapePredicate(var15, var23, var24, 0.0F, 0.0F, false);
         Vector3i var43 = new Vector3i();

         for (int var44 = -var23; var44 <= var23; var44++) {
            for (int var45 = -var24; var45 <= var24; var45++) {
               for (int var46 = -var23; var46 <= var23; var46++) {
                  int var47 = var1 + var44;
                  int var48 = var2 + var45;
                  int var49 = var3 + var46;
                  if (var48 >= 0 && var48 < 320) {
                     var43.set(var44, var45, var46);
                     if (var42.test(var43)) {
                        WorldChunk var50 = var38.getChunk(ChunkUtil.indexChunkFromBlock(var47, var49));
                        int var51 = var50.getBlock(var47, var48, var49);
                        if (var51 > 0 && isFullCubeBlock(var51, var50.getFiller(var47, var48, var49))) {
                           float var52 = edgeBlendFactor(var15, var44, var45, var46, var23, var24, var17);
                           if (!(var52 < 1.0F) || !(this.random.nextFloat() > var52)) {
                              float var53 = computeBlockExposure(var38, var47, var48, var49, var4, var5, var6, var27, var29, var31, var12);
                              int var54;
                              if (var13 != null) {
                                 float var55 = 0.5F + (var53 - 0.5F) * var14;
                                 int var56 = Math.round((1.0F - var55) * (var13.length - 1));
                                 var56 = Math.max(0, Math.min(var13.length - 1, var56));
                                 if (var16) {
                                    var56 = var13.length - 1 - var56;
                                 }

                                 var54 = var13[var56];
                              } else if (var10) {
                                 float var60 = (var53 - 0.5F) * 2.0F * var14;
                                 var60 = Math.max(-1.0F, Math.min(1.0F, var60));
                                 var54 = var60 >= 0.0F ? var20.findLighterVariant(var51, var60) : var20.findDarkerVariant(var51, -var60);
                              } else if (var9) {
                                 var54 = var20.findLighterVariant(var51, Math.min(1.0F, var53 * var14));
                              } else {
                                 var54 = var20.findDarkerVariant(var51, Math.min(1.0F, var53 * var14));
                              }

                              if (var54 != var51) {
                                 int var62 = var50.getRotationIndex(var47, var48, var49);
                                 Holder var64 = var50.getBlockComponentHolder(var47, var48, var49);
                                 Holder var57 = BuilderToolsPlugin.createBlockComponent(var50, var47, var48, var49, var54, var51, var64, false);
                                 int var58 = var50.getSupportValue(var47, var48, var49);
                                 int var59 = var50.getFiller(var47, var48, var49);
                                 var40.addBlockAtWorldPos(var47, var48, var49, var51, var62, var59, var58, var64);
                                 var41.addBlockAtWorldPos(var47, var48, var49, var54, var62, 0, 0, var57);
                              }
                           }
                        }
                     }
                  }
               }
            }
         }

         this.handleBrushUndoGrouping(var40, Collections.emptyList(), Collections.emptyList(), var18, var19);
         var41.placeNoReturn("Shading", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var22, var21);
         BuilderToolsPlugin.invalidateWorldMapForSelection(var41, var22);
         this.sendUpdate();
         this.sendArea();
      }

      class="kw">private class="kw">static float computeBlockExposure(
         @Nonnull LocalCachedChunkAccessor var0,
         int var1,
         int var2,
         int var3,
         float var4,
         float var5,
         float var6,
         double var7,
         double var9,
         double var11,
         @Nonnull BuilderToolsPlugin.ShadingLight var13
      ) {
         double[] var14 = estimateSurfaceNormalSobel(var0, var1, var2, var3);
         if (var14 == null) {
            class="kw">return 0.0F;
         }

         if (var13 == BuilderToolsPlugin.ShadingLight.ANGLE) {
            class="kw">return (float)((var14[1] + 1.0) / 2.0);
         }

         double var15 = var1 + 0.5;
         double var17 = var2 + 0.5;
         double var19 = var3 + 0.5;
         double var21;
         double var23;
         double var25;
         double var27;
         if (var13 == BuilderToolsPlugin.ShadingLight.SUN) {
            var21 = var15;
            var23 = var17 + 48.0;
            var25 = var19;
            var27 = 48.0;
         } else {
            var21 = var4;
            var23 = var5;
            var25 = var6;
            var27 = Math.sqrt((var4 - var15) * (var4 - var15) + (var5 - var17) * (var5 - var17) + (var6 - var19) * (var6 - var19));
            if (var27 < 1.0E-6) {
               class="kw">return 1.0F;
            }
         }

         double var29 = (var21 - var15) / var27;
         double var31 = (var23 - var17) / var27;
         double var33 = (var25 - var19) / var27;
         double var35 = Math.max(0.0, var14[0] * var29 + var14[1] * var31 + var14[2] * var33);
         double var37 = var7 - var15;
         double var39 = var9 - var17;
         double var41 = var11 - var19;
         double var43 = Math.sqrt(var37 * var37 + var39 * var39 + var41 * var41);
         boolean var45 = var43 > 48.0 || countLineOfSightOccluders(var0, var1, var2, var3, var21, var23, var25, var27) > 0;
         double var46 = var45 ? 0.0 : 1.0;
         double var48 = Math.max(0.0, 1.0 - var43 / 48.0);
         double var50 = var35 * var46 * var48;
         double var52 = 0.2 * (0.5 + 0.5 * var14[1]);
         class="kw">return (float)Math.min(1.0, var52 + 0.8 * var50);
      }

      @Nullable
      class="kw">private class="kw">static double[] estimateSurfaceNormalSobel(@Nonnull LocalCachedChunkAccessor var0, int var1, int var2, int var3) {
         double var4 = 0.0;
         double var6 = 0.0;
         double var8 = 0.0;
         int var10 = 0;

         for (int var11 = -2; var11 <= 2; var11++) {
            for (int var12 = -2; var12 <= 2; var12++) {
               for (int var13 = -2; var13 <= 2; var13++) {
                  if (!isBlockSolidCover(var0, var1 + var11, var2 + var12, var3 + var13)) {
                     if (Math.abs(var11) <= 1 && Math.abs(var12) <= 1 && Math.abs(var13) <= 1) {
                        var10++;
                     }
                  } else {
                     int var14 = var11 + 2;
                     int var15 = var12 + 2;
                     int var16 = var13 + 2;
                     var4 += SOBEL_DERIV[var14] * SOBEL_SMOOTH[var15] * SOBEL_SMOOTH[var16];
                     var6 += SOBEL_SMOOTH[var14] * SOBEL_DERIV[var15] * SOBEL_SMOOTH[var16];
                     var8 += SOBEL_SMOOTH[var14] * SOBEL_SMOOTH[var15] * SOBEL_DERIV[var16];
                  }
               }
            }
         }

         if (var10 == 0) {
            class="kw">return null;
         }

         double var19 = -var4;
         double var20 = -var6;
         double var21 = -var8;
         double var17 = Math.sqrt(var19 * var19 + var20 * var20 + var21 * var21);
         class="kw">return var17 < 1.0E-6 ? new double[]{0.0, 1.0, 0.0} : new double[]{var19 / var17, var20 / var17, var21 / var17};
      }

      class="kw">private class="kw">static int countLineOfSightOccluders(
         @Nonnull LocalCachedChunkAccessor var0, int var1, int var2, int var3, double var4, double var6, double var8, double var10
      ) {
         if (var10 < 1.0E-6) {
            class="kw">return 0;
         }

         double var12 = var1 + 0.5;
         double var14 = var2 + 0.5;
         double var16 = var3 + 0.5;
         double var18 = (var4 - var12) / var10;
         double var20 = (var6 - var14) / var10;
         double var22 = (var8 - var16) / var10;
         int var24 = var1;
         int var25 = var2;
         int var26 = var3;
         int var27 = var18 > 0.0 ? 1 : (var18 < 0.0 ? -1 : 0);
         int var28 = var20 > 0.0 ? 1 : (var20 < 0.0 ? -1 : 0);
         int var29 = var22 > 0.0 ? 1 : (var22 < 0.0 ? -1 : 0);
         double var30 = var27 != 0 ? voxelBoundaryT(var12, var18, var27) : Double.MAX_VALUE;
         double var32 = var28 != 0 ? voxelBoundaryT(var14, var20, var28) : Double.MAX_VALUE;
         double var34 = var29 != 0 ? voxelBoundaryT(var16, var22, var29) : Double.MAX_VALUE;
         double var36 = var27 != 0 ? 1.0 / Math.abs(var18) : Double.MAX_VALUE;
         double var38 = var28 != 0 ? 1.0 / Math.abs(var20) : Double.MAX_VALUE;
         double var40 = var29 != 0 ? 1.0 / Math.abs(var22) : Double.MAX_VALUE;
         double var42 = Math.min(var10, 48.0);
         int var44 = 0;
         double var45 = 0.0;

         while (var45 < var42) {
            if (var30 <= var32 && var30 <= var34) {
               var24 += var27;
               var45 = var30;
               var30 += var36;
            } else if (var32 <= var34) {
               var25 += var28;
               var45 = var32;
               var32 += var38;
            } else {
               var26 += var29;
               var45 = var34;
               var34 += var40;
            }

            if (var45 >= var42) {
               break;
            }

            if (var25 >= 0 && var25 < 320 && isBlockSolidCover(var0, var24, var25, var26)) {
               var44++;
            }
         }

         class="kw">return var44;
      }

      class="kw">private class="kw">static double voxelBoundaryT(double var0, double var2, int var4) {
         double var5 = var4 > 0 ? Math.floor(var0) + 1.0 : Math.floor(var0);
         class="kw">return (var5 - var0) / var2;
      }

      class="kw">public void update(int var1, int var2, int var3, int var4, int var5, int var6) {
         if (this.selection == null) {
            this.selection = new BlockSelection();
         }

         this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
         this.selection.setSelectionArea(new Vector3i(var1, var2, var3), new Vector3i(var4, var5, var6));
         this.syncRawPositions();
      }

      class="kw">public void tint(@Nonnull Ref<EntityStore> var1, int var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var3);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var3);
         } else {
            World var4 = var3.getExternalData().getWorld();
            int var5 = 0;
            int var6 = this.selection.getSelectionMin().x();
            int var7 = this.selection.getSelectionMin().z();
            int var8 = this.selection.getSelectionMax().x();
            int var9 = this.selection.getSelectionMax().z();
            BlockSelection var10 = new BlockSelection();
            var10.setPosition(var6, 0, var7);

            for (int var11 = var6; var11 < var8; var11++) {
               for (int var12 = var7; var12 < var9; var12++) {
                  var10.addTintAtWorldPos(var11, var12, var2);
                  var5++;
               }
            }

            BlockSelection var13 = var10.place(null, var4);
            this.pushHistory(BuilderToolsPlugin.Action.EDIT, new BlockSelectionSnapshot(var13));
            this.sendFeedback(Message.translation("server.builderTools.setColumnsTint").param("count", var5), var3);
         }
      }

      class="kw">public void environment(@Nonnull Ref<EntityStore> var1, int var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var3);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var3);
         } else {
            World var4 = var3.getExternalData().getWorld();
            LongSet var5 = new LongOpenHashSet();
            int var6 = 0;

            for (int var7 = this.selection.getSelectionMin().x(); var7 < this.selection.getSelectionMax().x(); var7++) {
               for (int var8 = this.selection.getSelectionMin().z(); var8 < this.selection.getSelectionMax().z(); var8++) {
                  WorldChunk var9 = var4.getChunk(ChunkUtil.indexChunkFromBlock(var7, var8));
                  var5.add(var9.getIndex());

                  for (int var10 = this.selection.getSelectionMin().y(); var10 < this.selection.getSelectionMax().y(); var10++) {
                     var9.getBlockChunk().setEnvironment(var7, var10, var8, var2);
                     var6++;
                  }
               }
            }

            var5.forEach(var1x -> var4.getNotificationHandler().updateChunkEnvironments(var1x));
            this.sendFeedback(Message.translation("server.builderTools.setEnvironment").param("count", var6), var3);
         }
      }

      class="kw">public int copyOrCut(
         @Nonnull Ref<EntityStore> var1, int var2, int var3, int var4, int var5, int var6, int var7, int var8, @Nonnull ComponentAccessor<EntityStore> var9
      ) class="kw">throws PrefabCopyException {
         class="kw">return this.copyOrCut(var1, var2, var3, var4, var5, var6, var7, var8, null, null, var9);
      }

      class="kw">public int copyOrCut(
         @Nonnull Ref<EntityStore> var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         @Nullable Vector3i var9,
         @Nonnull ComponentAccessor<EntityStore> var10
      ) class="kw">throws PrefabCopyException {
         class="kw">return this.copyOrCut(var1, var2, var3, var4, var5, var6, var7, var8, var9, null, var10);
      }

      class="kw">public int copyOrCut(
         @Nonnull Ref<EntityStore> var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         @Nullable Vector3i var9,
         @Nullable Set<Ref<EntityStore>> var10,
         @Nonnull ComponentAccessor<EntityStore> var11
      ) class="kw">throws PrefabCopyException {
         class="kw">return this.copyOrCut(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, null, var11);
      }

      class="kw">public int copyOrCut(
         @Nonnull Ref<EntityStore> var1,
         int var2,
         int var3,
         int var4,
         int var5,
         int var6,
         int var7,
         int var8,
         @Nullable Vector3i var9,
         @Nullable Set<Ref<EntityStore>> var10,
         @Nullable List<SelectionSnapshot<?>> var11,
         @Nonnull ComponentAccessor<EntityStore> var12
      ) class="kw">throws PrefabCopyException {
         World var13 = var12.getExternalData().getWorld();
         long var14 = System.nanoTime();
         if (this.selection == null) {
            this.selection = new BlockSelection();
         }

         BlockSelection var16 = null;
         BlockSelection var17 = null;
         List var18 = Collections.emptyList();
         boolean var19 = (var8 & 2) != 0;
         boolean var20 = (var8 & 4) != 0;
         boolean var21 = (var8 & 8) != 0;
         boolean var22 = (var8 & 16) != 0;
         boolean var23 = (var8 & 64) != 0;
         int var24 = var5 - var2;
         int var25 = var6 - var3;
         int var26 = var7 - var4;
         long var27 = Vector3iUtil.inclusiveBoxVolume(var2, var3, var4, var5, var6, var7);
         if (var27 >= 16000000L) {
            if (BuilderToolsPlugin.shouldShowNotification(var1, var12)) {
               NotificationUtil.sendNotification(
                  this.playerRef.getPacketHandler(),
                  Message.translation("server.builderTools.copycut.tooLarge"),
                  Message.translation("server.builderTools.copycut.tooLarge.detail").param("overCount", var27 - 16000000L),
                  NotificationStyle.Warning
               );
               SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex("CREATE_ERROR"), SoundCategory.UI, var12);
            }

            class="kw">return 0;
         } else {
            int var29 = Math.abs(var25);
            if (var29 >= 512L) {
               if (BuilderToolsPlugin.shouldShowNotification(var1, var12)) {
                  NotificationUtil.sendNotification(
                     this.playerRef.getPacketHandler(),
                     Message.translation("server.builderTools.copycut.tooTall"),
                     Message.translation("server.builderTools.copycut.tooTall.detail").param("max", 511),
                     NotificationStyle.Warning
                  );
                  SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex("CREATE_ERROR"), SoundCategory.UI, var12);
               }

               class="kw">return 0;
            } else {
               int var30 = var24 / 2;
               int var31 = var26 / 2;
               ClipboardContentsSnapshot var32 = ClipboardContentsSnapshot.copyOf(this.selection);
               if (var19) {
                  var16 = new BlockSelection();
                  var16.setPosition(var2 + var30, var3, var4 + var31);
                  var16.setSelectionArea(
                     new Vector3i(Math.min(var2, var5), Math.min(var3, var6), Math.min(var4, var7)),
                     new Vector3i(Math.max(var2, var5), Math.max(var3, var6), Math.max(var4, var7))
                  );
                  var17 = new BlockSelection(var16);
                  var18 = new ObjectArrayList();
               } else if (var11 != null) {
                  var11.add(var32);
               } else {
                  this.pushHistory(BuilderToolsPlugin.Action.COPY, var32);
               }

               LocalCachedChunkAccessor var33 = LocalCachedChunkAccessor.atWorldCoords(var13, var2 + var30, var4 + var31, Math.max(var24, var26));
               BlockTypeAssetMap var34 = BlockType.getAssetMap();
               int var35 = var34.getIndex("Editor_Block");
               if (var35 == Integer.MIN_VALUE) {
                  throw new IllegalArgumentException("Unknown key! Editor_Block");
               }

               int var36 = var34.getIndex("Editor_Empty");
               if (var36 == Integer.MIN_VALUE) {
                  throw new IllegalArgumentException("Unknown key! Editor_Empty");
               }

               int var37 = var34.getIndex("Editor_Anchor");
               if (var37 == Integer.MIN_VALUE) {
                  throw new IllegalArgumentException("Unknown key! Editor_Anchor");
               }

               Set var38 = new HashSet<>();
               Vector3i var39 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               Vector3i var40 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               this.selection = new BlockSelection();
               this.preRotationSnapshot = null;
               this.selection.setPosition(var2 + var30, var3, var4 + var31);
               this.selection.setSelectionArea(var39, var40);
               this.syncRawPositions();
               int var41 = 0;
               int var42 = 0;
               int var43 = Math.max(var3, var6);
               int var44 = Math.min(var3, var6);
               int var45 = (int)var27;

               for (long var46 = var2; var46 <= var5; var46++) {
                  int var48 = (int)var46;

                  for (long var49 = var4; var49 <= var7; var49++) {
                     int var51 = (int)var49;
                     WorldChunk var52 = var33.getChunk(ChunkUtil.indexChunkFromBlock(var48, var51));
                     Store var53 = var52.getReference().getStore();
                     ChunkColumn var54 = var53.getComponent(var52.getReference(), ChunkColumn.getComponentType());
                     int var55 = -1;
                     BlockPhysics var56 = null;

                     for (long var57 = var43; var57 >= var44; var57--) {
                        int var59 = (int)var57;
                        int var60 = var52.getBlock(var48, var59, var51);
                        int var61 = var52.getFluidId(var48, var59, var51);
                        if (var55 != ChunkUtil.chunkCoordinate(var59)) {
                           var55 = ChunkUtil.chunkCoordinate(var59);
                           Ref var62 = var54.getSection(var55);
                           if (var62 != null) {
                              var56 = var53.getComponent(var62, BlockPhysics.getComponentType());
                           } else {
                              var56 = null;
                           }
                        }

                        if (var21 && var19 && (var60 != 0 || var61 != 0 || var20)) {
                           var16.copyFromAtWorld(var48, var59, var51, var52, var56);
                           var17.addEmptyAtWorldPos(var48, var59, var51);
                        }

                        if (var60 == var37 && !var23 && var9 == null) {
                           var38.add(new Vector3i(var48, var59, var51));
                           this.selection.setAnchorAtWorldPos(var48, var59, var51);
                           if (var21) {
                              int var85 = BuilderToolsPlugin.getNonEmptyNeighbourBlock(var33, var48, var59, var51);
                              if (var85 > 0 && var85 != var36) {
                                 this.selection.addBlockAtWorldPos(var48, var59, var51, var85, 0, 0, 0);
                                 var41++;
                              } else if (var85 == var36) {
                                 this.selection.addBlockAtWorldPos(var48, var59, var51, 0, 0, 0, 0);
                                 var41++;
                              }
                           }
                        } else if (var21 && (var60 != 0 || var61 != 0 || var20) && var60 != var35) {
                           this.selection.copyFromAtWorld(var48, var59, var51, var52, var56);
                           var41++;
                        }

                        var42++;
                        this.sendFeedback(var19 ? "Gather 1/2" : "Gather 1/1", var45, var42, var12);
                     }
                  }
               }

               if (var41 > 16000000) {
                  this.selection = new BlockSelection();
                  this.preRotationSnapshot = null;
                  NotificationUtil.sendNotification(
                     this.playerRef.getPacketHandler(),
                     Message.translation("server.builderTools.copycut.tooLarge"),
                     Message.translation("server.builderTools.copycut.tooLarge.detail").param("overCount", var41 - 16000000),
                     NotificationStyle.Warning
                  );
                  SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex("CREATE_ERROR"), SoundCategory.UI, var12);
                  class="kw">return 0;
               }

               if (var38.size() > 1 && var9 == null) {
                  StringBuilder var65 = new StringBuilder("Anchors: ");
                  boolean var67 = true;

                  for (Vector3i var73 : var38) {
                     if (!var67) {
                        var65.append(", ");
                     }

                     var67 = false;
                     var65.append('[').append(var73.x()).append(", ").append(var73.y()).append(", ").append(var73.z()).append(']');
                  }

                  throw new PrefabCopyException("Prefab has multiple anchor blocks!\n" + var65);
               } else {
                  if (var9 != null) {
                     this.selection.setAnchorAtWorldPos(var9.x(), var9.y(), var9.z());
                  }

                  if (var22) {
                     List var63 = var18;
                     Store var47 = var13.getEntityStore().getStore();
                     ReferenceArrayList var68 = var19 ? new ReferenceArrayList() : null;
                     Set var71 = var10;
                     BuilderToolsPlugin.forEachCopyableInSelection(var13, var2, var3, var4, var24, var25, var26, var6x -> {
                        Holder var7 = var47.copyEntity(var6x);
                        this.selection.addEntityFromWorld(var7);
                        if (var19) {
                           boolean var8 = var71 != null && var71.contains(var6x);
                           if (!var8) {
                              var63.add(new EntityRemoveSnapshot(var6x));
                              var68.add(var6x);
                           }
                        }
                     });
                     if (var19 && var68 != null) {
                        ObjectListIterator var50 = var68.iterator();

                        while (var50.hasNext()) {
                           Ref var75 = (Ref<EntityStore>)var50.next();
                           var47.removeEntity(var75, RemoveReason.UNLOAD);
                        }
                     }
                  }

                  int var64 = Math.min(var2, var5);
                  int var66 = Math.min(var3, var6);
                  int var69 = Math.min(var4, var7);
                  int var72 = Math.max(var2, var5);
                  int var74 = Math.max(var3, var6);
                  int var76 = Math.max(var4, var7);

                  for (PrefabSaveContributor var79 : BuilderToolsPlugin.get().getClipboardContributors()) {
                     var79.contribute(this.selection, var13, new Vector3i(var64, var66, var69), new Vector3i(var72, var74, var76));
                  }

                  if (var19) {
                     var18.add(new BlockSelectionSnapshot(var16));
                     var18.add(var32);
                     if (var11 != null) {
                        var11.addAll(var18);
                     } else {
                        this.pushHistory(BuilderToolsPlugin.Action.CUT_REMOVE, var18);
                     }
                  }

                  if (var17 != null) {
                     var17.placeNoReturn("Cut 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var13, var12);
                     BuilderToolsPlugin.invalidateWorldMapForSelection(var17, var13);
                  }

                  long var78 = System.nanoTime();
                  long var80 = var78 - var14;
                  int var81 = var41;
                  BuilderToolsPlugin.get()
                     .getLogger()
                     .at(Level.FINE)
                     .log("Took: %dns (%dms) to execute copy of %d blocks", var80, TimeUnit.NANOSECONDS.toMillis(var80), var81);
                  if (var19) {
                     this.sendUpdate();
                  } else {
                     BlockSelection var82 = Objects.requireNonNullElseGet(this.selection, BlockSelection::new);
                     this.playerRef.getPacketHandler().write(var82.getBlockCount() > 2000000 ? var82.toShapePacket(16000000) : var82.toPacketWithSelection());
                  }

                  String var83 = var19 ? "SFX_CREATE_CUT" : "SFX_CREATE_COPY";
                  if (var11 != null) {
                     SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex(var83), SoundCategory.UI, var12);
                  } else {
                     int var58 = var22 ? this.selection.getEntityCount() : 0;
                     String var84;
                     if (var19) {
                        var84 = var58 > 0 ? "server.builderTools.cutWithEntities" : "server.builderTools.cut";
                     } else {
                        var84 = var58 > 0 ? "server.builderTools.copiedWithEntities" : "server.builderTools.copied";
                     }

                     this.sendFeedback(var1, Message.translation(var84).param("blockCount", var81).param("entityCount", var58), var83, var12);
                  }

                  class="kw">return var41;
               }
            }
         }
      }

      class="kw">public int clear(int var1, int var2, int var3, int var4, int var5, int var6, @Nonnull ComponentAccessor<EntityStore> var7) {
         long var8 = Vector3iUtil.inclusiveBoxVolume(var1, var2, var3, var4, var5, var6);
         if (this.editVolumeExceedsLimit(var8, var7)) {
            class="kw">return 0;
         }

         World var10 = var7.getExternalData().getWorld();
         long var11 = System.nanoTime();
         BlockSelection var13 = new BlockSelection();
         int var14 = var4 - var1;
         int var15 = var6 - var3;
         int var16 = var14 / 2;
         int var17 = var15 / 2;
         var13.setPosition(var1 + var16, var2, var3 + var17);
         var13.setSelectionArea(new Vector3i(var1, var2, var3), new Vector3i(var4, var5, var6));
         this.pushHistory(BuilderToolsPlugin.Action.CLEAR, new BlockSelectionSnapshot(var13));
         BlockSelection var18 = new BlockSelection(var13);
         LocalCachedChunkAccessor var19 = LocalCachedChunkAccessor.atWorldCoords(var10, var1 + var16, var3 + var17, Math.max(var14, var15));
         int var20 = Math.max(var2, var5);
         int var21 = Math.min(var2, var5);
         int var22 = (int)var8;
         int var23 = 0;

         for (long var24 = var1; var24 <= var4; var24++) {
            int var26 = (int)var24;

            for (long var27 = var3; var27 <= var6; var27++) {
               int var29 = (int)var27;
               WorldChunk var30 = var19.getChunk(ChunkUtil.indexChunkFromBlock(var26, var29));
               Store var31 = var30.getReference().getStore();
               ChunkColumn var32 = var31.getComponent(var30.getReference(), ChunkColumn.getComponentType());
               int var33 = -1;
               BlockPhysics var34 = null;

               for (long var35 = var20; var35 >= var21; var35--) {
                  int var37 = (int)var35;
                  int var38 = var30.getBlock(var26, var37, var29);
                  int var39 = var30.getFluidId(var26, var37, var29);
                  if (var33 != ChunkUtil.chunkCoordinate(var37)) {
                     var33 = ChunkUtil.chunkCoordinate(var37);
                     Ref var40 = var32.getSection(var33);
                     if (var40 != null) {
                        var34 = var31.getComponent(var40, BlockPhysics.getComponentType());
                     } else {
                        var34 = null;
                     }
                  }

                  if (var38 != 0 || var39 != 0) {
                     var13.copyFromAtWorld(var26, var37, var29, var30, var34);
                     var18.addEmptyAtWorldPos(var26, var37, var29);
                  }

                  this.sendFeedback("Clear 1/2", var22, ++var23, var7);
               }
            }
         }

         var18.placeNoReturn("Clear 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var10, var7);
         BuilderToolsPlugin.invalidateWorldMapForSelection(var18, var10);
         long var41 = System.nanoTime();
         long var42 = var41 - var11;
         int var28 = var18.getBlockCount();
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute clear of %d blocks", var42, TimeUnit.NANOSECONDS.toMillis(var42), var28);
         this.sendFeedback("Clear", var28, var7);
         class="kw">return var28;
      }

      class="kw">private class="kw">static Vector3d rotateByEulerMatrix(@Nonnull Vector3dc var0, @Nonnull RotationTuple var1) {
         Vector3d var2 = new Vector3d(var0);
         var1.roll().rotateZ(var2, var2);
         var1.pitch().rotateX(var2, var2);
         var1.yaw().rotateY(var2, var2);
         class="kw">return var2;
      }

      class="kw">public class="kw">static RotationTuple transformRotation(RotationTuple var0, Quaterniond var1) {
         Vector3d var2 = new Vector3d(1.0, 0.0, 0.0);
         Vector3d var3 = new Vector3d(0.0, 1.0, 0.0);
         var2 = rotateByEulerMatrix(var2, var0);
         var3 = rotateByEulerMatrix(var3, var0);
         Vector3d var4 = var1.transform(new Vector3d(var2.x, var2.y, var2.z));
         Vector3d var5 = var1.transform(new Vector3d(var3.x, var3.y, var3.z));
         Vector3d var6 = new Vector3d(var4.x, var4.y, var4.z);
         Vector3d var7 = new Vector3d(var5.x, var5.y, var5.z);
         double var8 = Float.MIN_VALUE;
         RotationTuple var10 = var0;

         for (RotationTuple var14 : RotationTuple.VALUES) {
            Vector3d var15 = rotateByEulerMatrix(new Vector3d(1.0, 0.0, 0.0), var14);
            Vector3d var16 = rotateByEulerMatrix(new Vector3d(0.0, 1.0, 0.0), var14);
            double var17 = var15.dot(var6) + var16.dot(var7);
            if (var17 > var8) {
               var8 = var17;
               var10 = var14;
            }
         }

         class="kw">return var10;
      }

      class="kw">public void transformThenPasteClipboard(
         @Nonnull BlockChange[] var1,
         @Nullable PrototypePlayerBuilderToolSettings.FluidChange[] var2,
         @Nullable PrototypePlayerBuilderToolSettings.EntityChange[] var3,
         @Nullable Holder<ChunkStore>[] var4,
         @Nonnull Quaterniond var5,
         @Nonnull Vector3i var6,
         @Nonnull Rotation3f var7,
         @Nonnull Vector3i var8,
         boolean var9,
         @Nonnull PrototypePlayerBuilderToolSettings var10,
         @Nullable List<SelectionSnapshot<?>> var11,
         ComponentAccessor<EntityStore> var12
      ) {
         World var13 = var12.getExternalData().getWorld();
         long var14 = System.nanoTime();
         BlockTypeAssetMap var16 = BlockType.getAssetMap();
         int var17 = var16.getIndex("Editor_Empty");
         int var18 = 0;

         for (BlockChange var22 : var1) {
            if (var22.y < 0 && Math.abs(var22.y) > var18) {
               var18 = Math.abs(var22.y);
            }
         }

         int var56 = var6.x + (int)var7.x;
         int var57 = var6.y + (int)var7.y;
         int var58 = var6.z + (int)var7.z;
         BlockSelection var59 = new BlockSelection();
         var59.setPosition(var56, var57, var58);
         BlockSelection var23 = new BlockSelection(var59);
         LocalCachedChunkAccessor var24 = LocalCachedChunkAccessor.atWorldCoords(var13, var56, var58, 50);
         int var25 = Integer.MAX_VALUE;
         int var26 = Integer.MAX_VALUE;
         int var27 = Integer.MAX_VALUE;
         int var28 = Integer.MIN_VALUE;
         int var29 = Integer.MIN_VALUE;
         int var30 = Integer.MIN_VALUE;

         record RotatedBlock(Vector3i location, int blockId, int newRotation, Holder<ChunkStore> holder, BlockType blockType, BlockBoundingBoxes hitbox) {
            RotatedBlock {
            }
         }

         ObjectArrayList var31 = new ObjectArrayList(var1.length);
         LongOpenHashSet var32 = new LongOpenHashSet(var1.length);
         Vector3d var33 = new Vector3d();

         for (int var34 = 0; var34 < var1.length; var34++) {
            BlockChange var35 = var1[var34];
            var33.set(var35.x - var7.x + var8.x + 0.5, var35.y - var7.y + var8.y + 0.5 + var18, var35.z - var7.z + var8.z + 0.5);
            var5.transform(var33);
            var33.add(var6.x, var6.y, var6.z);
            Vector3i var36 = new Vector3i(
               (int)Math.floor(var33.x + 0.1 + var7.x - 0.5), (int)Math.floor(var33.y + 0.1 + var7.y - 0.5), (int)Math.floor(var33.z + 0.1 + var7.z - 0.5)
            );
            var25 = Math.min(var25, var36.x);
            var26 = Math.min(var26, var36.y);
            var27 = Math.min(var27, var36.z);
            var28 = Math.max(var28, var36.x);
            var29 = Math.max(var29, var36.y);
            var30 = Math.max(var30, var36.z);
            int var37 = transformRotation(RotationTuple.get(var35.rotation), var5).index();
            int var38 = var35.block;
            if (var35.block == var17 && !var9) {
               var38 = 0;
            }

            BlockType var39 = var16.getAsset(var38);
            if (var39 != null) {
               BlockBoundingBoxes var40 = BlockBoundingBoxes.getAssetMap().getAsset(var39.getHitboxTypeIndex());
               if (var40 != null) {
                  Holder var41;
                  if (var4 != null && var34 < var4.length && var4[var34] != null) {
                     var41 = var4[var34].clone();
                  } else if (var39.getBlockEntity() != null) {
                     var41 = var39.getBlockEntity().clone();
                  } else {
                     var41 = null;
                  }

                  var31.add(new RotatedBlock(var36, var38, var37, var41, var39, var40));
                  var32.add(BlockUtil.pack(var36.x, var36.y, var36.z));
               }
            }
         }

         ObjectListIterator var60 = var31.iterator();

         while (var60.hasNext()) {
            RotatedBlock var62 = (RotatedBlock)var60.next();
            Vector3i var65 = var62.location();
            int var68 = var62.blockId();
            int var72 = var62.newRotation();
            Holder var77 = var62.holder();
            WorldChunk var84 = var24.getChunk(ChunkUtil.indexChunkFromBlock(var65.x, var65.z));
            int var90 = var84.getBlock(var65.x, var65.y, var65.z);
            int var42 = var84.getFiller(var65.x, var65.y, var65.z);
            int var43 = var84.getRotationIndex(var65.x, var65.y, var65.z);
            var59.addBlockAtWorldPos(var65.x, var65.y, var65.z, var90, var43, var42, 0, var77);
            int var44 = var84.getFluidId(var65.x, var65.y, var65.z);
            byte var45 = var84.getFluidLevel(var65.x, var65.y, var65.z);
            var59.addFluidAtWorldPos(var65.x, var65.y, var65.z, var44, var45);
            if (var62.hitbox().protrudesUnitBox()) {
               FillerBlockUtil.forEachFillerBlock(
                  var62.hitbox().get(var72),
                  (var3x, var4x, var5x) -> {
                     if (var3x != 0 || var4x != 0 || var5x != 0) {
                        int var6 = var65.x + var3x;
                        int var7 = var65.y + var4x;
                        int var8 = var65.z + var5x;
                        if (!var59.hasBlockAtWorldPos(var6, var7, var8)) {
                           WorldChunk var9 = var24.getChunk(ChunkUtil.indexChunkFromBlock(var6, var8));
                           var59.addBlockAtWorldPos(
                              var6,
                              var7,
                              var8,
                              var9.getBlock(var6, var7, var8),
                              var9.getRotationIndex(var6, var7, var8),
                              var9.getFiller(var6, var7, var8),
                              0,
                              var9.getBlockComponentHolder(var6, var7, var8)
                           );
                        }
                     }
                  }
               );
               FillerBlockUtil.forEachFillerBlock(var62.hitbox().get(var72), (var6x, var7x, var8x) -> {
                  int var9 = var65.x + var6x;
                  int var10 = var65.y + var7x;
                  int var11 = var65.z + var8x;
                  if (var6x == 0 && var7x == 0 && var8x == 0 || !var32.contains(BlockUtil.pack(var9, var10, var11))) {
                     boolean var12 = var6x == 0 && var7x == 0 && var8x == 0;
                     var23.addBlockAtWorldPos(var9, var10, var11, var68, var72, FillerBlockUtil.pack(var6x, var7x, var8x), 0, var12 ? var77 : null);
                  }
               });
            } else {
               var23.addBlockAtWorldPos(var65.x, var65.y, var65.z, var68, var72, 0, 0, var77);
            }
         }

         int var61 = var18;
         if (var2 != null) {
            for (PrototypePlayerBuilderToolSettings.FluidChange var73 : var2) {
               var33.set(var73.x() - var7.x + var8.x + 0.5, var73.y() - var7.y + var8.y + 0.5 + var61, var73.z() - var7.z + var8.z + 0.5);
               var5.transform(var33);
               var33.add(var6.x, var6.y, var6.z);
               Vector3i var78 = new Vector3i(
                  (int)Math.floor(var33.x + 0.1 + var7.x - 0.5), (int)Math.floor(var33.y + 0.1 + var7.y - 0.5), (int)Math.floor(var33.z + 0.1 + var7.z - 0.5)
               );
               var23.addFluidAtWorldPos(var78.x, var78.y, var78.z, var73.fluidId(), var73.fluidLevel());
            }
         }

         List var64 = var10.getLastTransformEntityRefs();
         List var67 = new ArrayList<>();
         if (var64 != null) {
            Store var70 = var13.getEntityStore().getStore();

            for (Ref var79 : var64) {
               if (var79 != null && var79.isValid()) {
                  var67.add(new EntityRemoveSnapshot(var79));
                  var70.removeEntity(var79, RemoveReason.UNLOAD);
               }
            }
         }

         List var71 = new ReferenceArrayList();
         if (var3 != null && var3.length > 0) {
            Vector3d var75 = new Vector3d();

            for (PrototypePlayerBuilderToolSettings.EntityChange var93 : var3) {
               boolean var96 = var93.entityHolder().getComponent(BlockEntity.getComponentType()) != null;
               double var98 = var96 ? 0.5 : 0.0;
               var75.set(var93.x() + var8.x - var7.x, var93.y() + var98 + var8.y - var7.y + var61, var93.z() + var8.z - var7.z);
               var5.transform(var75);
               var75.add(var6.x, var6.y, var6.z);
               double var46 = var75.x + var7.x;
               double var48 = var75.y + var7.y - var98;
               double var50 = var75.z + var7.z;
               Holder var52 = var93.entityHolder().clone();
               TransformComponent var53 = var52.getComponent(TransformComponent.getComponentType());
               if (var53 != null && var53.getPosition() != null) {
                  var53.getPosition().set(var46, var48, var50);
                  Rotation3f var54 = var53.getRotation();
                  if (var54 != null) {
                     var54.premul(var5);
                  }
               }

               HeadRotation var99 = var52.getComponent(HeadRotation.getComponentType());
               if (var99 != null && var99.getRotation() != null) {
                  var99.getRotation().premul(var5);
               }

               var52.putComponent(UUIDComponent.getComponentType(), new UUIDComponent(UUID.randomUUID()));
               if (var52.getComponent(EntityTrackerSystems.Visible.getComponentType()) != null) {
                  var52.removeComponent(EntityTrackerSystems.Visible.getComponentType());
               }

               if (var52.getComponent(NetworkId.getComponentType()) != null) {
                  var52.removeComponent(NetworkId.getComponentType());
               }

               Ref var55 = var12.addEntity(var52, AddReason.LOAD);
               if (var55 != null) {
                  var71.add(var55);
               }
            }
         }

         if (var25 != Integer.MAX_VALUE) {
            var59.setSelectionArea(new Vector3i(var25, var26, var27), new Vector3i(var28, var29, var30));
         }

         var10.setLastTransformEntityRefs(new ArrayList<>(var71));
         List var76 = new ObjectArrayList(var71.size() + var67.size() + 1);

         for (Ref var86 : var71) {
            var76.add(new EntityAddSnapshot(var86));
         }

         for (EntityRemoveSnapshot var87 : var67) {
            var76.add(var87);
         }

         BlockSelection var83 = var59;
         if (var11 != null) {
            for (SelectionSnapshot var92 : var11) {
               if (var92 class="kw">instanceof BlockSelectionSnapshot var94) {
                  BlockSelection var97 = var94.getBlockSelection();
                  mergeBeforeSelectionPreservingOriginal(var97, var83);
                  unionSelectionArea(var97, var83);
                  var83 = var97;
               } else {
                  var76.add(var92);
               }
            }
         }

         var76.add(new BlockSelectionSnapshot(var83));
         this.pushHistory(BuilderToolsPlugin.Action.TRANSFORM, var76);
         if (var11 != null) {
            var11.clear();
         }

         var23.placeNoReturn("Transform 1/1", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var13, var12);
         BuilderToolsPlugin.invalidateWorldMapForSelection(var23, var13);
         long var89 = System.nanoTime();
         long var95 = var89 - var14;
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute set of %d blocks", var95, TimeUnit.NANOSECONDS.toMillis(var95), var23.getBlockCount());
         this.sendUpdate();
         this.sendArea();
      }

      class="kw">public void transformSelectionPoints(@Nonnull Quaterniond var1, @Nonnull Vector3i var2, @Nonnull Rotation3f var3) {
         Vector3i var4 = this.transformBlockLocation(this.selection.getSelectionMin(), var1, var2, var3);
         Vector3i var5 = this.transformBlockLocation(this.selection.getSelectionMax(), var1, var2, var3);
         this.selection.setSelectionArea(Vector3iUtil.min(var4, var5), Vector3iUtil.max(var4, var5));
         this.syncRawPositions();
         this.sendUpdate();
         this.sendArea();
      }

      @Nonnull
      class="kw">public Vector3i transformBlockLocation(@Nonnull Vector3i var1, @Nonnull Quaterniond var2, @Nonnull Vector3i var3, @Nonnull Rotation3f var4) {
         Vector3d var5 = new Vector3d(var1.x - var4.x + 0.5, var1.y - var4.y + 0.5, var1.z - var4.z + 0.5);
         var2.transform(var5);
         var5.add(var3.x, var3.y, var3.z);
         class="kw">return new Vector3i(
            (int)Math.floor(var5.x + var4.x - 0.5 + 0.1), (int)Math.floor(var5.y + var4.y - 0.5 + 0.1), (int)Math.floor(var5.z + var4.z - 0.5 + 0.1)
         );
      }

      class="kw">public void layer(
         int var1,
         int var2,
         int var3,
         @Nonnull List<Pair<Integer, String>> var4,
         int var5,
         Vector3ic var6,
         WorldChunk var7,
         BlockSelection var8,
         BlockSelection var9
      ) {
         int var10 = var6.x() == 1 ? -1 : (var6.x() == -1 ? 1 : 0);
         int var11 = var6.y() == 1 ? -1 : (var6.y() == -1 ? 1 : 0);
         int var12 = var6.z() == 1 ? -1 : (var6.z() == -1 ? 1 : 0);

         for (int var13 = 0; var13 < var5; var13++) {
            if (var7.getBlock(var1 + var13 * var10 + var10, var2 + var13 * var11 + var11, var3 + var13 * var12 + var12) <= 0
               && this.attemptSetLayer(var1, var2, var3, var13, var4, var7, var8, var9)) {
               class="kw">return;
            }
         }
      }

      class="kw">public void layer(@Nonnull List<Pair<Integer, String>> var1, Vector3ic var2, ComponentAccessor<EntityStore> var3) {
         if (this.selection == null) {
            this.sendFeedback(Message.translation("server.builderTools.noSelection"), var3);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendFeedback(Message.translation("server.builderTools.noSelectionBounds"), var3);
         } else if (!this.selectionExceedsEditLimit(var3)) {
            int var4 = 0;

            for (Pair var6 : var1) {
               var4 += var6.left();
            }

            long var29 = System.nanoTime();
            Vector3i var7 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var8 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            int var9 = var7.x();
            int var10 = var8.x();
            int var11 = var7.y();
            int var12 = var8.y();
            int var13 = var7.z();
            int var14 = var8.z();
            BlockSelection var15 = new BlockSelection();
            int var16 = var10 - var9;
            int var17 = var14 - var13;
            int var18 = var16 / 2;
            int var19 = var17 / 2;
            var15.setPosition(var9 + var18, var11, var13 + var19);
            var15.setSelectionArea(var7, var8);
            this.pushHistory(BuilderToolsPlugin.Action.LAYER, new BlockSelectionSnapshot(var15));
            BlockSelection var20 = new BlockSelection(var15);
            World var21 = var3.getExternalData().getWorld();
            LocalCachedChunkAccessor var22 = LocalCachedChunkAccessor.atWorldCoords(var21, var9 + var18, var13 + var19, Math.max(var16, var17));

            for (int var23 = var9; var23 <= var10; var23++) {
               for (int var24 = var13; var24 <= var14; var24++) {
                  WorldChunk var25 = var22.getChunk(ChunkUtil.indexChunkFromBlock(var23, var24));

                  for (int var26 = var12; var26 >= var11; var26--) {
                     int var27 = var25.getBlock(var23, var26, var24);
                     int var28 = var25.getFluidId(var23, var26, var24);
                     if (var27 > 0 && (this.globalMask == null || !this.globalMask.isExcluded(var22, var23, var26, var24, var7, var8, var27, var28))) {
                        this.layer(var23, var26, var24, var1, var4, var2, var25, var15, var20);
                     }
                  }
               }
            }

            var20.placeNoReturn("Finished layer", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var21, var3);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var20, var21);
            long var30 = System.nanoTime();
            long var31 = var30 - var29;
            BuilderToolsPlugin.get().getLogger().at(Level.FINE).log("Took: %dns (%dms) to execute layer", var31, TimeUnit.NANOSECONDS.toMillis(var31));
            this.sendUpdate();
            this.sendArea();
         }
      }

      class="kw">private boolean attemptSetLayer(
         int var1, int var2, int var3, int var4, List<Pair<Integer, String>> var5, WorldChunk var6, BlockSelection var7, BlockSelection var8
      ) {
         int var9 = 0;

         for (Pair var11 : var5) {
            var9 += var11.left();
            if (var4 < var9) {
               int var12 = var6.getBlock(var1, var2, var3);
               int var13 = var6.getFiller(var1, var2, var3);
               Holder var14 = var6.getBlockComponentHolder(var1, var2, var3);
               int var15 = var6.getRotationIndex(var1, var2, var3);
               int var16 = var6.getSupportValue(var1, var2, var3);
               BlockPattern var17 = BlockPattern.parse((String)var11.right());
               int var18 = var17.nextBlock(this.random);
               Holder var19 = BuilderToolsPlugin.createBlockComponent(var6, var1, var2, var3, var18, var12, var14, true);
               var7.addBlockAtWorldPos(var1, var2, var3, var12, var15, var13, var16, var14);
               var8.addBlockAtWorldPos(var1, var2, var3, var18, var15, 0, 0, var19);
               class="kw">return true;
            }
         }

         class="kw">return false;
      }

      class="kw">public int paste(@Nonnull Ref<EntityStore> var1, int var2, int var3, int var4, @Nonnull ComponentAccessor<EntityStore> var5) {
         class="kw">return this.paste(var1, var2, var3, var4, false, false, var5);
      }

      class="kw">public int paste(@Nonnull Ref<EntityStore> var1, int var2, int var3, int var4, boolean var5, @Nonnull ComponentAccessor<EntityStore> var6) {
         class="kw">return this.paste(var1, var2, var3, var4, var5, false, var6);
      }

      class="kw">public int paste(@Nonnull Ref<EntityStore> var1, int var2, int var3, int var4, boolean var5, boolean var6, @Nonnull ComponentAccessor<EntityStore> var7) {
         World var8 = var7.getExternalData().getWorld();
         if (this.selection != null) {
            long var9 = System.nanoTime();
            Vector3i var11 = this.selection.getSelectionMin();
            Vector3i var12 = this.selection.getSelectionMax();
            int var13 = (var11.x + var12.x) / 2;
            int var14 = var11.y;
            int var15 = (var11.z + var12.z) / 2;
            int var16 = var2 - var13;
            int var17 = var3 - var14;
            int var18 = var4 - var15;
            Vector3i var19 = new Vector3i(var11.x + var16, var11.y + var17, var11.z + var18);
            Vector3i var20 = new Vector3i(var12.x + var16, var12.y + var17, var12.z + var18);
            BlockSelection var21 = this.selection;
            IntUnaryOperator var22 = null;
            if (var5) {
               var21 = this.convertEmptyBlocksToEditorEmpty(this.selection);
            } else {
               int var23 = BlockType.getAssetMap().getIndex("Editor_Empty");
               if (var23 != Integer.MIN_VALUE) {
                  var22 = var1x -> var1x == var23 ? 0 : var1x;
               }
            }

            int var36 = var21.getX();
            int var24 = var21.getY();
            int var25 = var21.getZ();
            int var26 = var21.getPrefabId();
            int var27 = PrefabUtil.getNextPrefabId();

            int var28;
            try {
               var21.setPosition(var2, var3, var4);
               var21.setPrefabId(var27);
               if (!BuilderToolsPlugin.onPasteStart(var27, var7)) {
                  this.sendErrorFeedback(var1, Message.translation("server.builderTools.pasteCancelledByEvent"), "buildertools.paste", var7);
                  class="kw">return 0;
               }

               int var29 = var21.getEntityCount();
               List var30 = new ObjectArrayList(var29 + 1);
               Consumer var31 = BlockSelection.DEFAULT_ENTITY_CONSUMER;
               if (var29 > 0) {
                  var31 = var1x -> var30.add(new EntityAddSnapshot(var1x));
               }

               BlockSelection var32 = var21.place(this.playerRef, var8, Vector3iUtil.ZERO, this.globalMask, var31, var6, var22, var22 != null);
               var32.setSelectionArea(var19, var20);
               var30.add(new BlockSelectionSnapshot(var32));
               this.pushHistory(BuilderToolsPlugin.Action.PASTE, var30);
               BuilderToolsPlugin.invalidateWorldMapForBounds(var19, var20, var8);
               BuilderToolsPlugin.get().onPasteEnd(var27, var7);
               var28 = var21.getBlockCount();
            } class="kw">finally {
               var21.setPrefabId(var26);
               var21.setPosition(var36, var24, var25);
            }

            long var37 = System.nanoTime();
            long var38 = var37 - var9;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute paste of %d blocks", var38, TimeUnit.NANOSECONDS.toMillis(var38), var28);
            this.sendFeedback(Message.translation("server.builderTools.pastedBlocks").param("count", var28), "buildertools.paste", var7);
            class="kw">return var28;
         } else {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionClipboardEmpty"), var7);
            class="kw">return 0;
         }
      }

      class="kw">private BlockSelection convertEmptyBlocksToEditorEmpty(@Nonnull BlockSelection var1) {
         BlockTypeAssetMap var2 = BlockType.getAssetMap();
         int var3 = var2.getIndex("Editor_Empty");
         if (var3 == Integer.MIN_VALUE) {
            class="kw">return var1;
         }

         BlockSelection var4 = new BlockSelection(var1.getBlockCount(), var1.getEntityCount());
         var4.setPosition(var1.getX(), var1.getY(), var1.getZ());
         var4.setAnchor(var1.getAnchorX(), var1.getAnchorY(), var1.getAnchorZ());
         var4.setSelectionArea(var1.getSelectionMin(), var1.getSelectionMax());
         LongOpenHashSet var5 = new LongOpenHashSet();
         var1.forEachFluid((var1x, var2x, var3x, var4x, var5x) -> {
            if (var4x != 0) {
               var5.add(BlockUtil.packUnchecked(var1x, var2x, var3x));
            }
         });
         var1.forEachBlock((var3x, var4x, var5x, var6) -> {
            int var7 = var6.blockId();
            if (var7 == 0 && !var5.contains(BlockUtil.packUnchecked(var3x, var4x, var5x))) {
               var7 = var3;
            }

            var4.addBlockAtLocalPos(var3x, var4x, var5x, var7, var6.rotation(), var6.filler(), var6.supportValue(), var6.holder());
         });
         var1.forEachFluid((var1x, var2x, var3x, var4x, var5x) -> var4.addFluidAtLocalPos(var1x, var2x, var3x, var4x, var5x));
         var1.forEachEntity(var1x -> var4.addEntityHolderRaw(var1x.clone()));
         class="kw">return var4;
      }

      class="kw">public void rotate(@Nonnull Ref<EntityStore> var1, @Nonnull Axis var2, int var3, @Nonnull ComponentAccessor<EntityStore> var4) {
         this.rotate(var1, var2, var3, RotateBlockMode.ALL, var4);
      }

      class="kw">public void rotate(
         @Nonnull Ref<EntityStore> var1, @Nonnull Axis var2, int var3, @Nonnull RotateBlockMode var4, @Nonnull ComponentAccessor<EntityStore> var5
      ) {
         if (this.selection != null) {
            long var6 = System.nanoTime();
            if (this.preRotationSnapshot == null) {
               this.preRotationSnapshot = this.selection.cloneSelection();
            }

            this.selection = this.selection.rotate(var2, var3, var4);
            class="kw">switch (var2) {
               case X:
                  this.cumulativeRotX = ((this.cumulativeRotX + var3) % 360 + 360) % 360;
                  break;
               case Y:
                  this.cumulativeRotY = ((this.cumulativeRotY + var3) % 360 + 360) % 360;
                  break;
               case Z:
                  this.cumulativeRotZ = ((this.cumulativeRotZ + var3) % 360 + 360) % 360;
            }

            long var8 = System.nanoTime();
            long var10 = var8 - var6;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute rotate of %d blocks", var10, TimeUnit.NANOSECONDS.toMillis(var10), this.selection.getBlockCount());
            this.sendUpdate();
            this.sendFeedback(Message.translation("server.builderTools.clipboardRotatedBy").param("angle", var3).param("axis", var2.toString()), var5);
         } else {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionClipboardEmpty"), var5);
         }
      }

      class="kw">public void resetClipboardRotation(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         if (this.preRotationSnapshot == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noRotationToReset"), var2);
         } else {
            this.selection = this.preRotationSnapshot;
            this.preRotationSnapshot = null;
            this.cumulativeRotX = this.cumulativeRotY = this.cumulativeRotZ = 0;
            this.sendUpdate();
            this.sendFeedback(Message.translation("server.builderTools.clipboardRotationReset"), var2);
         }
      }

      class="kw">public void rotateArbitrary(@Nonnull Ref<EntityStore> var1, float var2, float var3, float var4, @Nonnull ComponentAccessor<EntityStore> var5) {
         if (this.selection != null) {
            long var6 = System.nanoTime();
            if (this.preRotationSnapshot == null) {
               this.preRotationSnapshot = this.selection.cloneSelection();
            }

            int var8 = this.selection.getEntityCount();
            this.selection = this.selection.rotateArbitrary(var2, var3, var4);
            long var9 = System.nanoTime();
            long var11 = var9 - var6;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log(
                  "Took: %dns (%dms) to execute arbitrary rotate of %d blocks, %d -> %d entities",
                  var11,
                  TimeUnit.NANOSECONDS.toMillis(var11),
                  this.selection.getBlockCount(),
                  var8,
                  this.selection.getEntityCount()
               );
            this.sendUpdate();
            Message var13 = Message.translation("server.builderTools.clipboardRotatedArbitrary").param("yaw", var2).param("pitch", var3).param("roll", var4);
            this.sendFeedback(var13, var5);
         } else {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionClipboardEmpty"), var5);
         }
      }

      class="kw">public void flip(@Nonnull Ref<EntityStore> var1, @Nonnull Axis var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (this.selection != null) {
            long var4 = System.nanoTime();
            if (this.preRotationSnapshot == null) {
               this.preRotationSnapshot = this.selection.cloneSelection();
            }

            this.selection = this.selection.flip(var2);
            long var6 = System.nanoTime();
            long var8 = var6 - var4;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute flip of %d blocks", var8, TimeUnit.NANOSECONDS.toMillis(var8), this.selection.getBlockCount());
            this.sendUpdate();
            this.sendFeedback(Message.translation("server.builderTools.clipboardFlipped").param("axis", var2.toString()), var3);
         } else {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionClipboardEmpty"), var3);
         }
      }

      class="kw">public void applyRandomizeTransforms(
         @Nonnull Ref<EntityStore> var1,
         int var2,
         int var3,
         int var4,
         boolean var5,
         boolean var6,
         boolean var7,
         @Nonnull RotateBlockMode var8,
         @Nonnull ComponentAccessor<EntityStore> var9
      ) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionClipboardEmpty"), var9);
         } else {
            if (this.preRotationSnapshot == null) {
               this.preRotationSnapshot = this.selection.cloneSelection();
            }

            if (var2 != 0) {
               this.selection = this.selection.rotate(Axis.X, var2, var8);
            }

            if (var3 != 0) {
               this.selection = this.selection.rotate(Axis.Y, var3, var8);
            }

            if (var4 != 0) {
               this.selection = this.selection.rotate(Axis.Z, var4, var8);
            }

            if (var5) {
               this.selection = this.selection.flip(Axis.X);
            }

            if (var6) {
               this.selection = this.selection.flip(Axis.Y);
            }

            if (var7) {
               this.selection = this.selection.flip(Axis.Z);
            }

            if (var2 != 0) {
               this.cumulativeRotX = ((this.cumulativeRotX + var2) % 360 + 360) % 360;
            }

            if (var3 != 0) {
               this.cumulativeRotY = ((this.cumulativeRotY + var3) % 360 + 360) % 360;
            }

            if (var4 != 0) {
               this.cumulativeRotZ = ((this.cumulativeRotZ + var4) % 360 + 360) % 360;
            }

            this.sendUpdate();
            this.sendFeedback(Message.translation("server.builderTools.clipboardRandomized"), var9);
         }
      }

      class="kw">public void hollow(@Nonnull Ref<EntityStore> var1, class="kw">final int var2, int var3, boolean var4, boolean var5, @Nonnull ComponentAccessor<EntityStore> var6) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var6);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var6);
         } else if (!this.selectionExceedsEditLimit(var6)) {
            long var7 = System.nanoTime();
            class="kw">final Vector3i var9 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            class="kw">final Vector3i var10 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            class="kw">final BlockSelection var11 = new BlockSelection();
            var11.setPosition(var9.x, var9.y, var9.z);
            var11.setSelectionArea(var9, var10);
            class="kw">final BlockSelection var12 = new BlockSelection(var11);
            World var13 = var6.getExternalData().getWorld();
            class="kw">final LocalCachedChunkAccessor var14 = LocalCachedChunkAccessor.atWorldCoords(
               var13, var10.x + 1 - var9.x, var10.z + 1 - var9.z, Math.max(var10.x + 1 - var9.x, Math.max(var10.y + 1 - var9.y, var10.z + 1 - var9.z))
            );
            BlockCubeUtil.forEachBlock(var9, var10, var3, !var4, !var5, true, null, new TriIntObjPredicate<Void>() {
               class="kw">private int previousX = Integer.MIN_VALUE;
               class="kw">private int previousZ = Integer.MIN_VALUE;
               @Nullable
               class="kw">private WorldChunk currentChunk;

               class="kw">public boolean test(int var1, int var2x, int var3x, Void var4x) {
                  if (this.previousX != var1 || this.previousZ != var3x) {
                     this.previousX = var1;
                     this.previousZ = var3x;
                     this.currentChunk = var14.getChunk(ChunkUtil.indexChunkFromBlock(var1, var3x));
                  }

                  int var5 = this.currentChunk.getBlock(var1, var2x, var3x);
                  int var6 = this.currentChunk.getFluidId(var1, var2x, var3x);
                  if (BuilderState.this.globalMask != null && BuilderState.this.globalMask.isExcluded(var14, var1, var2x, var3x, var9, var10, var5, var6)) {
                     class="kw">return true;
                  }

                  Holder var7 = this.currentChunk.getBlockComponentHolder(var1, var2x, var3x);
                  Holder var8 = BuilderToolsPlugin.createBlockComponent(this.currentChunk, var1, var2x, var3x, var2, var5, var7, false);
                  int var9x = this.currentChunk.getSupportValue(var1, var2x, var3x);
                  int var10x = this.currentChunk.getFiller(var1, var2x, var3x);
                  int var11x = this.currentChunk.getRotationIndex(var1, var2x, var3x);
                  var11.addBlockAtWorldPos(var1, var2x, var3x, var5, var10x, var11x, var9x, var7);
                  var12.addBlockAtWorldPos(var1, var2x, var3x, var2, 0, 0, 0, var8);
                  class="kw">return true;
               }
            });
            this.pushHistory(BuilderToolsPlugin.Action.HOLLOW, new BlockSelectionSnapshot(var11));
            var12.placeNoReturn("Hollow 1/1", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var13, var6);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var12, var13);
            long var15 = System.nanoTime();
            long var17 = var15 - var7;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute set of %d blocks", var17, TimeUnit.NANOSECONDS.toMillis(var17), var12.getBlockCount());
            this.sendUpdate();
            this.sendArea();
         }
      }

      class="kw">public void walls(
         @Nonnull Ref<EntityStore> var1, @Nonnull class="kw">final BlockPattern var2, int var3, boolean var4, boolean var5, @Nonnull ComponentAccessor<EntityStore> var6
      ) {
         if (!var2.isEmpty()) {
            if (this.selection == null) {
               this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var6);
            } else if (!this.selection.hasSelectionBounds()) {
               this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var6);
            } else if (!this.selectionExceedsEditLimit(var6)) {
               World var7 = var6.getExternalData().getWorld();
               long var8 = System.nanoTime();
               class="kw">final Vector3i var10 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               class="kw">final Vector3i var11 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               class="kw">final BlockSelection var12 = new BlockSelection();
               var12.setPosition(var10.x, var10.y, var10.z);
               var12.setSelectionArea(var10, var11);
               class="kw">final BlockSelection var13 = new BlockSelection(var12);
               class="kw">final LocalCachedChunkAccessor var14 = LocalCachedChunkAccessor.atWorldCoords(
                  var7, var11.x + 1 - var10.x, var11.z + 1 - var10.z, Math.max(var11.x + 1 - var10.x, Math.max(var11.y + 1 - var10.y, var11.z + 1 - var10.z))
               );
               BlockCubeUtil.forEachBlock(var10, var11, var3, var4, var5, false, null, new TriIntObjPredicate<Void>() {
                  class="kw">private int previousX = Integer.MIN_VALUE;
                  class="kw">private int previousZ = Integer.MIN_VALUE;
                  @Nullable
                  class="kw">private WorldChunk currentChunk;

                  class="kw">public boolean test(int var1, int var2x, int var3x, Void var4x) {
                     if (this.previousX != var1 || this.previousZ != var3x) {
                        this.previousX = var1;
                        this.previousZ = var3x;
                        this.currentChunk = var14.getChunk(ChunkUtil.indexChunkFromBlock(var1, var3x));
                     }

                     int var5 = this.currentChunk.getBlock(var1, var2x, var3x);
                     int var6 = this.currentChunk.getFluidId(var1, var2x, var3x);
                     if (BuilderState.this.globalMask != null && BuilderState.this.globalMask.isExcluded(var14, var1, var2x, var3x, var10, var11, var5, var6)) {
                        class="kw">return true;
                     }

                     Material var7 = Material.fromPattern(var2, BuilderState.this.random);
                     if (var7.isFluid()) {
                        byte var8 = this.currentChunk.getFluidLevel(var1, var2x, var3x);
                        if (var5 != 0) {
                           Holder var9 = this.currentChunk.getBlockComponentHolder(var1, var2x, var3x);
                           int var10x = this.currentChunk.getRotationIndex(var1, var2x, var3x);
                           int var11x = this.currentChunk.getSupportValue(var1, var2x, var3x);
                           int var12x = this.currentChunk.getFiller(var1, var2x, var3x);
                           var12.addBlockAtWorldPos(var1, var2x, var3x, var5, var10x, var12x, var11x, var9);
                           var13.addBlockAtWorldPos(var1, var2x, var3x, 0, 0, 0, 0);
                           BuilderState.this.clearFillerBlocksIfNeeded(var1, var2x, var3x, var5, var10x, var14, var12, var13);
                        }

                        var12.addFluidAtWorldPos(var1, var2x, var3x, var6, var8);
                        var13.addFluidAtWorldPos(var1, var2x, var3x, var7.getFluidId(), var7.getFluidLevel());
                     } else {
                        int var17 = var7.getBlockId();
                        int var18 = var7.getRotation();
                        Holder var19 = this.currentChunk.getBlockComponentHolder(var1, var2x, var3x);
                        Holder var20 = BuilderToolsPlugin.createBlockComponent(this.currentChunk, var1, var2x, var3x, var17, var5, var19, false);
                        int var21 = this.currentChunk.getSupportValue(var1, var2x, var3x);
                        int var13x = this.currentChunk.getFiller(var1, var2x, var3x);
                        int var14x = this.currentChunk.getRotationIndex(var1, var2x, var3x);
                        var12.addBlockAtWorldPos(var1, var2x, var3x, var5, var14x, var13x, var21, var19);
                        var13.addBlockAtWorldPos(var1, var2x, var3x, var17, var18, 0, 0, var20);
                        if (var17 == 0) {
                           int var15 = this.currentChunk.getFluidId(var1, var2x, var3x);
                           byte var16 = this.currentChunk.getFluidLevel(var1, var2x, var3x);
                           if (var15 != 0) {
                              var12.addFluidAtWorldPos(var1, var2x, var3x, var15, var16);
                              var13.addFluidAtWorldPos(var1, var2x, var3x, 0, (byte)0);
                           }
                        }
                     }

                     class="kw">return true;
                  }
               });
               this.pushHistory(BuilderToolsPlugin.Action.WALLS, new BlockSelectionSnapshot(var12));
               var13.placeNoReturn("Walls 1/1", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var7, var6);
               BuilderToolsPlugin.invalidateWorldMapForSelection(var13, var7);
               long var15 = System.nanoTime();
               long var17 = var15 - var8;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log("Took: %dns (%dms) to execute walls of %d blocks", var17, TimeUnit.NANOSECONDS.toMillis(var17), var13.getBlockCount());
               this.sendUpdate();
               this.sendArea();
            }
         }
      }

      class="kw">private boolean selectionExceedsEditLimit(@Nonnull ComponentAccessor<EntityStore> var1) {
         if (this.selection != null && this.selection.hasSelectionBounds()) {
            Vector3i var2 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var3 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            long var4 = Vector3iUtil.inclusiveBoxVolume(var2.x(), var2.y(), var2.z(), var3.x(), var3.y(), var3.z());
            class="kw">return this.editVolumeExceedsLimit(var4, var1);
         } else {
            class="kw">return false;
         }
      }

      class="kw">private boolean editVolumeExceedsLimit(long var1, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (var1 < 16000000L) {
            class="kw">return false;
         }

         Ref var4 = this.playerRef.getReference();
         if (BuilderToolsPlugin.shouldShowNotification(var4, var3)) {
            NotificationUtil.sendNotification(
               this.playerRef.getPacketHandler(),
               Message.translation("server.builderTools.edit.tooLarge"),
               Message.translation("server.builderTools.edit.tooLarge.detail").param("overCount", var1 - 16000000L),
               NotificationStyle.Warning
            );
         }

         SoundUtil.playSoundEvent2d(var4, TempAssetIdUtil.getSoundEventIndex("CREATE_ERROR"), SoundCategory.UI, var3);
         class="kw">return true;
      }

      class="kw">public void set(@Nonnull BlockPattern var1, ComponentAccessor<EntityStore> var2) {
         if (!var1.isEmpty()) {
            if (this.selection == null) {
               this.sendFeedback(Message.translation("server.builderTools.noSelection"), var2);
            } else if (!this.selection.hasSelectionBounds()) {
               this.sendFeedback(Message.translation("server.builderTools.noSelectionBounds"), var2);
            } else if (!this.selectionExceedsEditLimit(var2)) {
               long var3 = System.nanoTime();
               Vector3i var5 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               Vector3i var6 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               int var7 = var5.x();
               int var8 = var6.x();
               int var9 = var5.y();
               int var10 = var6.y();
               int var11 = var5.z();
               int var12 = var6.z();
               int var13 = (var8 - var7 + 1) * (var12 - var11 + 1) * (var10 - var9 + 1);
               int var14 = var8 - var7;
               int var15 = var12 - var11;
               int var16 = var14 / 2;
               int var17 = var15 / 2;
               BlockSelection var18 = new BlockSelection(var13, 0);
               var18.setPosition(var7 + var16, var9, var11 + var17);
               var18.setSelectionArea(var5, var6);
               this.pushHistory(BuilderToolsPlugin.Action.SET, new BlockSelectionSnapshot(var18));
               BlockSelection var19 = new BlockSelection(var13, 0);
               var19.copyPropertiesFrom(var18);
               World var20 = var2.getExternalData().getWorld();
               LocalCachedChunkAccessor var21 = LocalCachedChunkAccessor.atWorldCoords(var20, var7 + var16, var11 + var17, Math.max(var14, var15));
               LongOpenHashSet var22 = new LongOpenHashSet(var13);
               Material var23 = var1.getResolvedKeys().length == 1 ? Material.fromPattern(var1, this.random) : null;
               int var24 = 0;

               for (int var25 = var7; var25 <= var8; var25++) {
                  for (int var26 = var11; var26 <= var12; var26++) {
                     WorldChunk var27 = var21.getChunk(ChunkUtil.indexChunkFromBlock(var25, var26));

                     for (int var28 = var10; var28 >= var9; var28--) {
                        int var29 = var27.getBlock(var25, var28, var26);
                        int var30 = var27.getFluidId(var25, var28, var26);
                        if (this.globalMask != null && this.globalMask.isExcluded(var21, var25, var28, var26, var5, var6, var29, var30)) {
                           var24++;
                        } else if (var22.contains(BlockUtil.pack(var25, var28, var26))) {
                           this.sendFeedback("Set 1/2", var13, ++var24, var2);
                        } else {
                           Material var31 = var23 != null ? var23 : Material.fromPattern(var1, this.random);
                           if (var31.isFluid()) {
                              byte var32 = var27.getFluidLevel(var25, var28, var26);
                              if (var29 != 0) {
                                 Holder var33 = var27.getBlockComponentHolder(var25, var28, var26);
                                 int var34 = var27.getRotationIndex(var25, var28, var26);
                                 int var35 = var27.getSupportValue(var25, var28, var26);
                                 int var36 = var27.getFiller(var25, var28, var26);
                                 var18.addBlockAtWorldPos(var25, var28, var26, var29, var34, var36, var35, var33);
                                 var19.addBlockAtWorldPos(var25, var28, var26, 0, 0, 0, 0);
                                 this.clearFillerBlocksIfNeeded(var25, var28, var26, var29, var34, var21, var18, var19);
                              }

                              var18.addFluidAtWorldPos(var25, var28, var26, var30, var32);
                              var19.addFluidAtWorldPos(var25, var28, var26, var31.getFluidId(), var31.getFluidLevel());
                           } else {
                              int var39 = var31.getBlockId();
                              int var40 = var31.getRotation();
                              if (var39 == 0) {
                                 FillerPlacementUtil.captureAndClearFootprint(var21, var18, var19, var25, var28, var26);
                                 int var41 = var27.getFluidId(var25, var28, var26);
                                 if (var41 != 0) {
                                    var18.addFluidAtWorldPos(var25, var28, var26, var41, var27.getFluidLevel(var25, var28, var26));
                                    var19.addFluidAtWorldPos(var25, var28, var26, 0, (byte)0);
                                 }
                              } else {
                                 FillerPlacementUtil.stampBlockWithFiller(var21, var18, var19, var22, var25, var28, var26, var39, var40, false);
                              }
                           }

                           this.sendFeedback("Set 1/2", var13, ++var24, var2);
                        }
                     }
                  }
               }

               var19.placeNoReturn("Set 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var20, var2);
               BuilderToolsPlugin.invalidateWorldMapForSelection(var19, var20);
               long var37 = System.nanoTime();
               long var38 = var37 - var3;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log("Took: %dns (%dms) to execute set of %d blocks", var38, TimeUnit.NANOSECONDS.toMillis(var38), var24);
               this.sendUpdate();
               this.sendArea();
            }
         }
      }

      class="kw">public void submerge(@Nonnull BlockPattern var1, ComponentAccessor<EntityStore> var2) {
         if (!var1.isEmpty()) {
            if (this.selection == null) {
               this.sendFeedback(Message.translation("server.builderTools.noSelection"), var2);
            } else if (!this.selection.hasSelectionBounds()) {
               this.sendFeedback(Message.translation("server.builderTools.noSelectionBounds"), var2);
            } else if (!this.selectionExceedsEditLimit(var2)) {
               long var3 = System.nanoTime();
               Vector3i var5 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               Vector3i var6 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               int var7 = var5.x();
               int var8 = var6.x();
               int var9 = var5.y();
               int var10 = var6.y();
               int var11 = var5.z();
               int var12 = var6.z();
               int var13 = (var8 - var7 + 1) * (var12 - var11 + 1) * (var10 - var9 + 1);
               int var14 = var8 - var7;
               int var15 = var12 - var11;
               int var16 = var14 / 2;
               int var17 = var15 / 2;
               BlockSelection var18 = new BlockSelection(var13, 0);
               var18.setPosition(var7 + var16, var9, var11 + var17);
               var18.setSelectionArea(var5, var6);
               this.pushHistory(BuilderToolsPlugin.Action.SET, new BlockSelectionSnapshot(var18));
               BlockSelection var19 = new BlockSelection(var13, 0);
               var19.copyPropertiesFrom(var18);
               World var20 = var2.getExternalData().getWorld();
               LocalCachedChunkAccessor var21 = LocalCachedChunkAccessor.atWorldCoords(var20, var7 + var16, var11 + var17, Math.max(var14, var15));
               int var22 = 0;

               for (int var23 = var7; var23 <= var8; var23++) {
                  for (int var24 = var11; var24 <= var12; var24++) {
                     WorldChunk var25 = var21.getChunk(ChunkUtil.indexChunkFromBlock(var23, var24));

                     for (int var26 = var10; var26 >= var9; var26--) {
                        int var27 = var25.getBlock(var23, var26, var24);
                        int var28 = var25.getFluidId(var23, var26, var24);
                        if (this.globalMask != null && this.globalMask.isExcluded(var21, var23, var26, var24, var5, var6, var27, var28)) {
                           var22++;
                        } else {
                           Material var29 = Material.fromPattern(var1, this.random);
                           if (var29.isFluid()) {
                              byte var30 = var25.getFluidLevel(var23, var26, var24);
                              var18.addFluidAtWorldPos(var23, var26, var24, var28, var30);
                              var19.addFluidAtWorldPos(var23, var26, var24, var29.getFluidId(), var29.getFluidLevel());
                           }

                           this.sendFeedback("Submerge 1/2", var13, ++var22, var2);
                        }
                     }
                  }
               }

               var19.placeNoReturn("Submerge 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var20, var2);
               BuilderToolsPlugin.invalidateWorldMapForSelection(var19, var20);
               long var31 = System.nanoTime();
               long var32 = var31 - var3;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log("Took: %dns (%dms) to execute submerge of %d blocks", var32, TimeUnit.NANOSECONDS.toMillis(var32), var22);
               this.sendUpdate();
               this.sendArea();
            }
         }
      }

      class="kw">public void unsubmerge(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         if (this.selection == null) {
            this.sendFeedback(Message.translation("server.builderTools.noSelection"), var2);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendFeedback(Message.translation("server.builderTools.noSelectionBounds"), var2);
         } else if (!this.selectionExceedsEditLimit(var2)) {
            long var3 = System.nanoTime();
            Vector3i var5 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var6 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            int var7 = var5.x();
            int var8 = var6.x();
            int var9 = var5.y();
            int var10 = var6.y();
            int var11 = var5.z();
            int var12 = var6.z();
            int var13 = (var8 - var7 + 1) * (var12 - var11 + 1) * (var10 - var9 + 1);
            int var14 = var8 - var7;
            int var15 = var12 - var11;
            int var16 = var14 / 2;
            int var17 = var15 / 2;
            BlockSelection var18 = new BlockSelection(var13, 0);
            var18.setPosition(var7 + var16, var9, var11 + var17);
            var18.setSelectionArea(var5, var6);
            this.pushHistory(BuilderToolsPlugin.Action.SET, new BlockSelectionSnapshot(var18));
            BlockSelection var19 = new BlockSelection(var13, 0);
            var19.copyPropertiesFrom(var18);
            World var20 = var2.getExternalData().getWorld();
            LocalCachedChunkAccessor var21 = LocalCachedChunkAccessor.atWorldCoords(var20, var7 + var16, var11 + var17, Math.max(var14, var15));
            int var22 = 0;

            for (int var23 = var7; var23 <= var8; var23++) {
               for (int var24 = var11; var24 <= var12; var24++) {
                  WorldChunk var25 = var21.getChunk(ChunkUtil.indexChunkFromBlock(var23, var24));

                  for (int var26 = var10; var26 >= var9; var26--) {
                     int var27 = var25.getBlock(var23, var26, var24);
                     int var28 = var25.getFluidId(var23, var26, var24);
                     if (this.globalMask != null && this.globalMask.isExcluded(var21, var23, var26, var24, var5, var6, var27, var28)) {
                        var22++;
                     } else {
                        if (var28 != 0) {
                           byte var29 = var25.getFluidLevel(var23, var26, var24);
                           var18.addFluidAtWorldPos(var23, var26, var24, var28, var29);
                           var19.addFluidAtWorldPos(var23, var26, var24, 0, (byte)0);
                        }

                        this.sendFeedback("Unsubmerge 1/2", var13, ++var22, var2);
                     }
                  }
               }
            }

            var19.placeNoReturn("Unsubmerge 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var20, var2);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var19, var20);
            long var30 = System.nanoTime();
            long var31 = var30 - var3;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute unsubmerge of %d blocks", var31, TimeUnit.NANOSECONDS.toMillis(var31), var22);
            this.sendUpdate();
            this.sendArea();
            SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex("CREATE_SELECTION_FILL"), SoundCategory.SFX, var2);
         }
      }

      class="kw">public void fill(@Nonnull BlockPattern var1, ComponentAccessor<EntityStore> var2) {
         if (!var1.isEmpty()) {
            if (this.selection == null) {
               this.sendFeedback(Message.translation("server.builderTools.noSelection"), var2);
            } else if (!this.selection.hasSelectionBounds()) {
               this.sendFeedback(Message.translation("server.builderTools.noSelectionBounds"), var2);
            } else if (!this.selectionExceedsEditLimit(var2)) {
               long var3 = System.nanoTime();
               Vector3i var5 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               Vector3i var6 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               int var7 = var5.x();
               int var8 = var6.x();
               int var9 = var5.y();
               int var10 = var6.y();
               int var11 = var5.z();
               int var12 = var6.z();
               int var13 = (var8 - var7 + 1) * (var12 - var11 + 1) * (var10 - var9 + 1);
               int var14 = var8 - var7;
               int var15 = var12 - var11;
               int var16 = var14 / 2;
               int var17 = var15 / 2;
               BlockSelection var18 = new BlockSelection(var13, 0);
               var18.setPosition(var7 + var16, var9, var11 + var17);
               var18.setSelectionArea(var5, var6);
               this.pushHistory(BuilderToolsPlugin.Action.EDIT, new BlockSelectionSnapshot(var18));
               BlockSelection var19 = new BlockSelection(var13, 0);
               var19.copyPropertiesFrom(var18);
               World var20 = var2.getExternalData().getWorld();
               LocalCachedChunkAccessor var21 = LocalCachedChunkAccessor.atWorldCoords(var20, var7 + var16, var11 + var17, Math.max(var14, var15));
               LongOpenHashSet var22 = new LongOpenHashSet(var13);
               int var23 = 0;

               for (int var24 = var7; var24 <= var8; var24++) {
                  for (int var25 = var11; var25 <= var12; var25++) {
                     WorldChunk var26 = var21.getChunk(ChunkUtil.indexChunkFromBlock(var24, var25));

                     for (int var27 = var10; var27 >= var9; var27--) {
                        Material var28 = Material.fromPattern(var1, this.random);
                        if (var28.isFluid()) {
                           int var29 = var26.getFluidId(var24, var27, var25);
                           if (var29 == 0) {
                              byte var30 = var26.getFluidLevel(var24, var27, var25);
                              var18.addFluidAtWorldPos(var24, var27, var25, var29, var30);
                              var19.addFluidAtWorldPos(var24, var27, var25, var28.getFluidId(), var28.getFluidLevel());
                           }
                        } else {
                           int var33 = var26.getBlock(var24, var27, var25);
                           int var34 = var28.getBlockId();
                           if (var33 == 0 && var34 != 0) {
                              FillerPlacementUtil.stampBlockWithFiller(var21, var18, var19, var22, var24, var27, var25, var34, var28.getRotation(), true);
                           }
                        }

                        this.sendFeedback("Fill 1/2", var13, ++var23, var2);
                     }
                  }
               }

               var19.placeNoReturn("Fill 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var20, var2);
               BuilderToolsPlugin.invalidateWorldMapForSelection(var19, var20);
               long var31 = System.nanoTime();
               long var32 = var31 - var3;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log("Took: %dns (%dms) to execute fill of %d blocks", var32, TimeUnit.NANOSECONDS.toMillis(var32), var23);
               this.sendUpdate();
               this.sendArea();
            }
         }
      }

      class="kw">public void floodFill(@Nonnull BlockPattern var1, int var2, int var3, int var4, int var5, ComponentAccessor<EntityStore> var6) {
         if (!var1.isEmpty()) {
            World var7 = var6.getExternalData().getWorld();
            LocalCachedChunkAccessor var8 = LocalCachedChunkAccessor.atWorldCoords(var7, var3, var5, var2);
            WorldChunk var9 = var8.getChunk(ChunkUtil.indexChunkFromBlock(var3, var5));
            if (var9 != null && var9.getBlock(var3, var4, var5) == 0) {
               long var10 = System.nanoTime();
               int var12 = var2 * var2;
               int var13 = (int)Math.min(200000.0, Math.ceil((Math.PI * 4.0 / 3.0) * var2 * var2 * var2));
               Vector3i var14 = new Vector3i(var3 - var2, Math.max(0, var4 - var2), var5 - var2);
               Vector3i var15 = new Vector3i(var3 + var2, Math.min(319, var4 + var2), var5 + var2);
               BlockSelection var16 = new BlockSelection(var13, 0);
               var16.setPosition(var3, var14.y(), var5);
               var16.setSelectionArea(var14, var15);
               BlockSelection var17 = new BlockSelection(var13, 0);
               var17.copyPropertiesFrom(var16);
               LongOpenHashSet var18 = new LongOpenHashSet(var13);
               LongOpenHashSet var19 = new LongOpenHashSet(var13);
               LongArrayList var20 = new LongArrayList(var13);
               long var21 = BlockUtil.pack(var3, var4, var5);
               var19.add(var21);
               var20.add(var21);
               int var23 = 0;

               while (!var20.isEmpty()) {
                  long var24 = var20.removeLong(var20.size() - 1);
                  int var26 = BlockUtil.unpackX(var24);
                  int var27 = BlockUtil.unpackY(var24);
                  int var28 = BlockUtil.unpackZ(var24);
                  WorldChunk var29 = var8.getChunk(ChunkUtil.indexChunkFromBlock(var26, var28));
                  if (var29 != null) {
                     Material var30 = Material.fromPattern(var1, this.random);
                     if (var30.isFluid()) {
                        int var31 = var29.getFluidId(var26, var27, var28);
                        if (var31 == 0) {
                           byte var32 = var29.getFluidLevel(var26, var27, var28);
                           var16.addFluidAtWorldPos(var26, var27, var28, var31, var32);
                           var17.addFluidAtWorldPos(var26, var27, var28, var30.getFluidId(), var30.getFluidLevel());
                        }
                     } else {
                        int var46 = var30.getBlockId();
                        if (var46 != 0) {
                           FillerPlacementUtil.stampBlockWithFiller(var8, var16, var17, var18, var26, var27, var28, var46, var30.getRotation(), true);
                        }
                     }

                     this.sendFeedback("Flood 1/2", var13, ++var23, var6);

                     for (int[] var34 : FLOOD_NEIGHBORS) {
                        int var35 = var26 + var34[0];
                        int var36 = var27 + var34[1];
                        int var37 = var28 + var34[2];
                        if (var36 >= 0 && var36 < 320) {
                           int var38 = var35 - var3;
                           int var39 = var36 - var4;
                           int var40 = var37 - var5;
                           if (var38 * var38 + var39 * var39 + var40 * var40 <= var12) {
                              long var41 = BlockUtil.pack(var35, var36, var37);
                              if (var19.add(var41)) {
                                 WorldChunk var43 = var8.getChunk(ChunkUtil.indexChunkFromBlock(var35, var37));
                                 if (var43 != null && var43.getBlock(var35, var36, var37) == 0) {
                                    if (var23 + var20.size() >= 200000) {
                                       this.sendFeedback(Message.translation("server.commands.floodfill.tooLarge").param("radius", var2), var6);
                                       class="kw">return;
                                    }

                                    var20.add(var41);
                                 }
                              }
                           }
                        }
                     }
                  }
               }

               this.pushHistory(BuilderToolsPlugin.Action.EDIT, new BlockSelectionSnapshot(var16));
               var17.placeNoReturn("Flood 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var7, var6);
               BuilderToolsPlugin.invalidateWorldMapForSelection(var17, var7);
               long var44 = System.nanoTime();
               long var45 = var44 - var10;
               BuilderToolsPlugin.get()
                  .getLogger()
                  .at(Level.FINE)
                  .log("Took: %dns (%dms) to execute flood fill of %d blocks", var45, TimeUnit.NANOSECONDS.toMillis(var45), var23);
               this.sendUpdate();
               this.sendArea();
            } else {
               this.sendFeedback(Message.translation("server.commands.floodfill.notOpen"), var6);
            }
         }
      }

      class="kw">public void replace(@Nonnull Ref<EntityStore> var1, @Nonnull Material var2, @Nonnull Material var3, @Nonnull ComponentAccessor<EntityStore> var4) {
         if (this.selection == null) {
            this.sendFeedback(Message.translation("server.builderTools.noSelection"), var4);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendFeedback(Message.translation("server.builderTools.noSelectionBounds"), var4);
         } else if (!this.selectionExceedsEditLimit(var4)) {
            long var5 = System.nanoTime();
            Vector3i var7 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var8 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            int var9 = var7.x();
            int var10 = var8.x();
            int var11 = var7.y();
            int var12 = var8.y();
            int var13 = var7.z();
            int var14 = var8.z();
            BlockSelection var15 = new BlockSelection();
            int var16 = var10 - var9;
            int var17 = var14 - var13;
            int var18 = var16 / 2;
            int var19 = var17 / 2;
            var15.setPosition(var9 + var18, var11, var13 + var19);
            var15.setSelectionArea(var7, var8);
            this.pushHistory(BuilderToolsPlugin.Action.REPLACE, new BlockSelectionSnapshot(var15));
            BlockSelection var20 = new BlockSelection(var15);
            World var21 = var4.getExternalData().getWorld();
            LocalCachedChunkAccessor var22 = LocalCachedChunkAccessor.atWorldCoords(var21, var9 + var18, var13 + var19, Math.max(var16, var17));
            int var23 = (var16 + 1) * (var17 + 1) * (var12 - var11 + 1);
            LongOpenHashSet var24 = new LongOpenHashSet(var23);
            int var25 = 0;

            for (int var26 = var9; var26 <= var10; var26++) {
               for (int var27 = var13; var27 <= var14; var27++) {
                  WorldChunk var28 = var22.getChunk(ChunkUtil.indexChunkFromBlock(var26, var27));

                  for (int var29 = var12; var29 >= var11; var29--) {
                     int var30 = var28.getFiller(var26, var29, var27);
                     if (var30 != 0) {
                        this.sendFeedback("Replace 1/2", var23, ++var25, var4);
                     } else {
                        boolean var31 = false;
                        if (var2.isFluid()) {
                           int var32 = var28.getFluidId(var26, var29, var27);
                           var31 = var32 == var2.getFluidId();
                        } else {
                           int var41 = var28.getBlock(var26, var29, var27);
                           var31 = var41 == var2.getBlockId();
                        }

                        if (var31) {
                           int var42 = var28.getBlock(var26, var29, var27);
                           int var33 = var28.getFluidId(var26, var29, var27);
                           byte var34 = var28.getFluidLevel(var26, var29, var27);
                           if (var3.isFluid()) {
                              if (var42 != 0) {
                                 Holder var35 = var28.getBlockComponentHolder(var26, var29, var27);
                                 int var36 = var28.getRotationIndex(var26, var29, var27);
                                 int var37 = var28.getSupportValue(var26, var29, var27);
                                 var15.addBlockAtWorldPos(var26, var29, var27, var42, var36, var30, var37, var35);
                                 var20.addBlockAtWorldPos(var26, var29, var27, 0, 0, 0, 0);
                                 this.clearFillerBlocksIfNeeded(var26, var29, var27, var42, var36, var22, var15, var20);
                              }

                              var15.addFluidAtWorldPos(var26, var29, var27, var33, var34);
                              var20.addFluidAtWorldPos(var26, var29, var27, var3.getFluidId(), var3.getFluidLevel());
                           } else if (var3.isEmpty()) {
                              Holder var43 = var28.getBlockComponentHolder(var26, var29, var27);
                              int var45 = var28.getRotationIndex(var26, var29, var27);
                              int var46 = var28.getSupportValue(var26, var29, var27);
                              var15.addBlockAtWorldPos(var26, var29, var27, var42, var45, var30, var46, var43);
                              var20.addBlockAtWorldPos(var26, var29, var27, 0, 0, 0, 0);
                              this.clearFillerBlocksIfNeeded(var26, var29, var27, var42, var45, var22, var15, var20);
                              if (var33 != 0) {
                                 var15.addFluidAtWorldPos(var26, var29, var27, var33, var34);
                                 var20.addFluidAtWorldPos(var26, var29, var27, 0, (byte)0);
                              }
                           } else {
                              if (var33 != 0) {
                                 var15.addFluidAtWorldPos(var26, var29, var27, var33, var34);
                                 var20.addFluidAtWorldPos(var26, var29, var27, 0, (byte)0);
                              }

                              int var44 = var28.getRotationIndex(var26, var29, var27);
                              FillerPlacementUtil.stampBlockWithFiller(var22, var15, var20, var24, var26, var29, var27, var3.getBlockId(), var44, false);
                           }
                        }

                        this.sendFeedback("Replace 1/2", var23, ++var25, var4);
                     }
                  }
               }
            }

            var20.placeNoReturn("Replace 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var21, var4);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var20, var21);
            long var38 = System.nanoTime();
            long var39 = var38 - var5;
            BuilderToolsPlugin.get().getLogger().at(Level.FINE).log("Took: %dns (%dms) to execute replace", var39, TimeUnit.NANOSECONDS.toMillis(var39));
            this.sendUpdate();
            this.sendArea();
            SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex("CREATE_SELECTION_FILL"), SoundCategory.SFX, var4);
         }
      }

      class="kw">private void clearFillerBlocksIfNeeded(
         int var1, int var2, int var3, int var4, int var5, LocalCachedChunkAccessor var6, BlockSelection var7, BlockSelection var8
      ) {
         this.replaceMultiBlockStructure(var1, var2, var3, var4, 0, var5, var6, var7, var8);
      }

      class="kw">private void replaceMultiBlockStructure(
         int var1, int var2, int var3, int var4, int var5, int var6, LocalCachedChunkAccessor var7, BlockSelection var8, BlockSelection var9
      ) {
         BlockTypeAssetMap var10 = BlockType.getAssetMap();
         IndexedLookupTableAssetMap var11 = BlockBoundingBoxes.getAssetMap();
         BlockType var12 = var10.getAsset(var4);
         BlockBoundingBoxes var13 = null;
         if (var12 != null) {
            var13 = var11.getAsset(var12.getHitboxTypeIndex());
         }

         BlockType var14 = var10.getAsset(var5);
         BlockBoundingBoxes var15 = null;
         if (var14 != null) {
            var15 = var11.getAsset(var14.getHitboxTypeIndex());
         }

         if (var13 != null && var13.protrudesUnitBox()) {
            BlockBoundingBoxes var16 = var15;
            FillerBlockUtil.forEachFillerBlock(var13.get(var6), (var8x, var9x, var10x) -> {
               if (var8x != 0 || var9x != 0 || var10x != 0) {
                  int var11 = var1 + var8x;
                  int var12 = var2 + var9x;
                  int var13 = var3 + var10x;
                  WorldChunk var14 = var7.getChunk(ChunkUtil.indexChunkFromBlock(var11, var13));
                  int var15 = var14.getBlock(var11, var12, var13);
                  int var16 = var14.getFiller(var11, var12, var13);
                  if (var16 != 0) {
                     Holder var17 = var14.getBlockComponentHolder(var11, var12, var13);
                     var8.addBlockAtWorldPos(var11, var12, var13, var15, var6, var16, var14.getSupportValue(var11, var12, var13), var17);
                     boolean var18 = var16 != null && var16.protrudesUnitBox() && var16.get(var6).getBoundingBox().containsBlock(var8x, var9x, var10x);
                     if (!var18) {
                        var9.addBlockAtWorldPos(var11, var12, var13, 0, 0, 0, 0);
                     }
                  }
               }
            });
         }

         if (var15 != null && var15.protrudesUnitBox()) {
            FillerBlockUtil.forEachFillerBlock(var15.get(var6), (var8x, var9x, var10x) -> {
               if (var8x != 0 || var9x != 0 || var10x != 0) {
                  int var11 = var1 + var8x;
                  int var12 = var2 + var9x;
                  int var13 = var3 + var10x;
                  WorldChunk var14 = var7.getChunk(ChunkUtil.indexChunkFromBlock(var11, var13));
                  int var15 = var14.getBlock(var11, var12, var13);
                  int var16 = var14.getFiller(var11, var12, var13);
                  if (var16 == 0 && !var8.hasBlockAtWorldPos(var11, var12, var13)) {
                     Holder var17 = var14.getBlockComponentHolder(var11, var12, var13);
                     var8.addBlockAtWorldPos(var11, var12, var13, var15, var6, var16, var14.getSupportValue(var11, var12, var13), var17);
                  }

                  int var18 = FillerBlockUtil.pack(var8x, var9x, var10x);
                  var9.addBlockAtWorldPos(var11, var12, var13, var5, var6, var18, 0);
               }
            });
         }
      }

      class="kw">public void replace(@Nonnull Ref<EntityStore> var1, @Nullable BlockMask var2, @Nonnull BlockPattern var3, @Nonnull ComponentAccessor<EntityStore> var4) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var4);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var4);
         } else if (!this.selectionExceedsEditLimit(var4)) {
            long var5 = System.nanoTime();
            Vector3i var7 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var8 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            int var9 = var7.x();
            int var10 = var8.x();
            int var11 = var7.y();
            int var12 = var8.y();
            int var13 = var7.z();
            int var14 = var8.z();
            BlockSelection var15 = new BlockSelection();
            int var16 = var10 - var9;
            int var17 = var14 - var13;
            int var18 = var16 / 2;
            int var19 = var17 / 2;
            var15.setPosition(var9 + var18, var11, var13 + var19);
            var15.setSelectionArea(var7, var8);
            this.pushHistory(BuilderToolsPlugin.Action.REPLACE, new BlockSelectionSnapshot(var15));
            BlockSelection var20 = new BlockSelection(var15);
            World var21 = var4.getExternalData().getWorld();
            LocalCachedChunkAccessor var22 = LocalCachedChunkAccessor.atWorldCoords(var21, var9 + var18, var13 + var19, Math.max(var16, var17));
            int var23 = (var16 + 1) * (var17 + 1) * (var12 - var11 + 1);
            LongOpenHashSet var24 = new LongOpenHashSet(var23);
            int var25 = 0;

            for (int var26 = var9; var26 <= var10; var26++) {
               for (int var27 = var13; var27 <= var14; var27++) {
                  WorldChunk var28 = var22.getChunk(ChunkUtil.indexChunkFromBlock(var26, var27));

                  for (int var29 = var12; var29 >= var11; var29--) {
                     int var30 = var28.getFiller(var26, var29, var27);
                     if (var30 != 0) {
                        this.sendFeedback("Replace 1/2", var23, ++var25, var4);
                     } else {
                        int var31 = var28.getBlock(var26, var29, var27);
                        if (var31 >= 0 && var31 != 1) {
                           boolean var32;
                           if (var2 == null) {
                              var32 = true;
                           } else {
                              int var33 = var28.getFluidId(var26, var29, var27);
                              var32 = !var2.isExcluded(var22, var26, var29, var27, var7, var8, var31, var33);
                           }

                           if (var32) {
                              Material var39 = Material.fromPattern(var3, this.random);
                              int var34 = var39.getBlockId();
                              int var35 = var39.hasRotation() ? var39.getRotation() : var28.getRotationIndex(var26, var29, var27);
                              if (var34 == 0) {
                                 FillerPlacementUtil.captureAndClearFootprint(var22, var15, var20, var26, var29, var27);
                                 int var36 = var28.getFluidId(var26, var29, var27);
                                 if (var36 != 0) {
                                    var15.addFluidAtWorldPos(var26, var29, var27, var36, var28.getFluidLevel(var26, var29, var27));
                                    var20.addFluidAtWorldPos(var26, var29, var27, 0, (byte)0);
                                 }
                              } else {
                                 FillerPlacementUtil.stampBlockWithFiller(var22, var15, var20, var24, var26, var29, var27, var34, var35, false);
                              }
                           }

                           this.sendFeedback("Replace 1/2", var23, ++var25, var4);
                        } else {
                           this.sendFeedback("Replace 1/2", var23, ++var25, var4);
                        }
                     }
                  }
               }
            }

            var20.placeNoReturn("Replace 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var21, var4);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var20, var21);
            long var37 = System.nanoTime();
            long var38 = var37 - var5;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute replace of %d blocks", var38, TimeUnit.NANOSECONDS.toMillis(var38), var20.getBlockCount());
            this.sendUpdate();
            this.sendArea();
            SoundUtil.playSoundEvent2d(var1, TempAssetIdUtil.getSoundEventIndex("CREATE_SELECTION_FILL"), SoundCategory.SFX, var4);
         }
      }

      class="kw">public int replace(@Nonnull Ref<EntityStore> var1, @Nonnull Int2IntFunction var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var3);
            class="kw">return 0;
         }

         if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var3);
            class="kw">return 0;
         }

         if (this.selectionExceedsEditLimit(var3)) {
            class="kw">return 0;
         }

         long var4 = System.nanoTime();
         Vector3i var6 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
         Vector3i var7 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
         int var8 = var6.x();
         int var9 = var7.x();
         int var10 = var6.y();
         int var11 = var7.y();
         int var12 = var6.z();
         int var13 = var7.z();
         BlockSelection var14 = new BlockSelection();
         int var15 = var9 - var8;
         int var16 = var13 - var12;
         int var17 = var15 / 2;
         int var18 = var16 / 2;
         var14.setPosition(var8 + var17, var10, var12 + var18);
         var14.setSelectionArea(var6, var7);
         this.pushHistory(BuilderToolsPlugin.Action.REPLACE, new BlockSelectionSnapshot(var14));
         BlockSelection var19 = new BlockSelection(var14);
         World var20 = var3.getExternalData().getWorld();
         LocalCachedChunkAccessor var21 = LocalCachedChunkAccessor.atWorldCoords(var20, var8 + var17, var12 + var18, Math.max(var15, var16));
         int var22 = (var15 + 1) * (var16 + 1) * (var11 - var10 + 1);
         int var23 = 0;

         for (int var26 = var8; var26 <= var9; var26++) {
            for (int var27 = var12; var27 <= var13; var27++) {
               WorldChunk var28 = var21.getChunk(ChunkUtil.indexChunkFromBlock(var26, var27));

               for (int var29 = var11; var29 >= var10; var29--) {
                  int var30 = var28.getFiller(var26, var29, var27);
                  if (var30 != 0) {
                     this.sendFeedback("Replace 1/2", var22, ++var23, var3);
                  } else {
                     int var24 = var28.getBlock(var26, var29, var27);
                     int var25 = var2.applyAsInt(var24);
                     if (var24 != var25) {
                        Holder var31 = var28.getBlockComponentHolder(var26, var29, var27);
                        Holder var32 = BuilderToolsPlugin.createBlockComponent(var28, var26, var29, var27, var25, var24, var31, true);
                        int var33 = var28.getRotationIndex(var26, var29, var27);
                        var14.addBlockAtWorldPos(var26, var29, var27, var24, var33, var30, var28.getSupportValue(var26, var29, var27), var31);
                        var19.addBlockAtWorldPos(var26, var29, var27, var25, var33, 0, 0, var32);
                        this.replaceMultiBlockStructure(var26, var29, var27, var24, var25, var33, var21, var14, var19);
                        if (var25 == 0) {
                           int var34 = var28.getFluidId(var26, var29, var27);
                           byte var35 = var28.getFluidLevel(var26, var29, var27);
                           if (var34 != 0) {
                              var14.addFluidAtWorldPos(var26, var29, var27, var34, var35);
                              var19.addFluidAtWorldPos(var26, var29, var27, 0, (byte)0);
                           }
                        }
                     }

                     this.sendFeedback("Replace 1/2", var22, ++var23, var3);
                  }
               }
            }
         }

         var19.placeNoReturn("Replace 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var20, var3);
         BuilderToolsPlugin.invalidateWorldMapForSelection(var19, var20);
         long var36 = System.nanoTime();
         long var37 = var36 - var4;
         int var38 = var19.getBlockCount();
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute replace of %d blocks", var37, TimeUnit.NANOSECONDS.toMillis(var37), var38);
         this.sendUpdate();
         this.sendArea();
         class="kw">return var38;
      }

      class="kw">public void move(@Nonnull Ref<EntityStore> var1, @Nonnull Vector3i var2, boolean var3, boolean var4, @Nonnull ComponentAccessor<EntityStore> var5) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var5);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var5);
         } else if (!this.selectionExceedsEditLimit(var5)) {
            long var6 = System.nanoTime();
            Vector3i var8 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var9 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            int var10 = var8.x();
            int var11 = var9.x();
            int var12 = var8.y();
            int var13 = var9.y();
            int var14 = var8.z();
            int var15 = var9.z();
            BlockSelection var16 = new BlockSelection();
            int var17 = var11 - var10;
            int var18 = var13 - var12;
            int var19 = var15 - var14;
            int var20 = var17 / 2;
            int var21 = var19 / 2;
            int var22 = var10 + var20;
            int var23 = var12;
            int var24 = var14 + var21;
            var16.setPosition(var22, var23, var24);
            BlockSelection var25 = new BlockSelection(var16);
            World var26 = var5.getExternalData().getWorld();
            LocalCachedChunkAccessor var27 = LocalCachedChunkAccessor.atWorldCoords(var26, var10 + var20, var14 + var21, Math.max(var17, var19) + 16);
            BlockTypeAssetMap var28 = BlockType.getAssetMap();
            IndexedLookupTableAssetMap var29 = BlockBoundingBoxes.getAssetMap();

            for (int var30 = var10; var30 <= var11; var30++) {
               for (int var31 = var14; var31 <= var15; var31++) {
                  WorldChunk var32 = var27.getChunk(ChunkUtil.indexChunkFromBlock(var30, var31));

                  for (int var33 = var13; var33 >= var12; var33--) {
                     int var34 = var32.getBlock(var30, var33, var31);
                     int var35 = var32.getFluidId(var30, var33, var31);
                     byte var36 = var32.getFluidLevel(var30, var33, var31);
                     if ((var34 != 0 || var35 != 0 || var3)
                        && (this.globalMask == null || !this.globalMask.isExcluded(var27, var30, var33, var31, var8, var9, var34, var35))) {
                        int var37 = var32.getFiller(var30, var33, var31);
                        int var38 = var32.getRotationIndex(var30, var33, var31);
                        var16.addBlockAtWorldPos(
                           var30,
                           var33,
                           var31,
                           var34,
                           var38,
                           var37,
                           var32.getSupportValue(var30, var33, var31),
                           var32.getBlockComponentHolder(var30, var33, var31)
                        );
                        var16.addFluidAtWorldPos(var30, var33, var31, var35, var36);
                        var25.addBlockAtWorldPos(var30, var33, var31, 0, 0, 0, 0);
                        var25.addFluidAtWorldPos(var30, var33, var31, 0, (byte)0);
                        if (var37 == 0 && var34 != 0) {
                           BlockType var39 = var28.getAsset(var34);
                           if (var39 != null) {
                              BlockBoundingBoxes var40 = var29.getAsset(var39.getHitboxTypeIndex());
                              if (var40 != null && var40.protrudesUnitBox()) {
                                 int var41 = var30;
                                 int var42 = var33;
                                 int var43 = var31;
                                 FillerBlockUtil.forEachFillerBlock(
                                    var40.get(var38),
                                    (var12x, var13x, var14x) -> {
                                       if (var12x != 0 || var13x != 0 || var14x != 0) {
                                          int var15 = var41 + var12x;
                                          int var16 = var42 + var13x;
                                          int var17 = var43 + var14x;
                                          if (var15 < var10 || var15 > var11 || var16 < var12 || var16 > var13 || var17 < var14 || var17 > var15) {
                                             WorldChunk var18 = var27.getChunk(ChunkUtil.indexChunkFromBlock(var15, var17));
                                             int var19 = var18.getBlock(var15, var16, var17);
                                             int var20 = var18.getFiller(var15, var16, var17);
                                             if (var20 != 0) {
                                                int var21 = var18.getRotationIndex(var15, var16, var17);
                                                var16.addBlockAtWorldPos(
                                                   var15,
                                                   var16,
                                                   var17,
                                                   var19,
                                                   var21,
                                                   var20,
                                                   var18.getSupportValue(var15, var16, var17),
                                                   var18.getBlockComponentHolder(var15, var16, var17)
                                                );
                                                var25.addBlockAtWorldPos(var15, var16, var17, 0, 0, 0, 0);
                                             }
                                          }
                                       }
                                    }
                                 );
                              }
                           }
                        }
                     }
                  }
               }
            }

            BlockSelection var44 = var25.place(this.playerRef, var26);
            var16.setPosition(var22 + var2.x(), var23 + var2.y(), var24 + var2.z());
            BlockSelection var45 = var16.place(this.playerRef, var26);
            List var46 = new ObjectArrayList();
            if (var4) {
               for (Ref var51 : TargetUtil.getAllEntitiesInBox(Vector3iUtil.toVector3d(var8), Vector3iUtil.toVector3d(var9), var5)) {
                  var46.add(new EntityTransformSnapshot(var51, var5));
                  TransformComponent var53 = var5.getComponent(var51, TransformComponent.getComponentType());
                  if (var53 != null) {
                     var53.getPosition().add(var2.x, var2.y, var2.z);
                  }
               }
            }

            var45.add(var44);
            ClipboardBoundsSnapshot var48 = new ClipboardBoundsSnapshot(var8, var9);
            Vector3i var50 = new Vector3i(var8).add(var2);
            Vector3i var52 = new Vector3i(var9).add(var2);
            var45.setSelectionArea(Vector3iUtil.min(var8, var50), Vector3iUtil.max(var9, var52));
            var46.add(new BlockSelectionSnapshot(var45));
            var46.add(var48);
            this.pushHistory(BuilderToolsPlugin.Action.MOVE, var46);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var25, var26);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var16, var26);
            this.selection.setSelectionArea(new Vector3i(var8).add(var2), new Vector3i(var9).add(var2));
            this.syncRawPositions();
            long var54 = System.nanoTime();
            long var55 = var54 - var6;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute move of %d blocks", var55, TimeUnit.NANOSECONDS.toMillis(var55), var25.getBlockCount());
            this.sendUpdate();
            this.sendArea();
            this.sendFeedback(Message.translation("server.builderTools.selectionMovedBy").param("x", var2.x()).param("y", var2.y()).param("z", var2.z()), var5);
         }
      }

      class="kw">public void shift(@Nonnull Ref<EntityStore> var1, @Nonnull Vector3i var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var3);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var3);
         } else {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
            this.selection.setSelectionArea(this.selection.getSelectionMin().add(var2), this.selection.getSelectionMax().add(var2));
            this.syncRawPositions();
            this.sendArea();
            this.sendFeedback(
               Message.translation("server.builderTools.selectionShiftedBy").param("x", var2.x()).param("y", var2.y()).param("z", var2.z()), var3
            );
         }
      }

      class="kw">public void pos1(@Nonnull Vector3i var1, ComponentAccessor<EntityStore> var2) {
         this.rawPos1 = new Vector3i(var1);
         if (this.selection == null) {
            this.selection = new BlockSelection();
         }

         if (this.selection.hasSelectionBounds()) {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
            if (this.rawPos2 == null) {
               this.rawPos2 = this.selection.getSelectionMax();
            }
         } else {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, ClipboardBoundsSnapshot.EMPTY);
         }

         Vector3i var3 = this.rawPos2 != null ? this.rawPos2 : var1;
         this.selection.setSelectionArea(var1, var3);
         this.sendArea();
         this.sendFeedback(
            Message.translation("server.builderTools.setPosTo").param("num", 1).param("x", var1.x()).param("y", var1.y()).param("z", var1.z()), var2
         );
      }

      class="kw">public void pos2(@Nonnull Vector3i var1, ComponentAccessor<EntityStore> var2) {
         this.rawPos2 = new Vector3i(var1);
         if (this.selection == null) {
            this.selection = new BlockSelection();
         }

         if (this.selection.hasSelectionBounds()) {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
            if (this.rawPos1 == null) {
               this.rawPos1 = this.selection.getSelectionMin();
            }
         } else {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, ClipboardBoundsSnapshot.EMPTY);
         }

         Vector3i var3 = this.rawPos1 != null ? this.rawPos1 : var1;
         this.selection.setSelectionArea(var3, var1);
         this.sendArea();
         this.sendFeedback(
            Message.translation("server.builderTools.setPosTo").param("num", 2).param("x", var1.x()).param("y", var1.y()).param("z", var1.z()), var2
         );
      }

      class="kw">public void select(@Nonnull Vector3i var1, @Nonnull Vector3i var2, @Nullable String var3, ComponentAccessor<EntityStore> var4) {
         this.select(var1, var2, var3, true, var4);
      }

      class="kw">public void syncSelection(@Nonnull Vector3i var1, @Nonnull Vector3i var2, ComponentAccessor<EntityStore> var3) {
         this.select(var1, var2, null, false, var3);
      }

      class="kw">private void select(@Nonnull Vector3i var1, @Nonnull Vector3i var2, @Nullable String var3, boolean var4, ComponentAccessor<EntityStore> var5) {
         if (this.selection != null && !this.selection.getSelectionMax().equals(Vector3iUtil.ZERO)) {
            if (var4) {
               this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
            }

            this.selection.setSelectionArea(var1, var2);
            this.syncRawPositions();
            this.sendArea();
         } else {
            if (this.selection == null) {
               this.selection = new BlockSelection();
            }

            if (var4) {
               this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, ClipboardBoundsSnapshot.EMPTY);
            }

            this.selection.setSelectionArea(var1, var2);
            this.syncRawPositions();
            this.sendArea();
         }

         if (var4) {
            if (var3 != null) {
               this.sendFeedback(
                  Message.translation(var3)
                     .param("x1", var1.x())
                     .param("y1", var1.y())
                     .param("z1", var1.z())
                     .param("x2", var2.x())
                     .param("y2", var2.y())
                     .param("z2", var2.z()),
                  var5
               );
            } else {
               this.sendFeedback(
                  Message.translation("server.builderTools.selected")
                     .param("x1", var1.x())
                     .param("y1", var1.y())
                     .param("z1", var1.z())
                     .param("x2", var2.x())
                     .param("y2", var2.y())
                     .param("z2", var2.z()),
                  var5
               );
            }
         }
      }

      class="kw">public void deselect(ComponentAccessor<EntityStore> var1) {
         if (this.selection != null && this.selection.hasSelectionBounds()) {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
            this.selection.setSelectionArea(Vector3iUtil.ZERO, Vector3iUtil.ZERO);
            this.rawPos1 = null;
            this.rawPos2 = null;
            EditorBlocksChange var2 = new EditorBlocksChange();
            var2.selection = null;
            this.playerRef.getPacketHandler().write(var2);
            this.sendFeedback(Message.translation("server.builderTools.deselected"), var1);
            BiConsumer var3 = BuilderToolsPlugin.get().getSelectionClearedCallback();
            if (var3 != null) {
               World var4 = var1.getExternalData().getWorld();
               if (var4 != null) {
                  var3.accept(this.playerRef, var4.getEntityStore().getStore());
               }
            }
         } else {
            this.sendFeedback(Message.translation("server.builderTools.noSelectionToDeselect"), var1);
         }
      }

      class="kw">public void stack(@Nonnull Ref<EntityStore> var1, @Nonnull Vector3i var2, int var3, boolean var4, int var5, @Nonnull ComponentAccessor<EntityStore> var6) {
         this.extrudeSelectionFace(var1, var2, var3, var5, var4, var6);
      }

      class="kw">public void extrudeSelectionFace(
         @Nonnull Ref<EntityStore> var1, @Nonnull Vector3i var2, int var3, int var4, boolean var5, @Nonnull ComponentAccessor<EntityStore> var6
      ) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var6);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var6);
         } else if (var3 > 0) {
            if (!this.selectionExceedsEditLimit(var6)) {
               this.extrudeFace(this.selection.getSelectionMin(), this.selection.getSelectionMax(), var2, var3, var4, var5, var6);
            }
         }
      }

      class="kw">public void extrudeFaceSlice(
         @Nonnull Vector3i var1, @Nonnull Vector3i var2, @Nonnull Vector3i var3, int var4, int var5, @Nonnull ComponentAccessor<EntityStore> var6
      ) {
         if (var4 > 0) {
            Vector3i var7 = Vector3iUtil.min(var1, var2);
            Vector3i var8 = Vector3iUtil.max(var1, var2);
            long var9 = Vector3iUtil.inclusiveBoxVolume(var7.x(), var7.y(), var7.z(), var8.x(), var8.y(), var8.z());
            if (!this.editVolumeExceedsLimit(var9, var6)) {
               this.extrudeFace(var7, var8, var3, var4, var5, false, var6);
            }
         }
      }

      class="kw">private void extrudeFace(
         @Nonnull Vector3i var1, @Nonnull Vector3i var2, @Nonnull Vector3i var3, int var4, int var5, boolean var6, @Nonnull ComponentAccessor<EntityStore> var7
      ) {
         int var8 = var3.x();
         int var9 = var3.y();
         int var10 = var3.z();
         long var11 = System.nanoTime();
         Vector3i var13 = Vector3iUtil.min(var1, var2);
         Vector3i var14 = Vector3iUtil.max(var1, var2);
         int var15 = var13.x();
         int var16 = var14.x();
         int var17 = var13.y();
         int var18 = var14.y();
         int var19 = var13.z();
         int var20 = var14.z();
         int var21 = var16 - var15;
         int var22 = var20 - var19;
         int var23 = var15 + var21 / 2;
         int var24 = var19 + var22 / 2;
         int var25 = var8 * (var16 - var15 + 1 + var5);
         int var26 = var9 * (var18 - var17 + 1 + var5);
         int var27 = var10 * (var20 - var19 + 1 + var5);
         int var28 = Math.max(Math.abs(var25), Math.abs(var27));
         int var29 = Math.max(var21, var22) + (var4 + 1) * var28;
         World var30 = var7.getExternalData().getWorld();
         LocalCachedChunkAccessor var31 = LocalCachedChunkAccessor.atWorldCoords(var30, var23, var24, var29);
         LongOpenHashSet var32 = new LongOpenHashSet();

         for (int var33 = var15; var33 <= var16; var33++) {
            for (int var34 = var19; var34 <= var20; var34++) {
               WorldChunk var35 = var31.getChunk(ChunkUtil.indexChunkFromBlock(var33, var34));

               for (int var36 = var17; var36 <= var18; var36++) {
                  int var37 = var35.getBlock(var33, var36, var34);
                  int var38 = var35.getFluidId(var33, var36, var34);
                  if ((var37 > 0 || var38 != 0 || var6)
                     && var35.getFiller(var33, var36, var34) == 0
                     && (this.globalMask == null || !this.globalMask.isExcluded(var31, var33, var36, var34, var13, var14, var37, var38))) {
                     var32.add(BlockUtil.pack(var33, var36, var34));
                  }
               }
            }
         }

         if (var32.isEmpty()) {
            this.sendUpdate();
            this.sendArea();
         } else if (!this.editVolumeExceedsLimit((long)var32.size() * var4, var7)) {
            int var43 = var32.size() * var4 * 4;
            BlockSelection var44 = new BlockSelection(var43, 0);
            var44.setPosition(var23, var17, var24);
            BlockSelection var45 = new BlockSelection(var43, 0);
            var45.copyPropertiesFrom(var44);
            this.extrudeAlongFace(var31, var32, var8, var9, var10, var4, var5, var25, var26, var27, true, BlockPattern.EMPTY, var44, var45);
            var45.placeNoReturn("Extrude", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var30, var7);
            Vector3i var46 = new Vector3i(var25, var26, var27).mul(var4);
            Vector3i var47 = Vector3iUtil.min(var13, new Vector3i(var13).add(var46));
            Vector3i var48 = Vector3iUtil.max(var14, new Vector3i(var14).add(var46));
            var44.setSelectionArea(var47, var48);
            this.pushHistory(BuilderToolsPlugin.Action.STACK, new BlockSelectionSnapshot(var44));
            BuilderToolsPlugin.invalidateWorldMapForSelection(var44, var30);
            long var39 = System.nanoTime();
            long var41 = var39 - var11;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to extrude selection face of %d columns %d deep", var41, TimeUnit.NANOSECONDS.toMillis(var41), var32.size(), var4);
            this.sendUpdate();
            this.sendArea();
            this.sendFeedback(
               Message.translation("server.builderTools.selectionStacked").param("count", var4).param("x", var3.x()).param("y", var3.y()).param("z", var3.z()),
               var7
            );
         }
      }

      class="kw">public void expand(@Nonnull Ref<EntityStore> var1, @Nonnull Vector3i var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var3);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var3);
         } else {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
            Vector3i var4 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var5 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            if (var2.x() < 0) {
               var4 = var4.add(var2.x(), 0, 0);
            } else if (var2.x() > 0) {
               var5 = var5.add(var2.x(), 0, 0);
            }

            if (var2.y() < 0) {
               var4 = var4.add(0, var2.y(), 0);
            } else if (var2.y() > 0) {
               var5 = var5.add(0, var2.y(), 0);
            }

            if (var2.z() < 0) {
               var4 = var4.add(0, 0, var2.z());
            } else if (var2.z() > 0) {
               var5 = var5.add(0, 0, var2.z());
            }

            this.selection.setSelectionArea(var4, var5);
            this.syncRawPositions();
            this.sendArea();
            this.sendFeedback(Message.translation("server.builderTools.selectionExpanded").param("x", var2.x()).param("y", var2.y()).param("z", var2.z()), var3);
         }
      }

      class="kw">public void contract(@Nonnull Ref<EntityStore> var1, @Nonnull Vector3i var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var3);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var3);
         } else {
            this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
            Vector3i var4 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var5 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            if (var2.x() > 0) {
               var4 = var4.add(var2.x(), 0, 0);
            } else if (var2.x() < 0) {
               var5 = var5.add(var2.x(), 0, 0);
            }

            if (var2.y() > 0) {
               var4 = var4.add(0, var2.y(), 0);
            } else if (var2.y() < 0) {
               var5 = var5.add(0, var2.y(), 0);
            }

            if (var2.z() > 0) {
               var4 = var4.add(0, 0, var2.z());
            } else if (var2.z() < 0) {
               var5 = var5.add(0, 0, var2.z());
            }

            this.selection.setSelectionArea(var4, var5);
            this.syncRawPositions();
            this.sendArea();
            this.sendFeedback(
               var1,
               Message.translation("server.builderTools.selectionContracted").param("x", var2.x()).param("y", var2.y()).param("z", var2.z()),
               var2.length() > 0.0 ? "CREATE_SCALE_INCREASE" : "CREATE_SCALE_DECREASE",
               var3
            );
         }
      }

      class="kw">public void shrink(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var2);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var2);
         } else {
            World var3 = var2.getExternalData().getWorld();
            Vector3i var4 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var5 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            int var6 = var4.x();
            int var7 = var5.x();
            int var8 = var4.y();
            int var9 = var5.y();
            int var10 = var4.z();
            int var11 = var5.z();
            int var12 = var7 - var6;
            int var13 = var11 - var10;
            int var14 = var12 / 2;
            int var15 = var13 / 2;
            LocalCachedChunkAccessor var16 = LocalCachedChunkAccessor.atWorldCoords(var3, var6 + var14, var10 + var15, Math.max(var12, var13));
            int var17 = BlockType.getAssetMap().getIndex("Editor_Empty");
            int var18 = Integer.MAX_VALUE;
            int var19 = Integer.MAX_VALUE;
            int var20 = Integer.MAX_VALUE;
            int var21 = Integer.MIN_VALUE;
            int var22 = Integer.MIN_VALUE;
            int var23 = Integer.MIN_VALUE;
            int var24 = Math.max(var8, var9);
            int var25 = Math.min(var8, var9);
            int var26 = (var12 + 1) * (var13 + 1) * (var24 - var25 + 1);
            int var27 = 0;

            for (int var28 = var6; var28 <= var7; var28++) {
               for (int var29 = var10; var29 <= var11; var29++) {
                  WorldChunk var30 = var16.getChunk(ChunkUtil.indexChunkFromBlock(var28, var29));

                  for (int var31 = var25; var31 <= var24; var31++) {
                     int var32 = var30.getBlock(var28, var31, var29);
                     int var33 = var30.getFluidId(var28, var31, var29);
                     if (var32 != 0 && var32 != var17 || var33 != 0) {
                        var18 = Math.min(var18, var28);
                        var19 = Math.min(var19, var31);
                        var20 = Math.min(var20, var29);
                        var21 = Math.max(var21, var28);
                        var22 = Math.max(var22, var31);
                        var23 = Math.max(var23, var29);
                     }

                     this.sendFeedback("Shrink", var26, ++var27, var2);
                  }
               }
            }

            if (var18 == Integer.MAX_VALUE) {
               this.sendFeedback(Message.translation("server.builderTools.selectionShrinkEmpty"), var2);
            } else {
               Vector3i var34 = new Vector3i(var18, var19, var20);
               Vector3i var35 = new Vector3i(var21, var22, var23);
               if (var34.equals(var4) && var35.equals(var5)) {
                  this.sendFeedback(Message.translation("server.builderTools.selectionShrinkUnchanged"), var2);
               } else {
                  int var36 = (var7 - var6 + 1) * (var9 - var8 + 1) * (var11 - var10 + 1);
                  int var37 = (var21 - var18 + 1) * (var22 - var19 + 1) * (var23 - var20 + 1);
                  this.pushHistory(BuilderToolsPlugin.Action.UPDATE_SELECTION, new ClipboardBoundsSnapshot(this.selection));
                  this.selection.setSelectionArea(var34, var35);
                  this.syncRawPositions();
                  this.sendArea();
                  this.sendFeedback(Message.translation("server.builderTools.selectionShrunk").param("oldCount", var36).param("newCount", var37), var2);
               }
            }
         }
      }

      class="kw">public void repairFillers(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var2);
         } else if (!this.selection.hasSelectionBounds()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var2);
         } else if (!this.selectionExceedsEditLimit(var2)) {
            long var3 = System.nanoTime();
            Vector3i var5 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            Vector3i var6 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            int var7 = var5.x();
            int var8 = var6.x();
            int var9 = var5.y();
            int var10 = var6.y();
            int var11 = var5.z();
            int var12 = var6.z();
            int var13 = (var8 - var7 + 1) * (var12 - var11 + 1) * (var10 - var9 + 1);
            int var14 = var8 - var7;
            int var15 = var10 - var9;
            int var16 = var12 - var11;
            int var17 = var14 / 2;
            int var18 = var15 / 2;
            int var19 = var16 / 2;
            BlockSelection var20 = new BlockSelection(var13, 0);
            var20.setPosition(var7 + var17, var9, var11 + var19);
            var20.setSelectionArea(var5, var6);
            this.pushHistory(BuilderToolsPlugin.Action.SET, new BlockSelectionSnapshot(var20));
            BlockSelection var21 = new BlockSelection(var13, 0);
            var21.copyPropertiesFrom(var20);
            World var22 = var2.getExternalData().getWorld();
            Store var23 = var22.getChunkStore().getStore();
            BuilderToolsPlugin.CachedAccessor var24 = BuilderToolsPlugin.CachedAccessor.of(
               var23,
               ChunkUtil.chunkCoordinate(var7 + var17),
               ChunkUtil.chunkCoordinate(var9 + var18),
               ChunkUtil.chunkCoordinate(var11 + var19),
               var14 - var17,
               var15 - var18,
               var16 - var19
            );
            BlockTypeAssetMap var25 = BlockType.getAssetMap();
            IndexedLookupTableAssetMap var26 = BlockBoundingBoxes.getAssetMap();
            int var27 = 0;

            for (int var28 = var7; var28 <= var8; var28++) {
               int var29 = ChunkUtil.chunkCoordinate(var28);

               for (int var30 = var11; var30 <= var12; var30++) {
                  int var31 = ChunkUtil.chunkCoordinate(var30);
                  Ref var32 = var24.getColumn(var29, var31);
                  WorldChunk var33 = var23.getComponent(var32, WorldChunk.getComponentType());

                  for (int var34 = var10; var34 >= var9; var34--) {
                     int var35 = ChunkUtil.chunkCoordinate(var34);
                     BlockSection var36 = var24.getBlockSection(var29, var35, var31);
                     if (var36 != null) {
                        int var37 = var36.get(var28, var34, var30);
                        BlockType var38 = var25.getAsset(var37);
                        if (var38 != null) {
                           BlockPhysics var39 = var24.getBlockPhysics(var29, var35, var31);
                           BlockBoundingBoxes var40 = var26.getAsset(var38.getHitboxTypeIndex());
                           if (var36.getFiller(var28, var34, var30) != 0) {
                              var20.copyFromAtWorld(var28, var34, var30, var33, var39);
                              var21.copyFromAtWorld(var28, var34, var30, var33, var39);
                           } else if (var40 != null && var40.protrudesUnitBox()) {
                              var20.copyFromAtWorld(var28, var34, var30, var33, var39);
                              var21.copyFromAtWorld(var28, var34, var30, var33, var39);
                              int var41 = var28;
                              int var42 = var34;
                              int var43 = var30;
                              FillerBlockUtil.forEachFillerBlock(
                                 var40.get(var36.getRotationIndex(var28, var34, var30)),
                                 (var6x, var7x, var8x) -> var20.copyFromAtWorld(var41 + var6x, var42 + var7x, var43 + var8x, var33, var39)
                              );
                           }

                           this.sendFeedback("Set 1/2", var13, ++var27, var2);
                        }
                     }
                  }
               }
            }

            var21.tryFixFiller(false);
            var21.placeNoReturn("Set 2/2", this.playerRef, BuilderToolsPlugin.FEEDBACK_CONSUMER, var22, var2);
            BuilderToolsPlugin.invalidateWorldMapForSelection(var21, var22);
            long var44 = System.nanoTime();
            long var45 = var44 - var3;
            BuilderToolsPlugin.get()
               .getLogger()
               .at(Level.FINE)
               .log("Took: %dns (%dms) to execute repair of %d blocks", var45, TimeUnit.NANOSECONDS.toMillis(var45), var21.getBlockCount());
            this.sendUpdate();
            this.sendArea();
         }
      }

      @Nonnull
      class="kw">public List<BuilderToolsPlugin.ActionEntry> undo(@Nonnull Ref<EntityStore> var1, int var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         this.commitPendingUndoGroup();
         this.commitPendingEntitySessions();
         long var4 = System.nanoTime();
         BlockSelection var6 = this.selection;
         List var7 = new ObjectArrayList();

         for (int var8 = 0; var8 < var2; var8++) {
            BuilderToolsPlugin.ActionEntry var9 = this.historyAction(var1, this.undo, this.redo, var3);
            if (var9 == null) {
               break;
            }

            var7.add(var9);
         }

         if (var6 != this.selection) {
            this.sendUpdate();
            this.sendArea();
         }

         long var15 = System.nanoTime();
         long var10 = var15 - var4;
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute undo of %d actions", var10, TimeUnit.NANOSECONDS.toMillis(var10), var2);
         if (var7.isEmpty()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.nothingToUndo"), var3);
         } else {
            int var12 = 0;

            for (BuilderToolsPlugin.ActionEntry var14 : var7) {
               if (var14.isEntityNotFound()) {
                  this.sendErrorFeedback(var1, Message.translation("server.builderTools.undoEntityNotFound"), var3);
               } else {
                  this.sendFeedback(
                     var1,
                     Message.translation("server.builderTools.undoStatus").param("index", ++var12).param("action", var14.getAction().toMessage()),
                     "CREATE_UNDO",
                     var3
                  );
               }
            }
         }

         class="kw">return var7;
      }

      @Nonnull
      class="kw">public List<BuilderToolsPlugin.ActionEntry> redo(@Nonnull Ref<EntityStore> var1, int var2, @Nonnull ComponentAccessor<EntityStore> var3) {
         this.commitPendingEntitySessions();
         long var4 = System.nanoTime();
         BlockSelection var6 = this.selection;
         List var7 = new ObjectArrayList();

         for (int var8 = 0; var8 < var2; var8++) {
            BuilderToolsPlugin.ActionEntry var9 = this.historyAction(var1, this.redo, this.undo, var3);
            if (var9 == null) {
               break;
            }

            var7.add(var9);
         }

         if (var6 != this.selection) {
            this.sendUpdate();
            this.sendArea();
         }

         long var15 = System.nanoTime();
         long var10 = var15 - var4;
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute redo of %d actions", var10, TimeUnit.NANOSECONDS.toMillis(var10), var2);
         if (var7.isEmpty()) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.nothingToRedo"), var3);
         } else {
            int var12 = 0;

            for (BuilderToolsPlugin.ActionEntry var14 : var7) {
               if (var14.isEntityNotFound()) {
                  this.sendErrorFeedback(var1, Message.translation("server.builderTools.redoEntityNotFound"), var3);
               } else {
                  this.sendFeedback(
                     var1,
                     Message.translation("server.builderTools.redoStatus").param("index", ++var12).param("action", var14.getAction().toMessage()),
                     "CREATE_REDO",
                     var3
                  );
               }
            }
         }

         class="kw">return var7;
      }

      class="kw">public void save(
         @Nonnull Ref<EntityStore> var1,
         @Nonnull String var2,
         boolean var3,
         boolean var4,
         @Nonnull SupportMode var5,
         @Nullable AssetPack var6,
         @Nonnull PrefabFormat var7,
         ComponentAccessor<EntityStore> var8
      ) {
         if (this.selection == null) {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelection"), var8);
         } else {
            long var9 = System.nanoTime();
            var2 = var2.trim();
            if (var2.isBlank()) {
               this.sendErrorFeedback(var1, Message.translation("server.builderTools.prefabSave.nameRequired"), var8);
            } else if (var2.contains("..")) {
               this.sendFeedback(Message.translation("server.builderTools.attemptedToSaveOutsidePrefabsDir"), var8);
            } else {
               if (!PrefabStore.isPrefabFileName(var2)) {
                  var2 = var2 + ".prefab.json";
               }

               PrefabStore var11 = PrefabStore.get();
               Path var12 = var11.getPrefabsPathForPack(var6);
               if (!PathUtil.isChildOf(var12, var12.resolve(var2)) && !SingleplayerModule.isOwner(this.playerRef)) {
                  this.sendFeedback(Message.translation("server.builderTools.attemptedToSaveOutsidePrefabsDir"), var8);
               } else {
                  BlockSelection var13 = this.selection.cloneSelection();
                  long var14 = this.selection.getBlockCount();
                  this.sendUpdate();
                  boolean var16 = BuilderToolsPlugin.shouldShowNotification(var1, var8);
                  this.persistPrefabAsync(var13, var3, var2, var4, var5, var6, var7, var16, var14, var9);
               }
            }
         }
      }

      class="kw">private void persistPrefabAsync(
         @Nonnull BlockSelection var1,
         boolean var2,
         @Nonnull String var3,
         boolean var4,
         @Nonnull SupportMode var5,
         @Nullable AssetPack var6,
         @Nonnull PrefabFormat var7,
         boolean var8,
         long var9,
         long var11
      ) {
         PacketHandler var13 = this.playerRef.getPacketHandler();
         PrefabStore var14 = PrefabStore.get();
         String var15 = this.currentProgressTag();
         BuilderToolsPlugin.get()
            .prefabSaveExecutor
            .execute(
               () -> {
                  AtomicBoolean var16 = new AtomicBoolean(false);
                  ScheduledFuture var17 = var8 ? this.startWritingToDiskAnimation(var13, var15, var16) : null;

                  try {
                     Path var18;
                     try {
                        if (var2) {
                           var1.relativizeInPlace();
                        }

                        PrefabSaveSupport.apply(var1, var5);
                        if (var6 != null) {
                           var18 = var14.savePrefabToPack(var6, var3, var1, var4, var7);
                        } else {
                           var18 = var14.saveServerPrefab(var3, var1, var4, var7);
                        }
                     } class="kw">finally {
                        var16.set(true);
                        if (var17 != null) {
                           var17.cancel(false);
                        }
                     }

                     if (var8) {
                        String var19 = PathUtil.relativize(var14.getPrefabsPathForPack(var6), var18).toString().replace('\\', '/');
                        String var20 = var6 != null ? "server.builderTools.savedSelectionToPrefab.pack" : "server.builderTools.savedSelectionToPrefab";
                        Message var21 = Message.translation(var20).param("name", var19);
                        if (var6 != null) {
                           var21 = var21.param("pack", var6.getName());
                        }

                        NotificationUtil.sendNotification(var13, var21, null, null, null, NotificationStyle.Default, var15);
                     }
                  } catch (PrefabSaveException var34) {
                     class="kw">switch (var34.getType()) {
                        case ERROR:
                           ((HytaleLogger.Api)BuilderToolsPlugin.get().getLogger().at(Level.WARNING).withCause(var34)).log("Exception saving prefab %s", var3);
                           if (var8) {
                              NotificationUtil.sendNotification(
                                 var13,
                                 Message.translation("server.builderTools.errorSavingPrefab")
                                    .param("name", var3)
                                    .param("message", var34.getCause().getMessage()),
                                 null,
                                 null,
                                 null,
                                 NotificationStyle.Default,
                                 var15
                              );
                           }
                           break;
                        case ALREADY_EXISTS:
                           BuilderToolsPlugin.get().getLogger().at(Level.WARNING).log("Prefab already exists %s", var3);
                           if (var8) {
                              NotificationUtil.sendNotification(
                                 var13, Message.translation("server.builderTools.prefabAlreadyExists"), null, null, null, NotificationStyle.Default, var15
                              );
                           }
                     }
                  } catch (Throwable var35) {
                     ((HytaleLogger.Api)BuilderToolsPlugin.get().getLogger().at(Level.WARNING).withCause(var35)).log("Unexpected error saving prefab %s", var3);
                  } class="kw">finally {
                     long var23 = System.nanoTime() - var11;
                     BuilderToolsPlugin.get()
                        .getLogger()
                        .at(Level.FINE)
                        .log("Took: %dns (%dms) to execute prefab save of %d blocks", var23, TimeUnit.NANOSECONDS.toMillis(var23), var9);
                  }
               }
            );
      }

      @Nonnull
      class="kw">private ScheduledFuture<?> startWritingToDiskAnimation(@Nonnull class="kw">final PacketHandler var1, @Nonnull class="kw">final String var2, @Nonnull class="kw">final AtomicBoolean var3) {
         class="kw">return HytaleServer.SCHEDULED_EXECUTOR
            .scheduleWithFixedDelay(
               new Runnable() {
                  class="kw">private int tick = 0;

                  @Override
                  class="kw">public void run() {
                     if (!var3.get()) {
                        String var1x = ".".repeat(this.tick++ % 3 + 1);
                        NotificationUtil.sendNotification(
                           var1,
                           Message.translation("server.builderTools.prefabSaving.title"),
                           Message.translation("server.builderTools.prefabSaving.writingToDisk").param("dots", var1x),
                           null,
                           null,
                           NotificationStyle.Success,
                           var2
                        );
                     }
                  }
               },
               0L,
               400L,
               TimeUnit.MILLISECONDS
            );
      }

      class="kw">public void saveFromSelection(
         @Nonnull Ref<EntityStore> var1,
         @Nonnull String var2,
         boolean var3,
         boolean var4,
         boolean var5,
         boolean var6,
         @Nullable Vector3i var7,
         @Nonnull SupportMode var8,
         @Nullable AssetPack var9,
         @Nonnull PrefabFormat var10,
         @Nonnull ComponentAccessor<EntityStore> var11
      ) {
         if (this.selection != null
            && (!this.selection.getSelectionMin().equals(Vector3iUtil.ZERO) || !this.selection.getSelectionMax().equals(Vector3iUtil.ZERO))) {
            World var12 = var11.getExternalData().getWorld();
            long var13 = System.nanoTime();
            var2 = var2.trim();
            if (var2.isBlank()) {
               this.sendErrorFeedback(var1, Message.translation("server.builderTools.prefabSave.nameRequired"), var11);
            } else if (var2.contains("..")) {
               this.sendFeedback(Message.translation("server.builderTools.attemptedToSaveOutsidePrefabsDir"), var11);
            } else {
               if (!PrefabStore.isPrefabFileName(var2)) {
                  var2 = var2 + ".prefab.json";
               }

               PrefabStore var15 = PrefabStore.get();
               Path var16 = var15.getPrefabsPathForPack(var9);
               if (!PathUtil.isChildOf(var16, var16.resolve(var2)) && !SingleplayerModule.isOwner(this.playerRef)) {
                  this.sendFeedback(Message.translation("server.builderTools.attemptedToSaveOutsidePrefabsDir"), var11);
               } else {
                  Vector3i var17 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
                  Vector3i var18 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
                  int var19 = var17.x();
                  int var20 = var17.y();
                  int var21 = var17.z();
                  int var22 = var18.x();
                  int var23 = var18.y();
                  int var24 = var18.z();
                  int var25 = var22 - var19;
                  int var26 = var23 - var20;
                  int var27 = var24 - var21;
                  int var28 = var25 / 2;
                  int var29 = var27 / 2;
                  LocalCachedChunkAccessor var30 = LocalCachedChunkAccessor.atWorldCoords(var12, var19 + var28, var21 + var29, Math.max(var25, var27));
                  BlockTypeAssetMap var31 = BlockType.getAssetMap();
                  int var32 = var31.getIndex("Editor_Block");
                  int var33 = var31.getIndex("Editor_Empty");
                  int var34 = var31.getIndex("Editor_Anchor");
                  BlockSelection var35 = new BlockSelection();
                  var35.setPosition(var19 + var28, var20, var21 + var29);
                  var35.setSelectionArea(var17, var18);
                  int var36 = 0;
                  int var37 = Math.max(var20, var23);
                  int var38 = Math.min(var20, var23);
                  int var39 = (int)Math.min(2147483647L, (long)(var22 - var19 + 1) * (var24 - var21 + 1) * (var37 - var38 + 1));
                  int var40 = 0;

                  for (int var41 = var19; var41 <= var22; var41++) {
                     for (int var42 = var21; var42 <= var24; var42++) {
                        WorldChunk var43 = var30.getChunk(ChunkUtil.indexChunkFromBlock(var41, var42));
                        Store var44 = var43.getReference().getStore();
                        ChunkColumn var45 = var44.getComponent(var43.getReference(), ChunkColumn.getComponentType());
                        int var46 = -1;
                        BlockPhysics var47 = null;

                        for (int var48 = var37; var48 >= var38; var48--) {
                           this.sendFeedback("Save", var39, ++var40, var11);
                           int var49 = var43.getBlock(var41, var48, var42);
                           int var50 = var43.getFluidId(var41, var48, var42);
                           if (var46 != ChunkUtil.chunkCoordinate(var48)) {
                              var46 = ChunkUtil.chunkCoordinate(var48);
                              Ref var51 = var45.getSection(var46);
                              if (var51 != null) {
                                 var47 = var44.getComponent(var51, BlockPhysics.getComponentType());
                              } else {
                                 var47 = null;
                              }
                           }

                           if (var49 == var34 && var7 == null) {
                              var35.setAnchorAtWorldPos(var41, var48, var42);
                              int var57 = BuilderToolsPlugin.getNonEmptyNeighbourBlock(var30, var41, var48, var42);
                              if (var57 > 0 && var57 != var33) {
                                 var35.addBlockAtWorldPos(var41, var48, var42, var57, 0, 0, 0);
                                 var36++;
                              } else if (var57 == var33) {
                                 var35.addBlockAtWorldPos(var41, var48, var42, 0, 0, 0, 0);
                                 var36++;
                              }
                           } else if ((var49 != 0 || var50 != 0 || var6) && var49 != var32) {
                              if (var49 == var33) {
                                 var35.addBlockAtWorldPos(var41, var48, var42, 0, 0, 0, 0);
                              } else {
                                 var35.copyFromAtWorld(var41, var48, var42, var43, var47);
                              }

                              var36++;
                           }
                        }
                     }
                  }

                  if (var7 != null) {
                     var35.setAnchorAtWorldPos(var7.x(), var7.y(), var7.z());
                  }

                  if (var5) {
                     Store var53 = var12.getEntityStore().getStore();
                     BuilderToolsPlugin.forEachCopyableInSelection(var12, var19, var20, var21, var25, var26, var27, var2x -> {
                        Holder var3 = var53.copyEntity(var2x);
                        var35.addEntityFromWorld(var3);
                     });
                  }

                  for (PrefabSaveContributor var56 : BuilderToolsPlugin.get().getPrefabSaveContributors()) {
                     var56.contribute(var35, var12, new Vector3i(var19, var20, var21), new Vector3i(var22, var23, var24));
                  }

                  boolean var55 = BuilderToolsPlugin.shouldShowNotification(var1, var11);
                  this.persistPrefabAsync(var35, var3, var2, var4, var8, var9, var10, var55, var36, var13);
               }
            }
         } else {
            this.sendErrorFeedback(var1, Message.translation("server.builderTools.noSelectionBounds"), var11);
         }
      }

      class="kw">public void load(@Nonnull String var1, @Nonnull BlockSelection var2, ComponentAccessor<EntityStore> var3) {
         long var4 = System.nanoTime();

         try {
            Vector3ic var6 = Vector3iUtil.ZERO;
            Vector3ic var7 = Vector3iUtil.ZERO;
            if (this.selection != null) {
               Objects.requireNonNull(this.selection.getSelectionMin(), "min is null");
               Objects.requireNonNull(this.selection.getSelectionMax(), "max is null");
               var6 = Vector3iUtil.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
               var7 = Vector3iUtil.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
            }

            this.pushHistory(
               BuilderToolsPlugin.Action.COPY, ClipboardContentsSnapshot.copyOf(Objects.requireNonNullElseGet(this.selection, BlockSelection::new))
            );
            this.setSelection(var2.cloneSelection());
            this.selection.setSelectionArea(var6, var7);
            this.cumulativeRotX = this.cumulativeRotY = this.cumulativeRotZ = 0;
            this.syncRawPositions();
            this.sendUpdate();
            this.sendFeedback(Message.translation("server.builderTools.loadedPrefab").param("name", var1), var3);
         } catch (PrefabLoadException var10) {
            class="kw">switch (var10.getType()) {
               case ERROR:
                  ((HytaleLogger.Api)BuilderToolsPlugin.get().getLogger().at(Level.WARNING).withCause(var10)).log("Exception loading prefab %s", var1);
                  this.sendFeedback(
                     Message.translation("server.builderTools.errorSavingPrefab").param("name", var1).param("message", var10.getCause().getMessage()), var3
                  );
                  break;
               case NOT_FOUND:
                  BuilderToolsPlugin.get().getLogger().at(Level.WARNING).log("Prefab doesn't exist %s", var1);
                  this.sendFeedback(Message.translation("server.builderTools.prefabDoesNotExist").param("name", var1), var3);
            }
         }

         long var11 = System.nanoTime();
         long var8 = var11 - var4;
         BuilderToolsPlugin.get()
            .getLogger()
            .at(Level.FINE)
            .log("Took: %dns (%dms) to execute load of %d blocks", var8, TimeUnit.NANOSECONDS.toMillis(var8), this.selection.getBlockCount());
      }

      class="kw">public void clearHistory(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         long var3 = this.undoLock.writeLock();

         try {
            this.undo.clear();
            this.redo.clear();
         } class="kw">finally {
            this.undoLock.unlockWrite(var3);
         }

         this.sendFeedback(Message.translation("server.builderTools.historyCleared"), var2);
      }

      class="kw">public void setGlobalMask(@Nullable BlockMask var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         this.globalMask = var1;
         if (this.globalMask == null) {
            this.sendFeedback(Message.translation("server.builderTools.maskDisabled"), var2);
         } else {
            this.sendFeedback(Message.translation("server.builderTools.maskSet"), var2);
         }
      }

      class="kw">private void sendUpdate() {
         BlockSelection var1 = Objects.requireNonNullElseGet(this.selection, BlockSelection::new);
         boolean var2 = var1.getBlockCount() > 2000000;
         EditorBlocksChange var3;
         if (this.skipNextPreviewRebuild && var2) {
            var3 = new EditorBlocksChange();
            var3.blocksOmitted = true;
         } else {
            var3 = var2 ? var1.toShapePacket(16000000) : var1.toPacket();
         }

         var3.skipPreviewRebuild = this.skipNextPreviewRebuild;
         this.skipNextPreviewRebuild = false;
         var3.cumulativeRotX = this.cumulativeRotX;
         var3.cumulativeRotY = this.cumulativeRotY;
         var3.cumulativeRotZ = this.cumulativeRotZ;
         this.playerRef.getPacketHandler().write(var3);
      }

      class="kw">public void sendArea() {
         if (this.selection != null) {
            this.playerRef.getPacketHandler().write(this.selection.toSelectionPacket());
         } else {
            EditorBlocksChange var1 = new EditorBlocksChange();
            var1.selection = null;
            this.playerRef.getPacketHandler().write(var1);
         }
      }

      class="kw">public void pushHistory(@Nonnull UndoAction var1, @Nonnull SelectionSnapshot<?> var2) {
         this.pushHistory(var1, Collections.singletonList(var2));
      }

      class="kw">public void pushHistory(@Nonnull UndoAction var1, @Nonnull List<SelectionSnapshot<?>> var2) {
         if (var1 != BuilderToolsPlugin.Action.UPDATE_SELECTION || this.getUserData().isRecordingSelectionHistory()) {
            this.commitPendingUndoGroup();
            long var3 = this.undoLock.writeLock();

            try {
               BuilderToolsPlugin.ActionEntry var5 = new BuilderToolsPlugin.ActionEntry(var1, var2);
               var5.setCumulativeRotBefore(this.cumulativeRotX, this.cumulativeRotY, this.cumulativeRotZ);
               this.undo.enqueue(var5);
               this.redo.clear();
               this.undo.trim(BuilderToolsPlugin.get().historyCount, BuilderToolsPlugin.get().historyBlockBudget);
            } class="kw">finally {
               this.undoLock.unlockWrite(var3);
            }

            if (var1.marksPrefabDirty()) {
               this.markPrefabsDirtyFromSnapshots(var2);
            }
         }
      }

      class="kw">private void handleBrushUndoGrouping(
         @Nonnull BlockSelection var1, @Nonnull List<Ref<EntityStore>> var2, @Nonnull List<EntityTransformSnapshot> var3, int var4, boolean var5
      ) {
         if (!var5) {
            this.commitPendingUndoGroup();
            this.brushStrokeId++;
            this.brushStrokeBlocks = 0;
         }

         this.pinnedProgressTag = "buildertools.brushProgress" + this.brushStrokeId;
         if (var1.getBlockCount() != 0 || var1.getFluidCount() != 0 || var1.getEntityCount() != 0 || var1.getTintCount() != 0) {
            if (this.pendingUndoSnapshot == null) {
               this.pendingUndoSnapshot = var1;
            } else {
               this.mergeBeforeSnapshotPreservingOriginal(var1);
            }

            this.executionCountInGroup++;

            for (Ref var7 : var2) {
               this.pendingEntitySnapshots.add(new EntityAddSnapshot(var7));
            }

            this.pendingEntityTransformSnapshots.addAll(var3);
            if (this.executionCountInGroup >= var4) {
               this.commitPendingUndoGroup();
            }
         }
      }

      class="kw">private void mergeBeforeSnapshotPreservingOriginal(@Nonnull BlockSelection var1) {
         mergeBeforeSelectionPreservingOriginal(this.pendingUndoSnapshot, var1);
      }

      class="kw">private class="kw">static void mergeBeforeSelectionPreservingOriginal(@Nonnull BlockSelection var0, @Nonnull BlockSelection var1) {
         var1.forEachBlock(
            (var2, var3, var4, var5) -> {
               int var6 = var2 + var1.getX();
               int var7 = var3 + var1.getY();
               int var8 = var4 + var1.getZ();
               if (!var0.hasBlockAtWorldPos(var6, var7, var8)) {
                  var0.addBlockAtWorldPos(
                     var6,
                     var7,
                     var8,
                     var5.blockId(),
                     var5.rotation(),
                     var5.filler(),
                     var5.supportValue(),
                     var5.holder() != null ? var5.holder().clone() : null
                  );
               }
            }
         );
         var1.forEachFluid((var2, var3, var4, var5, var6) -> {
            int var7 = var2 + var1.getX();
            int var8 = var3 + var1.getY();
            int var9 = var4 + var1.getZ();
            if (var0.getFluidAtWorldPos(var7, var8, var9) < 0) {
               var0.addFluidAtWorldPos(var7, var8, var9, var5, var6);
            }
         });
         var1.forEachTint((var2, var3, var4) -> {
            int var5 = var2 + var1.getX();
            int var6 = var3 + var1.getZ();
            if (!var0.hasTintAtWorldPos(var5, var6)) {
               var0.addTintAtWorldPos(var5, var6, var4);
            }
         });
         var1.forEachEntity(var1x -> var0.addEntityHolderRaw(var1x));
      }

      class="kw">private class="kw">static void unionSelectionArea(@Nonnull BlockSelection var0, @Nonnull BlockSelection var1) {
         if (var1.hasSelectionBounds()) {
            if (!var0.hasSelectionBounds()) {
               var0.setSelectionArea(var1.getSelectionMin(), var1.getSelectionMax());
            } else {
               var0.setSelectionArea(
                  Vector3iUtil.min(var0.getSelectionMin(), var1.getSelectionMin()), Vector3iUtil.max(var0.getSelectionMax(), var1.getSelectionMax())
               );
            }
         }
      }

      class="kw">private void commitPendingUndoGroup() {
         if (this.pendingUndoSnapshot != null && this.executionCountInGroup > 0) {
            List var1 = new ArrayList<>();
            var1.add(new BlockSelectionSnapshot(this.pendingUndoSnapshot));
            var1.addAll(this.pendingEntitySnapshots);
            var1.addAll(this.pendingEntityTransformSnapshots);
            this.pendingUndoSnapshot = null;
            this.pendingEntitySnapshots.clear();
            this.pendingEntityTransformSnapshots.clear();
            this.executionCountInGroup = 0;
            this.pushHistory(BuilderToolsPlugin.Action.EDIT, var1);
         }
      }

      class="kw">public void handleEntityTransform(@Nonnull Ref<EntityStore> var1, boolean var2, boolean var3, @Nonnull ComponentAccessor<EntityStore> var4) {
         if (var2 && this.pendingEntityTransformSession == null) {
            this.pendingEntityTransformSession = new EntityTransformSnapshot(var1, var4);
         }

         if (var3) {
            this.commitPendingEntitySessions();
         }
      }

      class="kw">public void commitPendingEntityTransformSession() {
         if (this.pendingEntityTransformSession != null) {
            this.pushHistory(BuilderToolsPlugin.Action.ENTITY_TRANSFORM, this.pendingEntityTransformSession);
            this.pendingEntityTransformSession = null;
         }
      }

      class="kw">public void pushEntityCloneHistory(@Nonnull Ref<EntityStore> var1) {
         this.pushHistory(BuilderToolsPlugin.Action.ENTITY_CLONE, new EntityAddSnapshot(var1));
      }

      class="kw">public void pushEntityRemoveHistory(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         if (this.pendingEntityTransformSession != null) {
            this.pendingEntityTransformSession.applyTransform(var2);
            this.pendingEntityTransformSession = null;
         }

         this.pendingEntityScaleSession = null;
         this.pendingEntityScaleRef = null;
         EntityRemoveSnapshot var3 = new EntityRemoveSnapshot(var1);
         this.pushHistory(BuilderToolsPlugin.Action.ENTITY_REMOVE, var3);
      }

      class="kw">public void pushEntityFreezeHistory(@Nonnull EntityFreezeSnapshot var1) {
         this.commitPendingEntitySessions();
         this.pushHistory(BuilderToolsPlugin.Action.ENTITY_FREEZE, var1);
      }

      class="kw">public void pushEntitySettingsHistory(@Nonnull EntitySettingsSnapshot var1) {
         this.commitPendingEntitySessions();
         this.pushHistory(BuilderToolsPlugin.Action.ENTITY_SETTINGS, var1);
      }

      class="kw">public void pushTriggerVolumeHistory(@Nonnull SelectionSnapshot<?> var1) {
         this.commitPendingEntitySessions();
         this.pushHistory(BuilderToolsPlugin.Action.TRIGGER_VOLUME, var1);
      }

      class="kw">public void pushTriggerVolumeHistory(@Nonnull List<SelectionSnapshot<?>> var1) {
         this.commitPendingEntitySessions();
         this.pushHistory(BuilderToolsPlugin.Action.TRIGGER_VOLUME, var1);
      }

      class="kw">public void pushPointHistory(@Nonnull SelectionSnapshot<?> var1) {
         this.commitPendingEntitySessions();
         this.pushHistory(BuilderToolsPlugin.Action.POINT, var1);
      }

      class="kw">public void pushPointHistory(@Nonnull List<SelectionSnapshot<?>> var1) {
         this.commitPendingEntitySessions();
         this.pushHistory(BuilderToolsPlugin.Action.POINT, var1);
      }

      class="kw">public void handleEntityScale(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
         if (this.pendingEntityScaleRef == null || !var1.equals(this.pendingEntityScaleRef)) {
            this.commitPendingEntityScaleSession();
            this.pendingEntityScaleRef = var1;
            this.pendingEntityScaleSession = new EntityScaleSnapshot(var1, var2);
         }
      }

      class="kw">private void commitPendingEntityScaleSession() {
         if (this.pendingEntityScaleSession != null) {
            this.pushHistory(BuilderToolsPlugin.Action.ENTITY_SCALE, this.pendingEntityScaleSession);
            this.pendingEntityScaleSession = null;
            this.pendingEntityScaleRef = null;
         }
      }

      class="kw">private void commitPendingEntitySessions() {
         if (this.pendingEntityTransformSession != null && this.pendingEntityScaleSession != null) {
            List var1 = List.of(this.pendingEntityTransformSession, this.pendingEntityScaleSession);
            this.pendingEntityTransformSession = null;
            this.pendingEntityScaleSession = null;
            this.pendingEntityScaleRef = null;
            this.pushHistory(BuilderToolsPlugin.Action.ENTITY_TRANSFORM, var1);
         } else {
            this.commitPendingEntityTransformSession();
            this.commitPendingEntityScaleSession();
         }
      }

      class="kw">private void markPrefabsDirtyFromSnapshots(@Nonnull List<SelectionSnapshot<?>> var1) {
         PrefabEditSessionManager var2 = BuilderToolsPlugin.get().getPrefabEditSessionManager();
         Map var3 = var2.getActiveEditSessions();
         if (!var3.isEmpty()) {
            for (SelectionSnapshot var5 : var1) {
               if (var5 class="kw">instanceof BlockSelectionSnapshot var6) {
                  BlockSelection var7 = var6.getBlockSelection();
                  Vector3i var8 = var7.getSelectionMin();
                  Vector3i var9 = var7.getSelectionMax();

                  for (Entry var11 : var3.entrySet()) {
                     var11.getValue().markPrefabsDirtyInBounds(var8, var9);
                  }
               }
            }
         }
      }

      @Nullable
      class="kw">private BuilderToolsPlugin.ActionEntry historyAction(
         Ref<EntityStore> var1,
         @Nonnull BuilderToolsPlugin.HistoryStack var2,
         @Nonnull BuilderToolsPlugin.HistoryStack var3,
         ComponentAccessor<EntityStore> var4
      ) {
         long var5 = this.undoLock.writeLock();

         try {
            if (var2.isEmpty()) {
               class="kw">return null;
            }

            BuilderToolsPlugin.ActionEntry var7 = var2.dequeueLast();
            BuilderToolsPlugin.ActionEntry var8 = var7.restore(var1, this.playerRef, var4.getExternalData().getWorld(), var4);
            if (var7.getAction() == BuilderToolsPlugin.Action.TRANSFORM) {
               int var9 = this.cumulativeRotX;
               int var10 = this.cumulativeRotY;
               int var11 = this.cumulativeRotZ;
               this.cumulativeRotX = var7.getCumulativeRotXBefore();
               this.cumulativeRotY = var7.getCumulativeRotYBefore();
               this.cumulativeRotZ = var7.getCumulativeRotZBefore();
               var8.setCumulativeRotBefore(var9, var10, var11);
            }

            var3.enqueue(var8);
            long var15 = var3 == this.redo ? BuilderToolsPlugin.get().redoHistoryBlockBudget : BuilderToolsPlugin.get().historyBlockBudget;
            var3.trim(BuilderToolsPlugin.get().historyCount, var15);
            propagateEntityRefUpdates(var7, var8, var2);
            class="kw">return var7;
         } class="kw">finally {
            this.undoLock.unlockWrite(var5);
         }
      }

      class="kw">private class="kw">static void propagateEntityRefUpdates(
         @Nonnull BuilderToolsPlugin.ActionEntry var0, @Nonnull BuilderToolsPlugin.ActionEntry var1, @Nonnull BuilderToolsPlugin.HistoryStack var2
      ) {
         List var3 = var0.getSnapshots();
         List var4 = var1.getSnapshots();
         List var5 = null;
         List var6 = null;

         for (int var7 = 0; var7 < var3.size() && var7 < var4.size(); var7++) {
            if (var3.get(var7) class="kw">instanceof EntityRemoveSnapshot var8 && var4.get(var7) class="kw">instanceof EntityAddSnapshot var9) {
               Ref var18 = var8.getOriginalRef();
               Ref var11 = var9.getEntityRef();
               if (var18 != var11) {
                  if (var5 == null) {
                     var5 = new ObjectArrayList();
                     var6 = new ObjectArrayList();
                  }

                  var5.add(var18);
                  var6.add(var11);
               }
            }
         }

         if (var5 != null) {
            List var14 = new ObjectArrayList(var2.size());

            while (!var2.isEmpty()) {
               var14.add(var2.dequeue());
            }

            for (BuilderToolsPlugin.ActionEntry var16 : var14) {
               for (SelectionSnapshot var20 : var16.getSnapshots()) {
                  if (var20 class="kw">instanceof EntitySnapshot var12) {
                     for (int var13 = 0; var13 < var5.size(); var13++) {
                        var12.updateEntityRef(var5.get(var13), var6.get(var13));
                     }
                  }
               }

               var2.enqueue(var16);
            }
         }
      }

      class="kw">public class="kw">static class BlocksSampleData {
         class="kw">public int mainBlock = 0;
         class="kw">public int mainBlockCount = 0;
         class="kw">public int mainBlockNotAir = 0;
         class="kw">public int mainBlockNotAirCount = 0;

         class="kw">public BlocksSampleData() {
         }
      }

      class="kw">public class="kw">static class SmoothSampleData {
         class="kw">public float solidStrength = 0.0F;
         class="kw">public int solidBlock = 0;
         class="kw">public int solidBlockCount = 0;
         class="kw">public int fillerBlock = 0;
         class="kw">public int fillerBlockCount = 0;

         class="kw">public SmoothSampleData() {
         }
      }
   }

   class="kw">public class="kw">static class BuilderToolsConfig {
      class="kw">public class="kw">static class="kw">final BuilderCodec<BuilderToolsPlugin.BuilderToolsConfig> CODEC = BuilderCodec.builder(
            BuilderToolsPlugin.BuilderToolsConfig.class, BuilderToolsPlugin.BuilderToolsConfig::new
         )
         .append(new KeyedCodec<>("HistoryCount", Codec.INTEGER), (var0, var1) -> var0.historyCount = var1, var0 -> var0.historyCount)
         .documentation("The number of builder tool edit operations to keep in the undo/redo history")
         .add()
         .<Long>append(new KeyedCodec<>("HistoryBlockBudget", Codec.LONG), (var0, var1) -> var0.historyBlockBudget = var1, var0 -> var0.historyBlockBudget)
         .documentation(
            "The maximum total number of blocks (summed across undo entries) to retain in the undo history. When exceeded, the oldest entries are dropped (the most recent is always kept). Bounds the memory used by very large edits."
         )
         .addValidator(Validators.greaterThanOrEqual(0L))
         .add()
         .<Long>append(
            new KeyedCodec<>("RedoHistoryBlockBudget", Codec.LONG), (var0, var1) -> var0.redoHistoryBlockBudget = var1, var0 -> var0.redoHistoryBlockBudget
         )
         .documentation(
            "The maximum total number of blocks (summed across redo entries) to retain in the redo history. Typically smaller than HistoryBlockBudget since redo is relied on less. When exceeded, the oldest entries are dropped (the most recent is always kept)."
         )
         .addValidator(Validators.greaterThanOrEqual(0L))
         .add()
         .<Long>append(new KeyedCodec<>("ToolExpireTime", Codec.LONG), (var0, var1) -> var0.toolExpireTime = var1, var0 -> var0.toolExpireTime)
         .documentation(
            "The minimum time (in seconds) that a user's builder tool data will be persisted for after they disconnect from the server. If set to zero the player's data is removed immediately on disconnect"
         )
         .addValidator(Validators.greaterThanOrEqual(0L))
         .add()
         .build();
      class="kw">private int historyCount = 50;
      class="kw">private long historyBlockBudget = 16000000L;
      class="kw">private long redoHistoryBlockBudget = 8000000L;
      class="kw">private long toolExpireTime = 3600L;

      class="kw">public BuilderToolsConfig() {
      }
   }

   class="kw">public class="kw">static class CachedAccessor class="kw">extends AbstractCachedAccessor {
      class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Registry REGISTRY = new AbstractCachedAccessor.Registry();
      class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Key<FluidSection> FLUID_COMPONENT = REGISTRY.forSection(FluidSection::getComponentType);
      class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Key<BlockPhysics> PHYSICS_COMPONENT = REGISTRY.forSection(BlockPhysics::getComponentType);
      class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Key<BlockSection> BLOCKS_COMPONENT = REGISTRY.forSection(BlockSection::getComponentType);

      class="kw">public CachedAccessor() {
         super(REGISTRY);
      }

      @Nonnull
      class="kw">public class="kw">static BuilderToolsPlugin.CachedAccessor of(ComponentAccessor<ChunkStore> var0, int var1, int var2, int var3, int var4, int var5, int var6) {
         BuilderToolsPlugin.CachedAccessor var7 = new BuilderToolsPlugin.CachedAccessor();
         var7.init(var0, var1, var2, var3, var4, var5, var6);
         class="kw">return var7;
      }

      @Nullable
      class="kw">public FluidSection getFluidSection(int var1, int var2, int var3) {
         class="kw">return this.getComponentSection(var1, var2, var3, FLUID_COMPONENT);
      }

      @Nullable
      class="kw">public BlockPhysics getBlockPhysics(int var1, int var2, int var3) {
         class="kw">return this.getComponentSection(var1, var2, var3, PHYSICS_COMPONENT);
      }

      @Nullable
      class="kw">public BlockSection getBlockSection(int var1, int var2, int var3) {
         class="kw">return this.getComponentSection(var1, var2, var3, BLOCKS_COMPONENT);
      }
   }

   class="kw">public record ColorGradientMaterial(@Nonnull BlockPattern pattern, float weight) {
      class="kw">public ColorGradientMaterial {
      }
   }

   class="kw">private class="kw">static class="kw">final class HistoryStack {
      class="kw">private class="kw">static class="kw">final long BUDGET_MIN_EDIT_BLOCKS = 50000L;
      class="kw">private class="kw">final ObjectArrayFIFOQueue<BuilderToolsPlugin.ActionEntry> entries = new ObjectArrayFIFOQueue();
      class="kw">private long weight;

      class="kw">private HistoryStack() {
      }

      class="kw">private class="kw">static long budgetWeight(@Nonnull BuilderToolsPlugin.ActionEntry var0) {
         long var1 = var0.weight();
         class="kw">return var1 >= 50000L ? var1 : 0L;
      }

      int size() {
         class="kw">return this.entries.size();
      }

      boolean isEmpty() {
         class="kw">return this.entries.isEmpty();
      }

      long peekLastWeight() {
         class="kw">return this.entries.isEmpty() ? 0L : ((BuilderToolsPlugin.ActionEntry)this.entries.last()).weight();
      }

      void enqueue(@Nonnull BuilderToolsPlugin.ActionEntry var1) {
         this.entries.enqueue(var1);
         this.weight = this.weight + budgetWeight(var1);
      }

      @Nonnull
      BuilderToolsPlugin.ActionEntry dequeue() {
         BuilderToolsPlugin.ActionEntry var1 = (BuilderToolsPlugin.ActionEntry)this.entries.dequeue();
         this.weight = this.weight - budgetWeight(var1);
         class="kw">return var1;
      }

      @Nonnull
      BuilderToolsPlugin.ActionEntry dequeueLast() {
         BuilderToolsPlugin.ActionEntry var1 = (BuilderToolsPlugin.ActionEntry)this.entries.dequeueLast();
         this.weight = this.weight - budgetWeight(var1);
         class="kw">return var1;
      }

      void clear() {
         this.entries.clear();
         this.weight = 0L;
      }

      void trim(int var1, long var2) {
         while (this.entries.size() > 1 && (this.entries.size() > var1 || this.weight > var2)) {
            this.dequeue();
         }
      }
   }

   class="kw">public class="kw">static class PrefabPasteEventSystem class="kw">extends WorldEventSystem<EntityStore, PrefabPasteEvent> {
      @Nonnull
      class="kw">private class="kw">final BuilderToolsPlugin plugin;

      class="kw">protected PrefabPasteEventSystem(@Nonnull BuilderToolsPlugin var1) {
         super(PrefabPasteEvent.class);
         this.plugin = var1;
      }

      class="kw">public void handle(@Nonnull Store<EntityStore> var1, @Nonnull CommandBuffer<EntityStore> var2, @Nonnull PrefabPasteEvent var3) {
         if (var3.isPasteStart()) {
            this.plugin.pastedPrefabPathUUIDMap.put(var3.getPrefabId(), new ConcurrentHashMap<>());
            this.plugin.pastedPrefabPathNameToUUIDMap.put(var3.getPrefabId(), new ConcurrentHashMap<>());
         } else {
            this.plugin.pastedPrefabPathUUIDMap.remove(var3.getPrefabId());
            this.plugin.pastedPrefabPathNameToUUIDMap.remove(var3.getPrefabId());
         }
      }
   }

   class="kw">private class="kw">static class="kw">final class QueuedTask {
      @Nonnull
      class="kw">private class="kw">final ThrowableTriConsumer<Ref<EntityStore>, BuilderToolsPlugin.BuilderState, ComponentAccessor<EntityStore>, ? class="kw">extends Throwable> task;

      class="kw">private QueuedTask(
         @Nonnull ThrowableTriConsumer<Ref<EntityStore>, BuilderToolsPlugin.BuilderState, ComponentAccessor<EntityStore>, ? class="kw">extends Throwable> var1
      ) {
         this.task = var1;
      }

      void execute(@Nonnull Ref<EntityStore> var1, @Nonnull BuilderToolsPlugin.BuilderState var2, @Nonnull ComponentAccessor<EntityStore> var3) class="kw">throws Throwable {
         this.task.acceptNow(var1, var2, var3);
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return "QueuedTask{task=" + this.task + "}";
      }
   }

   class="kw">public enum ShadingLight {
      PLAYER,
      SUN,
      ANGLE;

      ShadingLight() {
      }
   }
}