// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.builtin.buildertools.imageimport;

import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.builtin.buildertools.BlockColorIndex;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.builtin.buildertools.utils.PasteToolUtil;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
import javax.imageio.ImageIO;
import com.hypixel.hytale.server.core.entity.entities.Player;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserEventData;
import com.hypixel.hytale.common.util.StringUtil;
import java.util.List;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.server.core.ui.LocalizableString;
import com.hypixel.hytale.server.core.ui.DropdownEntryInfo;
import java.util.ArrayList;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserConfig;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.ui.browser.ServerFileBrowser;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;

public class ImageImportPage extends InteractiveCustomUIPage<PageData>
{
    private static final int DEFAULT_MAX_SIZE = 128;
    private static final int MIN_SIZE = 1;
    private static final int MAX_SIZE = 512;
    private static final String ASSET_PACK_SUB_PATH = "Server/Imports/Images";
    @Nonnull
    private String imagePath;
    private int maxDimension;
    @Nonnull
    private String orientationStr;
    @Nonnull
    private Orientation orientation;
    @Nonnull
    private String originStr;
    @Nonnull
    private Origin origin;
    @Nullable
    private String statusMessage;
    private boolean isError;
    private boolean isProcessing;
    private boolean showBrowser;
    @Nonnull
    private final ServerFileBrowser browser;
    
    public ImageImportPage(@Nonnull final PlayerRef playerRef) {
        super(playerRef, CustomPageLifetime.CanDismiss, PageData.CODEC);
        this.imagePath = "";
        this.maxDimension = 128;
        this.orientationStr = "wall_xy";
        this.orientation = Orientation.VERTICAL_XY;
        this.originStr = "bottom_center";
        this.origin = Origin.BOTTOM_CENTER;
        this.statusMessage = null;
        this.isError = false;
        this.isProcessing = false;
        this.showBrowser = false;
        final FileBrowserConfig config = FileBrowserConfig.builder().listElementId("#BrowserPage #FileList").searchInputId("#BrowserPage #SearchInput").currentPathId("#BrowserPage #CurrentPath").allowedExtensions(".png", ".jpg", ".jpeg", ".gif", ".bmp").enableRootSelector(false).enableSearch(true).enableDirectoryNav(true).maxResults(50).assetPackMode(true, "Server/Imports/Images").build();
        this.browser = new ServerFileBrowser(config);
    }
    
    @Override
    public void build(@Nonnull final Ref<EntityStore> ref, @Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder, @Nonnull final Store<EntityStore> store) {
        commandBuilder.append("Pages/ImageImportPage.ui");
        commandBuilder.set("#ImagePath #Input.Value", this.imagePath);
        commandBuilder.set("#MaxSizeInput #Input.Value", this.maxDimension);
        final List<DropdownEntryInfo> orientationEntries = new ArrayList<DropdownEntryInfo>();
        orientationEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.imageImport.orientation.wall_xy"), "wall_xy"));
        orientationEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.imageImport.orientation.wall_xz"), "wall_xz"));
        orientationEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.imageImport.orientation.floor"), "floor"));
        commandBuilder.set("#OrientationInput #Input.Entries", orientationEntries);
        commandBuilder.set("#OrientationInput #Input.Value", this.orientationStr);
        final List<DropdownEntryInfo> originEntries = new ArrayList<DropdownEntryInfo>();
        originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.bottom_front_left"), "bottom_front_left"));
        originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.bottom_center"), "bottom_center"));
        originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.center"), "center"));
        originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.top_center"), "top_center"));
        commandBuilder.set("#OriginInput #Input.Entries", originEntries);
        commandBuilder.set("#OriginInput #Input.Value", this.originStr);
        this.updateStatus(commandBuilder);
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#ImagePath #Input", EventData.of("@ImagePath", "#ImagePath #Input.Value"), false);
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#MaxSizeInput #Input", EventData.of("@MaxSize", "#MaxSizeInput #Input.Value"), false);
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#OrientationInput #Input", EventData.of("@Orientation", "#OrientationInput #Input.Value"), false);
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#OriginInput #Input", EventData.of("@Origin", "#OriginInput #Input.Value"), false);
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ImportButton", EventData.of("Import", "true"));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ImagePath #BrowseButton", EventData.of("Browse", "true"));
        commandBuilder.set("#FormContainer.Visible", !this.showBrowser);
        commandBuilder.set("#BrowserPage.Visible", this.showBrowser);
        if (this.showBrowser) {
            this.buildBrowserPage(commandBuilder, eventBuilder);
        }
    }
    
    private void buildBrowserPage(@Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder) {
        this.browser.buildSearchInput(commandBuilder, eventBuilder);
        this.browser.buildCurrentPath(commandBuilder);
        this.browser.buildFileList(commandBuilder, eventBuilder);
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #SelectButton", EventData.of("BrowserSelect", "true"));
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #CancelButton", EventData.of("BrowserCancel", "true"));
    }
    
    private void updateStatus(@Nonnull final UICommandBuilder commandBuilder) {
        if (this.statusMessage != null) {
            commandBuilder.set("#StatusText.Text", this.statusMessage);
            commandBuilder.set("#StatusText.Visible", true);
            commandBuilder.set("#StatusText.Style.TextColor", this.isError ? "#e74c3c" : "#cfd8e3");
        }
        else {
            commandBuilder.set("#StatusText.Visible", false);
        }
    }
    
    private void setError(@Nonnull final String message) {
        this.statusMessage = message;
        this.isError = true;
        this.isProcessing = false;
        this.rebuild();
    }
    
    private void setStatus(@Nonnull final String message) {
        this.statusMessage = message;
        this.isError = false;
        this.rebuild();
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final PageData data) {
        if (data.browse != null && data.browse) {
            this.showBrowser = true;
            this.rebuild();
            return;
        }
        if (data.browserCancel != null && data.browserCancel) {
            this.showBrowser = false;
            this.rebuild();
            return;
        }
        if (data.browserSelect != null && data.browserSelect) {
            this.showBrowser = false;
            this.rebuild();
            return;
        }
        if (this.showBrowser && this.handleBrowserEvent(data)) {
            return;
        }
        boolean needsUpdate = false;
        if (data.imagePath != null) {
            this.imagePath = StringUtil.stripQuotes(data.imagePath.trim());
            this.statusMessage = null;
            needsUpdate = true;
        }
        if (data.maxSize != null) {
            this.maxDimension = Math.max(1, Math.min(512, data.maxSize));
            needsUpdate = true;
        }
        if (data.orientation != null) {
            this.orientationStr = data.orientation.trim().toLowerCase();
            final String orientationStr = this.orientationStr;
            this.orientation = switch (orientationStr) {
                case "wall_xz",  "xz",  "vertical_xz" -> Orientation.VERTICAL_XZ;
                case "floor",  "horizontal",  "horizontal_xz" -> Orientation.HORIZONTAL_XZ;
                default -> Orientation.VERTICAL_XY;
            };
            needsUpdate = true;
        }
        if (data.origin != null) {
            this.originStr = data.origin.trim().toLowerCase();
            final String originStr = this.originStr;
            this.origin = switch (originStr) {
                case "bottom_front_left" -> Origin.BOTTOM_FRONT_LEFT;
                case "center" -> Origin.CENTER;
                case "top_center" -> Origin.TOP_CENTER;
                default -> Origin.BOTTOM_CENTER;
            };
            needsUpdate = true;
        }
        if (data.doImport != null && data.doImport && !this.isProcessing) {
            this.performImport(ref, store);
            return;
        }
        if (needsUpdate) {
            this.sendUpdate();
        }
    }
    
    private boolean handleBrowserEvent(@Nonnull final PageData data) {
        if (data.searchQuery != null) {
            this.browser.setSearchQuery(data.searchQuery.trim().toLowerCase());
            this.rebuildBrowser();
            return true;
        }
        if (data.file != null) {
            final String fileName = data.file;
            if ("..".equals(fileName)) {
                this.browser.navigateUp();
                this.rebuildBrowser();
                return true;
            }
            if (this.browser.handleEvent(FileBrowserEventData.file(fileName))) {
                this.rebuildBrowser();
                return true;
            }
            final String virtualPath = this.browser.getAssetPackCurrentPath().isEmpty() ? fileName : (this.browser.getAssetPackCurrentPath() + "/" + fileName);
            final Path resolvedPath = this.browser.resolveAssetPackPath(virtualPath);
            if (resolvedPath != null && Files.isRegularFile(resolvedPath, new LinkOption[0])) {
                this.imagePath = resolvedPath.toString();
                this.showBrowser = false;
                this.rebuild();
                return true;
            }
        }
        if (data.searchResult != null) {
            final Path resolvedPath2 = this.browser.resolveAssetPackPath(data.searchResult);
            if (resolvedPath2 != null && Files.isRegularFile(resolvedPath2, new LinkOption[0])) {
                this.imagePath = resolvedPath2.toString();
                this.showBrowser = false;
                this.rebuild();
                return true;
            }
        }
        return false;
    }
    
    private void rebuildBrowser() {
        final UICommandBuilder commandBuilder = new UICommandBuilder();
        final UIEventBuilder eventBuilder = new UIEventBuilder();
        this.browser.buildFileList(commandBuilder, eventBuilder);
        this.browser.buildCurrentPath(commandBuilder);
        this.sendUpdate(commandBuilder, eventBuilder, false);
    }
    
    private void performImport(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store) {
        if (this.imagePath.isEmpty()) {
            this.setError("Please enter a path to an image file");
            return;
        }
        final Path path = Paths.get(this.imagePath, new String[0]);
        if (!Files.exists(path, new LinkOption[0])) {
            this.setError("File not found: " + this.imagePath);
            return;
        }
        this.isProcessing = true;
        this.setStatus("Processing...");
        final Player playerComponent = store.getComponent(ref, Player.getComponentType());
        final PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
        if (playerComponent == null || playerRefComponent == null) {
            this.setError("Player not found");
            return;
        }
        final String finalPath = this.imagePath;
        final int finalMaxSize = this.maxDimension;
        final Orientation finalOrientation = this.orientation;
        final Origin finalOrigin = this.origin;
        BuilderToolsPlugin.addToQueue(playerComponent, playerRefComponent, (r, builderState, componentAccessor) -> {
            try {
                BufferedImage image = null;
                try {
                    image = ImageIO.read(Paths.get(finalPath, new String[0]).toFile());
                }
                catch (final Exception ex) {}
                if (image == null) {
                    this.setError("Unable to read image file (unsupported format or corrupted). Try PNG format.");
                }
                else {
                    int width = image.getWidth();
                    int height = image.getHeight();
                    float scale = 1.0f;
                    if (width > finalMaxSize || height > finalMaxSize) {
                        scale = finalMaxSize / (float)Math.max(width, height);
                        width = Math.round(width * scale);
                        height = Math.round(height * scale);
                    }
                    final BlockColorIndex colorIndex = BuilderToolsPlugin.get().getBlockColorIndex();
                    if (colorIndex.isEmpty()) {
                        this.setError("Block color index not initialized");
                    }
                    else {
                        int sizeX = 0;
                        int sizeY = 0;
                        int sizeZ = 0;
                        switch (finalOrientation.ordinal()) {
                            case 0: {
                                sizeX = width;
                                sizeY = height;
                                sizeZ = 1;
                                break;
                            }
                            case 1: {
                                sizeX = width;
                                sizeY = 1;
                                sizeZ = height;
                                break;
                            }
                            case 2: {
                                sizeX = width;
                                sizeY = 1;
                                sizeZ = height;
                                break;
                            }
                            default: {
                                sizeX = width;
                                sizeY = height;
                                sizeZ = 1;
                                break;
                            }
                        }
                        int offsetX = 0;
                        int offsetY = 0;
                        int offsetZ = 0;
                        switch (finalOrigin.ordinal()) {
                            case 1: {
                                offsetX = -sizeX / 2;
                                offsetZ = -sizeZ / 2;
                                break;
                            }
                            case 2: {
                                offsetX = -sizeX / 2;
                                offsetY = -sizeY / 2;
                                offsetZ = -sizeZ / 2;
                                break;
                            }
                            case 3: {
                                offsetX = -sizeX / 2;
                                offsetY = -sizeY;
                                offsetZ = -sizeZ / 2;
                                break;
                            }
                        }
                        final BlockSelection selection = new BlockSelection(width * height, 0);
                        selection.setPosition(0, 0, 0);
                        int blockCount = 0;
                        final float finalScale = scale;
                        for (int imgY = 0; imgY < height; ++imgY) {
                            for (int imgX = 0; imgX < width; ++imgX) {
                                final int srcX = Math.min((int)(imgX / finalScale), image.getWidth() - 1);
                                final int srcY = Math.min((int)(imgY / finalScale), image.getHeight() - 1);
                                final int rgba = image.getRGB(srcX, srcY);
                                final int alpha = rgba >> 24 & 0xFF;
                                if (alpha >= 128) {
                                    final int red = rgba >> 16 & 0xFF;
                                    final int green = rgba >> 8 & 0xFF;
                                    final int blue = rgba & 0xFF;
                                    final int blockId = colorIndex.findClosestBlock(red, green, blue);
                                    if (blockId > 0) {
                                        int blockX = 0;
                                        int blockY = 0;
                                        int blockZ = 0;
                                        switch (finalOrientation.ordinal()) {
                                            case 0: {
                                                blockX = imgX;
                                                blockY = height - 1 - imgY;
                                                blockZ = 0;
                                                break;
                                            }
                                            case 1: {
                                                blockX = imgX;
                                                blockY = 0;
                                                blockZ = height - 1 - imgY;
                                                break;
                                            }
                                            case 2: {
                                                blockX = imgX;
                                                blockY = 0;
                                                blockZ = imgY;
                                                break;
                                            }
                                            default: {
                                                blockX = imgX;
                                                blockY = height - 1 - imgY;
                                                blockZ = 0;
                                                break;
                                            }
                                        }
                                        selection.addBlockAtLocalPos(blockX + offsetX, blockY + offsetY, blockZ + offsetZ, blockId, 0, 0, 0);
                                        ++blockCount;
                                    }
                                }
                            }
                        }
                        selection.setSelectionArea(new Vector3i(offsetX, offsetY, offsetZ), new Vector3i(sizeX - 1 + offsetX, sizeY - 1 + offsetY, sizeZ - 1 + offsetZ));
                        builderState.setSelection(selection);
                        builderState.sendSelectionToClient();
                        this.statusMessage = String.format("Success! %d blocks copied to clipboard (%dx%dx%d)", blockCount, sizeX, sizeY, sizeZ);
                        this.isProcessing = false;
                        playerRefComponent.sendMessage(Message.translation("server.builderTools.imageImport.success").param("count", blockCount).param("width", sizeX).param("height", sizeY).param("depth", sizeZ));
                        playerComponent.getPageManager().setPage(r, store, Page.None);
                        PasteToolUtil.switchToPasteTool(playerComponent, playerRefComponent);
                    }
                }
            }
            catch (final Exception e) {
                BuilderToolsPlugin.get().getLogger().at(Level.WARNING).withCause(e).log("Image import error");
                this.setError("Error: " + e.getMessage());
            }
        });
    }
    
    public enum Orientation
    {
        VERTICAL_XY, 
        VERTICAL_XZ, 
        HORIZONTAL_XZ;
    }
    
    public enum Origin
    {
        BOTTOM_FRONT_LEFT, 
        BOTTOM_CENTER, 
        CENTER, 
        TOP_CENTER;
    }
    
    public static class PageData
    {
        static final String KEY_IMAGE_PATH = "@ImagePath";
        static final String KEY_MAX_SIZE = "@MaxSize";
        static final String KEY_ORIENTATION = "@Orientation";
        static final String KEY_ORIGIN = "@Origin";
        static final String KEY_IMPORT = "Import";
        static final String KEY_BROWSE = "Browse";
        static final String KEY_BROWSER_SELECT = "BrowserSelect";
        static final String KEY_BROWSER_CANCEL = "BrowserCancel";
        public static final BuilderCodec<PageData> CODEC;
        @Nullable
        private String imagePath;
        @Nullable
        private Integer maxSize;
        @Nullable
        private String orientation;
        @Nullable
        private String origin;
        @Nullable
        private Boolean doImport;
        @Nullable
        private Boolean browse;
        @Nullable
        private Boolean browserSelect;
        @Nullable
        private Boolean browserCancel;
        @Nullable
        private String file;
        @Nullable
        private String searchQuery;
        @Nullable
        private String searchResult;
        
        static {
            // 
            // This method could not be decompiled.
            // 
            // Original Bytecode:
            // 
            //     2: invokedynamic   BootstrapMethod #0, get:()Ljava/util/function/Supplier;
            //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    10: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    13: dup            
            //    14: ldc             "@ImagePath"
            //    16: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    19: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    22: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
            //    27: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
            //    32: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    35: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    38: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    41: dup            
            //    42: ldc             "@MaxSize"
            //    44: getstatic       com/hypixel/hytale/codec/Codec.INTEGER:Lcom/hypixel/hytale/codec/codecs/simple/IntegerCodec;
            //    47: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    50: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
            //    55: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
            //    60: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    63: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    66: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    69: dup            
            //    70: ldc             "@Orientation"
            //    72: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    75: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //    78: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
            //    83: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
            //    88: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    91: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    94: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //    97: dup            
            //    98: ldc             "@Origin"
            //   100: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   103: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   106: invokedynamic   BootstrapMethod #7, accept:()Ljava/util/function/BiConsumer;
            //   111: invokedynamic   BootstrapMethod #8, apply:()Ljava/util/function/Function;
            //   116: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   119: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   122: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   125: dup            
            //   126: ldc             "Import"
            //   128: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   131: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   134: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
            //   139: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
            //   144: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   147: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   150: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   153: dup            
            //   154: ldc             "Browse"
            //   156: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   159: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   162: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
            //   167: invokedynamic   BootstrapMethod #12, apply:()Ljava/util/function/Function;
            //   172: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   175: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   178: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   181: dup            
            //   182: ldc             "BrowserSelect"
            //   184: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   187: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   190: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
            //   195: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/Function;
            //   200: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   203: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   206: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   209: dup            
            //   210: ldc             "BrowserCancel"
            //   212: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   215: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   218: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
            //   223: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
            //   228: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   231: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   234: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   237: dup            
            //   238: ldc             "File"
            //   240: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   243: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   246: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
            //   251: invokedynamic   BootstrapMethod #18, apply:()Ljava/util/function/Function;
            //   256: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   259: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   262: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   265: dup            
            //   266: ldc             "@SearchQuery"
            //   268: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   271: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   274: invokedynamic   BootstrapMethod #19, accept:()Ljava/util/function/BiConsumer;
            //   279: invokedynamic   BootstrapMethod #20, apply:()Ljava/util/function/Function;
            //   284: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   287: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   290: new             Lcom/hypixel/hytale/codec/KeyedCodec;
            //   293: dup            
            //   294: ldc             "SearchResult"
            //   296: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   299: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
            //   302: invokedynamic   BootstrapMethod #21, accept:()Ljava/util/function/BiConsumer;
            //   307: invokedynamic   BootstrapMethod #22, apply:()Ljava/util/function/Function;
            //   312: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   315: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   318: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   321: putstatic       com/hypixel/hytale/builtin/buildertools/imageimport/ImageImportPage$PageData.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   324: return         
            // 
            // The error that occurred was:
            // 
            // java.lang.UnsupportedOperationException: The requested operation is not supported.
            //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
            //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:267)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.TypeDefinition.accept(TypeDefinition.java:189)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:324)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2586)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
            //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:662)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
            //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
            //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
            //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
            // 
            throw new IllegalStateException("An error occurred while decompiling this method.");
        }
    }
}
